diff options
1510 files changed, 37180 insertions, 22868 deletions
diff --git a/.gitignore b/.gitignore index caaca826c5..43083d931c 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,8 @@ dist/gdb/source dist/gdb/staging ipch tmp +/*-debug +/*-release # ignore both a directory as well as a symlink share/qtcreator/QtProject/ share/qtcreator/QtProject @@ -24,13 +24,15 @@ Prerequisites: * On Mac: XCode 2.5 or later, compiling on 10.4 requires setting the environment variable QTC_TIGER_COMPAT before running qmake -We recommend that you build Qt Creator not in the source directory, but in a -separate directory. To do that, use the following commands: +You can build Qt Creator with -mkdir $BUILD_DIRECTORY -cd $BUILD_DIRECTORY -qmake $SOURCE_DIRECTORY/qtcreator.pro -make (or mingw32-make or nmake or jom, depending on your platform) + cd $SOURCE_DIRECTORY + qmake -r + make (or mingw32-make or nmake or jom, depending on your platform) + +Installation ("make install") is not needed. It is however possible, using + + make install INSTALL_ROOT=$INSTALL_DIRECTORY Compiling Qt Quick Designer --------------------------- diff --git a/dist/gdb/Makefile.linux b/dist/gdb/Makefile.linux index 1c7d6da33b..94bf99bca9 100644 --- a/dist/gdb/Makefile.linux +++ b/dist/gdb/Makefile.linux @@ -5,18 +5,13 @@ staging=${broot}/staging pyversion=2.7 expatversion=2.0.1 arch=`uname -sm | sed 's/ /-/g' | tr A-Z a-z` -version=7.4.1 +version=7.5 targetdir=${broot}/qtcreator-gdb-${version} gdbtargets=$(addprefix ${targetdir}/gdb-, ${targets}) packagename=qtcreator-gdb-${version}-${arch}.tar.gz all:package -gdb-7.4: override version=7.4 - -gdb-7.4: ${staging}/lib/libpython${pyversion}.a ${staging}/lib/libexpat.a - ${MAKE} version=${version} - clean: rm -rf ${broot}/qtcreator-gdb-* ${staging}/gdb-* qtcreator-gdb-*.tar.gz @@ -73,7 +68,6 @@ ${staging}/gdb-${version}/configure: ${source}/gdb-${version}.tar.bz2 | makestag cd gdb-${version} && \ touch configure && \ patch -p2 < ${broot}/patches/pythonhome-7.4.patch && \ - patch -p1 < ${broot}/patches/gdb-buildid-locate.patch && \ patch -p1 < ${broot}/patches/gdb-ipv6.patch && \ patch -p1 < ${broot}/patches/gdb-work-around-trk-single-step.patch diff --git a/dist/gdb/Makefile.mingw b/dist/gdb/Makefile.mingw index e8e0f80563..acc8a84173 100644 --- a/dist/gdb/Makefile.mingw +++ b/dist/gdb/Makefile.mingw @@ -6,7 +6,7 @@ pyversion=2.7 pydir=${broot}/python expatversion=2.0.1 iconvversion=1.14 -version=7.4.1 +version=7.5 targetdir=${broot}/qtcreator-gdb-${version} gdbtargets=$(addprefix ${targetdir}/gdb-, ${targets}) packageparts=${targetdir}/lib ${targetdir}/lib ${targetdir}/libiconv-2.dll ${targetdir}/python27.dll ${targetdir}/libexpat-1.dll @@ -15,11 +15,6 @@ packagename=qtcreator-gdb-${version}-${arch}.tar.gz all: package -gdb-7.4: override version=7.4 - -gdb-7.4: - ${MAKE} version=${version} - clean: rm -rf ${broot}/qtcreator-gdb-* ${staging}/gdb-* diff --git a/dist/gdb/Makefile.osx b/dist/gdb/Makefile.osx index 6b03bf6b29..20517d01ea 100644 --- a/dist/gdb/Makefile.osx +++ b/dist/gdb/Makefile.osx @@ -1,22 +1,17 @@ broot=${PWD} source=${broot}/source -targets=x86_64-unknown-linux-gnu i686-unknown-linux-gnu arm-none-linux-gnueabi +targets=x86_64-unknown-linux-gnu i686-unknown-linux-gnu arm-none-linux-gnueabi x86_64-apple-darwin10 staging=${broot}/staging pyversion=2.7 expatversion=2.0.1 arch=`uname -sm | sed 's/ /-/g' | tr A-Z a-z` -version=7.4.1 +version=7.5 targetdir=${broot}/qtcreator-gdb-${version} gdbtargets=$(addprefix ${targetdir}/gdb-, ${targets}) packagename=qtcreator-gdb-${version}-${arch}.tar.gz all:package -gdb-7.4: override version=7.4 - -gdb-7.4: ${staging}/lib/libpython${pyversion}.a ${staging}/lib/libexpat.a - ${MAKE} version=${version} - clean: rm -rf ${broot}/qtcreator-gdb-* ${staging}/gdb-* qtcreator-gdb-*.tar.gz @@ -71,7 +66,6 @@ ${staging}/gdb-${version}/configure: ${source}/gdb-${version}.tar.bz2 | makestag tar xf ${source}/gdb-${version}.tar.bz2 && \ cd gdb-${version} && \ touch configure && \ - patch -p2 < ${broot}/patches/pythonhome-${version}.patch && \ patch -p1 < ${broot}/patches/gdb-ipv6.patch ${gdbtargets}: ${targetdir}/gdb-%: ${staging}/gdb-${version}/configure ${staging}/lib/libpython${pyversion}.a ${staging}/lib/libexpat.a | maketargetdir diff --git a/dist/gdb/patches/gdb-ipv6.patch b/dist/gdb/patches/gdb-ipv6.patch index f51d51f1d8..0e67e5cd10 100644 --- a/dist/gdb/patches/gdb-ipv6.patch +++ b/dist/gdb/patches/gdb-ipv6.patch @@ -59,7 +59,7 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot #include "server.h" #include "terminal.h" #include "target.h" -@@ -62,6 +64,9 @@ +@@ -63,6 +65,9 @@ #if USE_WIN32API #include <winsock2.h> @@ -69,8 +69,8 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot #endif #if __QNX__ -@@ -106,7 +111,7 @@ int remote_debug = 0; - struct ui_file *gdb_stdlog; +@@ -109,7 +114,7 @@ struct ui_file *gdb_stdlog; + static int remote_is_stdio = 0; static gdb_fildes_t remote_desc = INVALID_DESCRIPTOR; -static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR; @@ -78,7 +78,7 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot /* FIXME headerize? */ extern int using_threads; -@@ -145,15 +150,17 @@ enable_async_notification (int fd) +@@ -156,15 +161,17 @@ enable_async_notification (int fd) static int handle_accept_event (int err, gdb_client_data client_data) { @@ -100,7 +100,7 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot perror_with_name ("Accept failed"); /* Enable TCP keep alive process. */ -@@ -167,27 +174,55 @@ handle_accept_event (int err, gdb_client +@@ -178,27 +185,55 @@ handle_accept_event (int err, gdb_client setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY, (char *) &tmp, sizeof (tmp)); @@ -167,7 +167,7 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot enable_async_notification (remote_desc); -@@ -213,12 +248,15 @@ remote_prepare (char *name) +@@ -224,12 +259,15 @@ remote_prepare (char *name) { char *port_str; #ifdef USE_WIN32API @@ -186,9 +186,9 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot + char *host_str = NULL; + char back_host[128], back_port[32]; - port_str = strchr (name, ':'); - if (port_str == NULL) -@@ -227,8 +265,24 @@ remote_prepare (char *name) + remote_is_stdio = 0; + if (strcmp (name, STDIO_CONNECTION_NAME) == 0) +@@ -249,8 +287,24 @@ remote_prepare (char *name) return; } @@ -215,7 +215,7 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot fatal ("Bad port argument: %s", name); #ifdef USE_WIN32API -@@ -241,24 +295,181 @@ remote_prepare (char *name) +@@ -263,24 +317,181 @@ remote_prepare (char *name) } #endif @@ -241,14 +241,7 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot + err = getaddrinfo(host_str, port_str, &hints, &ainfo0); + if (err) + fatal ("%s for %s", gai_strerror(err), name); - -- sockaddr.sin_family = PF_INET; -- sockaddr.sin_port = htons (port); -- sockaddr.sin_addr.s_addr = INADDR_ANY; -- -- if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) -- || listen (listen_desc, 1)) -- perror_with_name ("Can't bind address"); ++ + for (ainfo = ainfo0; ainfo; ainfo = ainfo->ai_next) + { + int current_port, tmp; @@ -341,7 +334,14 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot + s = -1; + continue; + } -+ + +- sockaddr.sin_family = PF_INET; +- sockaddr.sin_port = htons (port); +- sockaddr.sin_addr.s_addr = INADDR_ANY; +- +- if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) +- || listen (listen_desc, 1)) +- perror_with_name ("Can't bind address"); + { + struct sockaddr_storage address; + socklen_t alen = (socklen_t) sizeof (address); @@ -380,7 +380,7 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot + back_host, back_port); + } + } -+ + + if (socktable_size < nsock + 3) + { + socktable = xrealloc (socktable, @@ -399,11 +399,11 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot + /* Bound socktable from both ends, so an inner pointer can still + find the whole array. */ + socktable[++nsock] = INVALID_DESCRIPTOR; - - transport_is_reliable = 1; ++ ++ transport_is_reliable = 1; + fprintf (stderr, "Listening on port %d\n", port); + fflush (stderr); -+ transport_is_reliable = 1; + transport_is_reliable = 1; + if (listening_sockets) + fatal ("Multiple concurrent remote_open not supported."); + @@ -411,12 +411,13 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot } /* Open a connection to a remote debugger. -@@ -268,8 +479,25 @@ void +@@ -290,8 +501,24 @@ remote_open (char *name) { char *port_str; + char *host_start, *host_end; -+ + +- port_str = strchr (name, ':'); + host_start = name; + if (host_start[0] == '[') + { @@ -433,78 +434,11 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot + port_str = strchr (name, ':'); + host_end = port_str; + } - -- port_str = strchr (name, ':'); - if (port_str == NULL) - { #ifdef USE_WIN32API -@@ -278,21 +506,21 @@ remote_open (char *name) - struct stat statbuf; - - if (stat (name, &statbuf) == 0 -- && (S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))) -- remote_desc = open (name, O_RDWR); -+ && (S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))) -+ remote_desc = open (name, O_RDWR); - else -- { -- errno = EINVAL; -- remote_desc = -1; -- } -+ { -+ errno = EINVAL; -+ remote_desc = -1; -+ } - - if (remote_desc < 0) -- perror_with_name ("Could not open remote device"); -+ perror_with_name ("Could not open remote device"); - - #ifdef HAVE_TERMIOS - { -- struct termios termios; -- tcgetattr (remote_desc, &termios); -+ struct termios termios; -+ tcgetattr (remote_desc, &termios); - - termios.c_iflag = 0; - termios.c_oflag = 0; -@@ -302,14 +530,14 @@ remote_open (char *name) - termios.c_cc[VMIN] = 1; - termios.c_cc[VTIME] = 0; - -- tcsetattr (remote_desc, TCSANOW, &termios); -+ tcsetattr (remote_desc, TCSANOW, &termios); - } - #endif - - #ifdef HAVE_TERMIO - { -- struct termio termio; -- ioctl (remote_desc, TCGETA, &termio); -+ struct termio termio; -+ ioctl (remote_desc, TCGETA, &termio); - - termio.c_iflag = 0; - termio.c_oflag = 0; -@@ -319,13 +547,13 @@ remote_open (char *name) - termio.c_cc[VMIN] = 1; - termio.c_cc[VTIME] = 0; - -- ioctl (remote_desc, TCSETA, &termio); -+ ioctl (remote_desc, TCSETA, &termio); - } - #endif - - #ifdef HAVE_SGTTY - { -- struct sgttyb sg; -+ struct sgttyb sg; - - ioctl (remote_desc, TIOCGETP, &sg); - sg.sg_flags = RAW; -@@ -343,22 +571,17 @@ remote_open (char *name) - } + if (port_str == NULL) + error ("Only <host>:<port> is supported on this platform."); +@@ -381,22 +608,17 @@ remote_open (char *name) + #endif /* USE_WIN32API */ else { - int port; @@ -536,8 +470,6 @@ diff -rup gdb-7.4-clean/gdb/gdbserver/remote-utils.c gdb-7.4/gdb/gdbserver/remot } } -Only in gdb-7.4/gdb/gdbserver: remote-utils.c.orig -Only in gdb-7.4/gdb/gdbserver: remote-utils.c.rej diff -rup gdb-7.4-clean/gdb/ser-tcp.c gdb-7.4/gdb/ser-tcp.c --- gdb-7.4-clean/gdb/ser-tcp.c 2012-03-30 15:07:01.540553998 +0200 +++ gdb-7.4/gdb/ser-tcp.c 2012-03-30 15:08:39.484553844 +0200 diff --git a/doc/src/debugger/creator-debugger.qdoc b/doc/src/debugger/creator-debugger.qdoc index 28a36a823b..fa065d2634 100644 --- a/doc/src/debugger/creator-debugger.qdoc +++ b/doc/src/debugger/creator-debugger.qdoc @@ -410,6 +410,8 @@ you are debugging C++ or QML. Frequently used views are shown by default and rarely used ones are hidden. To change the default settings, select \gui {Window > Views}, and then select views to display or hide. + Alternatively, you can enable or disable views from the context menu + of the title bar of any visible debugger view. \image qtcreator-debugger-views.png "Debug mode views" @@ -760,6 +762,20 @@ and \gui{Step Over}. By default, both \gui{Disassembler} and \gui{Registers} view are hidden. + \section2 Creating Snapshots + + A snapshot contains the complete state of the debugged program + at a time, including the full memory contents. + + To create snapshots of a debugged program, select \gui Create in the + context menu in the \gui Snapshot view. + + Double-click on entries in the snapshot view to switch between + snapshots. The debugger views are updated to reflect the + state of the program at time of taking the snapshot. + + By default, the \gui{Snapshots} view is hidden. + */ @@ -864,15 +880,17 @@ is also easier to extend as the script is less dependent on the actual Qt version and does not need compilation. - To extend the shipped Python based debugging helpers for custom types, - define one Python function per user defined type in the - GDB startup file. By default, the following startup file is used: - \c{~/.gdbinit}. To use another file, select \gui {Tools > Options > - Debugger > GDB} - and specify a filename in the \gui {GDB startup script} field. + To extend the shipped Python based debugging helpers for custom + types, add debugging helper implementations to the GDB startup file + \c{~/.gdbinit}, or specify them directly in the \gui{Additional + Startup Commands} in \gui {Tools > Options > Debugger > GDB}. - The function name has to be qdump__NS__Foo, where NS::Foo is the class - or class template to be examined. Nested namespaces are possible. + The implementation of a debugging helper typically + consists of a single Python function, which needs to be named + \c{qdump__NS__Foo}, where \c{NS::Foo} is the class + or class template to be examined. Note that the \c{::} scope + resolution operator is replaced by double underscores \c{__}. + Nested namespaces are possible. The debugger plugin calls this function whenever you want to display an object of this type. The function is passed the following @@ -899,9 +917,6 @@ alloc = d_ptr["alloc"] size = d_ptr["size"] - check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000) - checkRef(d_ptr["ref"]) - innerType = templateArgument(value.type, 0) d.putItemCount(size) d.putNumChild(size) @@ -1052,7 +1067,12 @@ \o \gui{putCallItem(self, name, value, func, *args)} - Uses GDB to call the function \c func on the value specified by - \a {value} and output the resulting item. + \a {value} and output the resulting item. Use \c{putCallItem} + only if there is no other way to access the data. + Calls cannot be executed + when inspecting a core file, they are expensive to execute + and have the potential to change the state of the debugged + program. \o \gui{putItem(self, value)} - The "master function", handling basic types, references, pointers and enums directly, iterates diff --git a/doc/src/howto/creator-cli.qdoc b/doc/src/howto/creator-cli.qdoc index 70073dc917..ef4115bc5e 100644 --- a/doc/src/howto/creator-cli.qdoc +++ b/doc/src/howto/creator-cli.qdoc @@ -54,6 +54,12 @@ \endlist + To open a project that is located in a particular folder, you can pass on the folder + name as a command line argument. \QC looks for a session that matches the folder name and + loads it. Or it looks for a project file in the folder and opens it. For example: + + \c {qtcreator .} + The following table summarizes the available options: \table diff --git a/doc/src/qtquick/qtquick-creating.qdoc b/doc/src/qtquick/qtquick-creating.qdoc index 623b84961c..a8dcf90f2b 100644 --- a/doc/src/qtquick/qtquick-creating.qdoc +++ b/doc/src/qtquick/qtquick-creating.qdoc @@ -62,7 +62,7 @@ projects in a \l{Previewing QML Files}{preview tool} and you need not build them. You do not need to have the development environment installed on your - computer to create and run this type of projects. + computer to create and run this type of project. \o \gui {Qt Quick Application (from Existing QML File)} converts existing QML applications to Qt Quick application projects. This diff --git a/doc/templates/style/offline.css b/doc/templates/style/offline.css index c59c1ff80e..ce2d67db70 100644 --- a/doc/templates/style/offline.css +++ b/doc/templates/style/offline.css @@ -487,6 +487,11 @@ border-top: 1px solid #999; padding-top:11px; } +.footer a[href*="http://"], a[href*="ftp://"],a[href*="https://"]{ +background-size: 13px 11px; +padding-left: 16px; +} + .footerNavi{ width:auto; text-align:right; diff --git a/lib/qtcreator/qtcomponents/qtcomponents.qbs b/lib/qtcreator/qtcomponents/qtcomponents.qbs index 7453269b6c..b7f81c62cd 100644 --- a/lib/qtcreator/qtcomponents/qtcomponents.qbs +++ b/lib/qtcreator/qtcomponents/qtcomponents.qbs @@ -51,13 +51,13 @@ Product { "ButtonRow.qml", "CheckBox.qml", "ChoiceList.qml", - "components.pro", "GroupBox.qml", "ProgressBar.qml", "Slider.qml", "SpinBox.qml", "SplitterRow.qml", "TextField.qml", + "components.pro", "qmldir", ] } diff --git a/qbs/defaults.js b/qbs/defaults.js new file mode 100644 index 0000000000..2233af0995 --- /dev/null +++ b/qbs/defaults.js @@ -0,0 +1,16 @@ +function testsEnabled(qbs) +{ + return qbs.getenv("TEST") || qbs.buildVariant === "debug"; +} + +function defines(qbs) +{ + var list = [ + 'IDE_LIBRARY_BASENAME="lib"', + "QT_DISABLE_DEPRECATED_BEFORE=0x040900", + "QT_NO_CAST_TO_ASCII" + ] + if (testsEnabled(qbs)) + list.push("WITH_TESTS") + return list +} diff --git a/qtcreator.pri b/qtcreator.pri index ed620d1ced..c4882530fa 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -1,7 +1,7 @@ !isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included") QTCREATOR_PRI_INCLUDED = 1 -QTCREATOR_VERSION = 2.6.1 +QTCREATOR_VERSION = 2.6.81 isEqual(QT_MAJOR_VERSION, 5) { diff --git a/qtcreator.qbs b/qtcreator.qbs index 0157e201a6..58c7978f38 100644 --- a/qtcreator.qbs +++ b/qtcreator.qbs @@ -1,15 +1,12 @@ import qbs.base 1.0 import qbs.fileinfo 1.0 as FileInfo +import "qbs/defaults.js" as Defaults Project { property string ide_version_major: '2' property string ide_version_minor: '6' - property string ide_version_release: '1' + property string ide_version_release: '81' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release - property var additionalCppDefines: [ - 'IDE_LIBRARY_BASENAME="lib"', - "QT_DISABLE_DEPRECATED_BEFORE=0x040900" - ] moduleSearchPaths: "qbs" references: [ @@ -62,7 +59,7 @@ Project { "src/plugins/mercurial/mercurial.qbs", "src/plugins/perforce/perforce.qbs", "src/plugins/projectexplorer/projectexplorer.qbs", - "src/plugins/qmldesigner/qmldesigner.qbs", +// "src/plugins/qmldesigner/qmldesigner.qbs", "src/plugins/qmljseditor/qmljseditor.qbs", "src/plugins/qmljstools/qmljstools.qbs", "src/plugins/qmlprofiler/qmlprofiler.qbs", @@ -80,9 +77,10 @@ Project { "src/plugins/valgrind/valgrind.qbs", "src/plugins/vcsbase/vcsbase.qbs", "src/plugins/welcome/welcome.qbs", - "src/share/share.qbs", "src/tools/qtcdebugger/qtcdebugger.qbs", + "src/tools/qtcreatorcrashhandler/qtcreatorcrashhandler.qbs", "src/tools/qtpromaker/qtpromaker.qbs", + "src/plugins/cpaster/frontend/frontend.qbs", "src/tools/sdktool/sdktool.qbs" ] @@ -131,6 +129,11 @@ Project { return cmd; } } + + ProductModule { + Depends { name: "cpp" } + cpp.includePaths: product.buildDirectory + } } Product { @@ -140,7 +143,7 @@ Project { consoleApplication: qbs.debugInformation cpp.rpaths: ["$ORIGIN/../lib/qtcreator"] - cpp.defines: project.additionalCppDefines + cpp.defines: Defaults.defines(qbs) cpp.linkerFlags: { if (qbs.buildVariant == "release" && (qbs.toolchain == "gcc" || qbs.toolchain == "mingw")) return ["-Wl,-s"] @@ -166,7 +169,9 @@ Project { "src/shared/qtsingleapplication/qtsingleapplication.cpp", "src/shared/qtsingleapplication/qtlocalpeer.h", "src/shared/qtsingleapplication/qtlocalpeer.cpp", - "src/shared/qtlockedfile/qtlockedfile.cpp" + "src/shared/qtlockedfile/qtlockedfile.cpp", + "src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp", + "src/tools/qtcreatorcrashhandler/crashhandlersetup.h" ] Group { diff --git a/share/qtcreator/dumper/bridge.py b/share/qtcreator/dumper/bridge.py index da75a51e54..69f67c4511 100644 --- a/share/qtcreator/dumper/bridge.py +++ b/share/qtcreator/dumper/bridge.py @@ -5,6 +5,19 @@ cdbLoaded = False lldbLoaded = False gdbLoaded = False +def warn(message): + print "XXX: %s\n" % message.encode("latin1") + + +def showException(msg, exType, exValue, exTraceback): + warn("**** CAUGHT EXCEPTION: %s ****" % msg) + try: + import traceback + for line in traceback.format_exception(exType, exValue, exTraceback): + warn("%s" % line) + except: + pass + try: #import cdb_bridge cdbLoaded = True @@ -42,28 +55,28 @@ try: # ####################################################################### + def savePrint(output): + try: + print(output) + except: + out = "" + for c in output: + cc = ord(c) + if cc > 127: + out += "\\\\%d" % cc + elif cc < 0: + out += "\\\\%d" % (cc + 256) + else: + out += c + print(out) + def registerCommand(name, func): class Command(gdb.Command): def __init__(self): super(Command, self).__init__(name, gdb.COMMAND_OBSCURE) def invoke(self, args, from_tty): - output = func(args) - try: - print(output) - except: - out = "" - for c in output: - cc = ord(c) - if cc > 127: - out += "\\\\%d" % cc - elif cc < 0: - out += "\\\\%d" % (cc + 256) - else: - out += c - print(out) - - + savePrint(func(args)) Command() @@ -78,16 +91,16 @@ try: if isGoodGdb(): return gdb.parse_and_eval(exp) # Work around non-existing gdb.parse_and_eval as in released 7.0 - gdb.execute("set logging redirect on") +# gdb.execute("set logging redirect on") gdb.execute("set logging on") try: gdb.execute("print %s" % exp) except: gdb.execute("set logging off") - gdb.execute("set logging redirect off") +# gdb.execute("set logging redirect off") return None gdb.execute("set logging off") - gdb.execute("set logging redirect off") +# gdb.execute("set logging redirect off") return gdb.history(0) @@ -189,13 +202,13 @@ try: block = block.superblock else: # Assuming gdb 7.0 release or 6.8-symbianelf. - filename, file = createTempFile() + filename = createTempFile() #warn("VARLIST: %s " % varList) #warn("FILENAME: %s " % filename) gdb.execute("set logging off") - gdb.execute("set logging redirect off") +# gdb.execute("set logging redirect off") gdb.execute("set logging file %s" % filename) - gdb.execute("set logging redirect on") +# gdb.execute("set logging redirect on") gdb.execute("set logging on") try: gdb.execute("info args") @@ -215,7 +228,7 @@ try: except: pass gdb.execute("set logging off") - gdb.execute("set logging redirect off") +# gdb.execute("set logging redirect off") try: temp = open(filename, "r") @@ -230,7 +243,7 @@ try: temp.close() except: pass - removeTempFile(filename, file) + removeTempFile(filename) #warn("VARLIST: %s " % varList) for name in varList: #warn("NAME %s " % name) @@ -260,11 +273,11 @@ try: return gdb.execute(command, to_string=True).split("\n") except: pass - filename, file = createTempFile() + filename = createTempFile() gdb.execute("set logging off") - gdb.execute("set logging redirect off") +# gdb.execute("set logging redirect off") gdb.execute("set logging file %s" % filename) - gdb.execute("set logging redirect on") +# gdb.execute("set logging redirect on") gdb.execute("set logging on") msg = "" try: @@ -276,17 +289,18 @@ try: except: msg = "Unknown error" gdb.execute("set logging off") - gdb.execute("set logging redirect off") +# gdb.execute("set logging redirect off") if len(msg): # Having that might confuse result handlers in the gdbengine. #warn("CLI ERROR: %s " % msg) + removeTempFile(filename) return "CLI ERROR: %s " % msg temp = open(filename, "r") lines = [] for line in temp: lines.append(line) temp.close() - removeTempFile(filename, file) + removeTempFile(filename) return lines def selectedInferior(): @@ -383,8 +397,8 @@ try: def invoke(self, args, from_tty): print(eval(args)) - registerCommand("pp", pp) - + PPCommand() + # Just convienience for 'python print gdb.parse_and_eval(...)' class PPPCommand(gdb.Command): def __init__(self): @@ -394,6 +408,29 @@ try: PPPCommand() + + def scanStack(p, n): + p = long(p) + r = [] + for i in xrange(n): + f = gdb.parse_and_eval("{void*}%s" % p) + m = gdb.execute("info symbol %s" % f, to_string=True) + if not m.startswith("No symbol matches"): + r.append(m) + p += f.type.sizeof + return r + + class ScanStackCommand(gdb.Command): + def __init__(self): + super(ScanStackCommand, self).__init__("scanStack", gdb.COMMAND_OBSCURE) + def invoke(self, args, from_tty): + if len(args) == 0: + args = 20 + savePrint(scanStack(gdb.parse_and_eval("$sp"), int(args))) + + ScanStackCommand() + + except: pass diff --git a/share/qtcreator/dumper/dumper.cpp b/share/qtcreator/dumper/dumper.cpp index 5e4a4c3dcb..0b2ae00c5c 100644 --- a/share/qtcreator/dumper/dumper.cpp +++ b/share/qtcreator/dumper/dumper.cpp @@ -2251,11 +2251,11 @@ static void qDumpQVariantHelper(const QVariant *v, QString *value, # endif default: { static const char *qTypeFormat = sizeof(void *) == sizeof(long) - ? "'" NS "%s " NS "qVariantValue<" NS "%s >'(*('" NS "QVariant'*)0x%lx)" - : "'" NS "%s " NS "qVariantValue<" NS "%s >'(*('" NS "QVariant'*)0x%llx)"; + ? "'" NS "%s " NS "qvariant_cast<" NS "%s >'(*('" NS "QVariant'*)0x%lx)" + : "'" NS "%s " NS "qvariant_cast<" NS "%s >'(*('" NS "QVariant'*)0x%llx)"; static const char *nonQTypeFormat = sizeof(void *) == sizeof(long) - ? "'%s " NS "qVariantValue<%s >'(*('" NS "QVariant'*)0x%lx)" - : "'%s " NS "qVariantValue<%s >'(*('" NS "QVariant'*)0x%llx)"; + ? "'%s " NS "qvariant_cast<%s >'(*('" NS "QVariant'*)0x%lx)" + : "'%s " NS "qvariant_cast<%s >'(*('" NS "QVariant'*)0x%llx)"; char buf[1000]; const char *format = (v->typeName()[0] == 'Q') ? qTypeFormat : nonQTypeFormat; qsnprintf(buf, sizeof(buf) - 1, format, v->typeName(), v->typeName(), v); diff --git a/share/qtcreator/dumper/dumper.py b/share/qtcreator/dumper/dumper.py index 52aad054ca..c38af76e65 100644 --- a/share/qtcreator/dumper/dumper.py +++ b/share/qtcreator/dumper/dumper.py @@ -2,6 +2,8 @@ import sys import base64 import __builtin__ import os +import os.path +import subprocess import tempfile # Fails on Windows. @@ -22,11 +24,12 @@ tempFileCounter = 0 try: # Test if 2.6 is used (Windows), trigger exception and default # to 2nd version. - tempfile.NamedTemporaryFile(prefix="py_",delete=True) + file = tempfile.NamedTemporaryFile(prefix="py_",delete=True) + file.close() def createTempFile(): - file = tempfile.NamedTemporaryFile(prefix="py_",delete=False) + file = tempfile.NamedTemporaryFile(prefix="py_",delete=True) file.close() - return file.name, file + return file.name except: def createTempFile(): @@ -34,9 +37,9 @@ except: tempFileCounter += 1 fileName = "%s/py_tmp_%d_%d" \ % (tempfile.gettempdir(), os.getpid(), tempFileCounter) - return fileName, None + return fileName -def removeTempFile(name, file): +def removeTempFile(name): try: os.remove(name) except: @@ -47,7 +50,7 @@ verbosity = 1 # Some "Enums" -# Encodings +# Encodings. Keep that synchronized with DebuggerEncoding in watchutils.h Unencoded8Bit, \ Base64Encoded8BitWithQuotes, \ Base64Encoded16BitWithQuotes, \ @@ -77,17 +80,33 @@ Hex2EncodedFloat4, \ Hex2EncodedFloat8 \ = range(27) -# Display modes +# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h StopDisplay, \ -DisplayImage1, \ -DisplayString, \ -DisplayImage, \ -DisplayProcess \ - = range(5) +DisplayImageData, \ +DisplayUtf16String, \ +DisplayImageFile, \ +DisplayProcess, \ +DisplayLatin1String, \ +DisplayUtf8String \ + = range(7) -qqStringCutOff = 1000 +qqStringCutOff = 10000 +# +# Gnuplot based display for array-like structures. +# +gnuplotPipe = {} +gnuplotPid = {} + +def hasPlot(): + fileName = "/usr/bin/gnuplot" + return os.path.isfile(fileName) and os.access(fileName, os.X_OK) + + +# +# Threads +# def hasInferiorThreadList(): #return False try: @@ -96,6 +115,9 @@ def hasInferiorThreadList(): except: return False +# +# VTable +# def hasVTable(type): fields = type.fields() if len(fields) == 0: @@ -309,16 +331,6 @@ def numericTemplateArgument(type, position): return int(msg) -def showException(msg, exType, exValue, exTraceback): - warn("**** CAUGHT EXCEPTION: %s ****" % msg) - try: - import traceback - for line in traceback.format_exception(exType, exValue, exTraceback): - warn("%s" % line) - except: - pass - - class OutputSafer: def __init__(self, d): self.d = d @@ -527,11 +539,6 @@ def simpleEncoding(typeobj): return Hex2EncodedFloat8 return None -def warn(message): - if True or verbosity > 0: - print "XXX: %s\n" % message.encode("latin1") - pass - def check(exp): if not exp: raise RuntimeError("Check failed") @@ -747,11 +754,18 @@ def qByteArrayData(value): # Qt 4: return private['data'], int(private['size']), int(private['alloc']) -def encodeByteArray(value): +def computeLimit(size, limit): + if limit is None: + return size + if limit == 0: + return min(size, qqStringCutOff) + return min(size, limit) + +def encodeByteArray(value, limit = None): data, size, alloc = qByteArrayData(value) if alloc != 0: check(0 <= size and size <= alloc and alloc <= 100*1000*1000) - limit = min(size, qqStringCutOff) + limit = computeLimit(size, limit) s = readRawMemory(data, limit) if limit < size: s += "2e2e2e" @@ -770,11 +784,11 @@ def qStringData(value): # Qt 4. return private['data'], int(private['size']), int(private['alloc']) -def encodeString(value): +def encodeString(value, limit = 0): data, size, alloc = qStringData(value) if alloc != 0: check(0 <= size and size <= alloc and alloc <= 100*1000*1000) - limit = min(size, qqStringCutOff) + limit = computeLimit(size, limit) s = readRawMemory(data, 2 * limit) if limit < size: s += "2e002e002e00" @@ -1352,6 +1366,45 @@ class Dumper: self.put('",') return True + def putPlotData(self, type, base, n, plotFormat): + if self.isExpanded(): + self.putArrayData(type, base, n) + if not hasPlot(): + return + if not isSimpleType(type): + self.putValue(self.currentValue + " (not plottable)") + return + global gnuplotPipe + global gnuplotPid + format = self.currentItemFormat() + iname = self.currentIName + #if False: + if format != plotFormat: + if iname in gnuplotPipe: + os.kill(gnuplotPid[iname], 9) + del gnuplotPid[iname] + gnuplotPipe[iname].terminate() + del gnuplotPipe[iname] + return + base = base.cast(type.pointer()) + if not iname in gnuplotPipe: + gnuplotPipe[iname] = subprocess.Popen(["gnuplot"], + stdin=subprocess.PIPE) + gnuplotPid[iname] = gnuplotPipe[iname].pid + f = gnuplotPipe[iname].stdin; + f.write("set term wxt noraise\n") + f.write("set title 'Data fields'\n") + f.write("set xlabel 'Index'\n") + f.write("set ylabel 'Value'\n") + f.write("set grid\n") + f.write("set style data lines;\n") + f.write("plot '-' title '%s'\n" % iname) + for i in range(1, n): + f.write(" %s\n" % base.dereference()) + base += 1 + f.write("e\n") + + def putArrayData(self, type, base, n, childNumChild = None, maxNumChild = 10000): base = base.cast(type.pointer()) @@ -1431,7 +1484,7 @@ class Dumper: if value.is_optimized_out: self.putValue("<optimized out>") else: - self.putValue(int(value)) + self.putValue(value) self.putNumChild(0) return @@ -1481,32 +1534,7 @@ class Dumper: return if type.code == ArrayCode: - targetType = type.target() - self.putAddress(value.address) - self.putType(typeName) - self.putNumChild(1) - format = self.currentItemFormat() - if format == None and str(targetType.unqualified()) == "char": - # Use Latin1 as default for char []. - self.putValue(encodeCharArray(value), Hex2EncodedLatin1) - elif format == 0: - # Explicitly requested Latin1 formatting. - self.putValue(encodeCharArray(value), Hex2EncodedLatin1) - elif format == 1: - # Explicitly requested UTF-8 formatting. - self.putValue(encodeCharArray(value), Hex2EncodedUtf8) - elif format == 2: - # Explicitly requested Local 8-bit formatting. - self.putValue(encodeCharArray(value), Hex2EncodedLocal8Bit) - else: - self.putValue("@0x%x" % long(value.cast(targetType.pointer()))) - if self.currentIName in self.expandedINames: - p = value.cast(targetType.pointer()) - ts = targetType.sizeof - if not self.tryPutArrayContents(targetType, p, type.sizeof/ts): - with Children(self, childType=targetType, - addrBase=p, addrStep=ts): - self.putFields(value) + qdump____c_style_array__(self, value) return if type.code == PointerCode: @@ -1721,6 +1749,17 @@ class Dumper: #except: # pass + # D arrays, gdc compiled. + if typeName.endswith("[]"): + n = value["length"] + base = value["ptr"] + self.putType(typeName) + self.putAddress(value.address) + self.putItemCount(n) + if self.isExpanded(): + self.putArrayData(base.type.target(), base, n) + return + #warn("GENERIC STRUCT: %s" % type) #warn("INAME: %s " % self.currentIName) #warn("INAMES: %s " % self.expandedINames) diff --git a/share/qtcreator/dumper/qttypes.py b/share/qtcreator/dumper/qttypes.py index 48dec6f25c..a7c2d7fbcd 100644 --- a/share/qtcreator/dumper/qttypes.py +++ b/share/qtcreator/dumper/qttypes.py @@ -11,6 +11,11 @@ from __future__ import with_statement def mapForms(): return "Normal,Compact" +def arrayForms(): + if hasPlot(): + return "Normal,Plot" + return "Normal" + def mapCompact(format, keyType, valueType): if format == 2: return True # Compact. @@ -38,10 +43,22 @@ def qdump__QBasicAtomicPointer(d, value): d.putItem(value["_q_value"]) +def qform__QByteArray(): + return "Inline,As Latin1 in Separate Window,As UTF-8 in Separate Window" + def qdump__QByteArray(d, value): d.putByteArrayValue(value) data, size, alloc = qByteArrayData(value) d.putNumChild(size) + format = d.currentItemFormat() + if format == 1: + d.putDisplay(StopDisplay) + elif format == 2: + d.putField("editformat", DisplayLatin1String) + d.putField("editvalue", encodeByteArray(value, None)) + elif format == 3: + d.putField("editformat", DisplayUtf8String) + d.putField("editvalue", encodeByteArray(value, None)) if d.isExpanded(): d.putArrayData(lookupType("char"), data, size) @@ -559,7 +576,7 @@ def qdump__QImage(d, value): if False: # Take four bytes at a time, this is critical for performance. # In fact, even four at a time is too slow beyond 100x100 or so. - d.putField("editformat", 1) # Magic marker for direct "QImage" data. + d.putField("editformat", DisplayImageData) d.put('%s="' % name) d.put("%08x" % int(d_ptr["width"])) d.put("%08x" % int(d_ptr["height"])) @@ -576,7 +593,7 @@ def qdump__QImage(d, value): p = bits.cast(lookupType("unsigned char").pointer()) gdb.execute("dump binary memory %s %s %s" % (filename, cleanAddress(p), cleanAddress(p + nbytes))) - d.putDisplay(DisplayImage, " %d %d %d %s" + d.putDisplay(DisplayImageFile, " %d %d %d %s" % (d_ptr["width"], d_ptr["height"], d_ptr["format"], filename)) @@ -781,10 +798,15 @@ def qdump__QObject(d, value): staticMetaObject = value["staticMetaObject"] d_ptr = value["d_ptr"]["d"].cast(privateType.pointer()).dereference() #warn("D_PTR: %s " % d_ptr) + objectName = None try: objectName = d_ptr["objectName"] except: # Qt 5 - objectName = d_ptr["extraData"].dereference()["objectName"] + p = d_ptr["extraData"] + if not isNull(p): + objectName = p.dereference()["objectName"] + if not objectName is None: + d.putStringValue(objectName) except: d.putPlainChildren(value) return @@ -816,13 +838,20 @@ def qdump__QObject(d, value): #warn("MO.D: %s " % mo["d"]) metaData = mo["d"]["data"] metaStringData = mo["d"]["stringdata"] + # This is char * in Qt 4 and ByteArrayData * in Qt 5. + # Force it to the char * data in the Qt 5 case. + try: + offset = metaStringData["offset"] + metaStringData = metaStringData.cast(lookupType('char*')) + int(offset) + except: + pass + #extradata = mo["d"]["extradata"] # Capitalization! #warn("METADATA: %s " % metaData) #warn("STRINGDATA: %s " % metaStringData) #warn("TYPE: %s " % value.type) #warn("INAME: %s " % d.currentIName()) #d.putValue("") - d.putStringValue(objectName) #QSignalMapper::staticMetaObject #checkRef(d_ptr["ref"]) d.putNumChild(4) @@ -1444,8 +1473,21 @@ def qdump__QString(d, value): if format == 1: d.putDisplay(StopDisplay) elif format == 2: - d.putField("editformat", 2) - d.putField("editvalue", encodeString(value)) + d.putField("editformat", DisplayUtf16String) + d.putField("editvalue", encodeString(value, None)) + + +def qdump__QStringRef(d, value): + s = value["m_string"].dereference() + data, size, alloc = qStringData(s) + data += int(value["m_position"]) + size = value["m_size"] + s = readRawMemory(data, 2 * size) + d.putValue(s, Hex4EncodedLittleEndian) + d.putNumChild(3) + if d.isExpanded(): + with Children(d): + d.putFields(value) def qdump__QStringList(d, value): @@ -1721,6 +1763,10 @@ def qedit__QVector(expr, value): gdb.execute(cmd) +def qform__QVector(): + return arrayForms() + + def qdump__QVector(d, value): private = value["d"] checkRef(private["ref"]) @@ -1741,8 +1787,7 @@ def qdump__QVector(d, value): check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000) d.putItemCount(size) d.putNumChild(size) - if d.isExpanded(): - d.putArrayData(innerType, p, size) + d.putPlotData(innerType, p, size, 2) def qdump__QWeakPointer(d, value): @@ -1786,6 +1831,42 @@ def qdump__QxXmlAttributes(d, value): # ####################################################################### +def qdump____c_style_array__(d, value): + type = value.type.unqualified() + targetType = type.target() + typeName = str(type) + d.putAddress(value.address) + d.putType(typeName) + d.putNumChild(1) + format = d.currentItemFormat() + isDefault = format == None and str(targetType.unqualified()) == "char" + if isDefault or (format >= 0 and format <= 2): + blob = readRawMemory(value.address, type.sizeof) + + if isDefault: + # Use Latin1 as default for char []. + d.putValue(blob, Hex2EncodedLatin1) + elif format == 0: + # Explicitly requested Latin1 formatting. + d.putValue(blob, Hex2EncodedLatin1) + elif format == 1: + # Explicitly requested UTF-8 formatting. + d.putValue(blob, Hex2EncodedUtf8) + elif format == 2: + # Explicitly requested Local 8-bit formatting. + d.putValue(blob, Hex2EncodedLocal8Bit) + else: + d.putValue("@0x%x" % long(value.cast(targetType.pointer()))) + + if d.currentIName in d.expandedINames: + p = value.address + ts = targetType.sizeof + if not d.tryPutArrayContents(targetType, p, type.sizeof / ts): + with Children(d, childType=targetType, + addrBase=p, addrStep=ts): + d.putFields(value) + + def qdump__std__array(d, value): size = numericTemplateArgument(value.type, 1) d.putItemCount(size) @@ -2001,6 +2082,9 @@ def qdump__std__stack(d, value): qdump__std__deque(d, value["c"]) +def qform__std__string(): + return "Inline,In Separate Window" + def qdump__std__string(d, value): data = value["_M_dataplus"]["_M_p"] baseType = value.type.unqualified().strip_typedefs() @@ -2021,40 +2105,36 @@ def qdump__std__string(d, value): check(rep['_M_refcount'] >= -1) # Can be -1 accoring to docs. check(0 <= size and size <= alloc and alloc <= 100*1000*1000) p = gdb.Value(data.cast(charType.pointer())) - s = "" # Override "std::basic_string<...> if str(charType) == "char": d.putType("std::string", 1) elif str(charType) == "wchar_t": d.putType("std::wstring", 1) - n = min(size, 1000) + n = min(size, qqStringCutOff) + mem = readRawMemory(p, n * charType.sizeof) if charType.sizeof == 1: - format = "%02x" - for i in xrange(size): - s += format % int(p.dereference()) - p += 1 - d.putValue(s, Hex2EncodedLatin1) - d.putNumChild(0) + encodingType = Hex2EncodedLatin1 + displayType = DisplayLatin1String elif charType.sizeof == 2: - format = "%02x%02x" - for i in xrange(size): - val = int(p.dereference()) - s += format % (val % 256, val / 256) - p += 1 - d.putValue(s, Hex4EncodedLittleEndian) + encodingType = Hex4EncodedLatin1 + displayType = DisplayUtf16String else: - # FIXME: This is not always a proper solution. - format = "%02x%02x%02x%02x" - for i in xrange(size): - val = int(p.dereference()) - hi = val / 65536 - lo = val % 65536 - s += format % (lo % 256, lo / 256, hi % 256, hi / 256) - p += 1 - d.putValue(s, Hex8EncodedLittleEndian) + encodinfType = Hex8EncodedLatin1 + displayType = DisplayUtf16String + d.putAddress(value.address) d.putNumChild(0) + d.putValue(mem, encodingType) + + format = d.currentItemFormat() + if format == 1: + d.putDisplay(StopDisplay) + elif format == 2: + d.putField("editformat", displayType) + if n != size: + mem = readRawMemory(p, size * charType.sizeof) + d.putField("editvalue", mem) def qdump__std__shared_ptr(d, value): @@ -2506,6 +2586,10 @@ def qdump__CPlusPlus__Internal__Value(d, value): d.putValue(value["l"]) d.putPlainChildren(value) +def qdump__Utils__FileName(d, value): + d.putStringValue(value) + d.putPlainChildren(value) + def qdump__Utils__ElfSection(d, value): d.putByteArrayValue(value["name"]) d.putPlainChildren(value) @@ -2662,20 +2746,24 @@ if False: d.putItem(v["a"]) - def qdump__Function(d, value): +if False: + + def qform__basic__Function(): + return "Normal,Displayed" + + def qdump__basic__Function(d, value): min = value["min"] max = value["max"] data, size, alloc = qByteArrayData(value["var"]) - var = extractCString(data) + var = extractCString(data, 0) data, size, alloc = qByteArrayData(value["f"]) - f = extractCString(data) + f = extractCString(data, 0) d.putValue("%s, %s=%f..%f" % (f, var, min, max)) d.putNumChild(0) - d.putField("typeformats", "Normal,Displayed"); format = d.currentItemFormat() - if format == 0: + if format == 1: d.putDisplay(StopDisplay) - elif format == 1: + elif format == 2: input = "plot [%s=%f:%f] %s" % (var, min, max, f) d.putDisplay(DisplayProcess, input, "gnuplot") @@ -2792,3 +2880,5 @@ if False: if d.isExpanded(): with Children(d): d.putFields(value) + + diff --git a/share/qtcreator/qml/qmldump/main.cpp b/share/qtcreator/qml/qmldump/main.cpp index 5c771e6378..0cfbbe6995 100644 --- a/share/qtcreator/qml/qmldump/main.cpp +++ b/share/qtcreator/qml/qmldump/main.cpp @@ -584,10 +584,10 @@ int main(int argc, char *argv[]) // find all QMetaObjects reachable when the specified module is imported if (action != Path) { - importCode += QString("import %0 %1\n").arg(pluginImportUri, pluginImportVersion).toAscii(); + importCode += QString("import %0 %1\n").arg(pluginImportUri, pluginImportVersion).toLatin1(); } else { // pluginImportVersion can be empty - importCode += QString("import \".\" %2\n").arg(pluginImportVersion).toAscii(); + importCode += QString("import \".\" %2\n").arg(pluginImportVersion).toLatin1(); } // create a component with these imports to make sure the imports are valid diff --git a/share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.cpp index 5bd1e760bf..45a5383237 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.cpp @@ -29,6 +29,8 @@ #include "changenodesourcecommand.h" +#include <QDataStream> + namespace QmlDesigner { ChangeNodeSourceCommand::ChangeNodeSourceCommand() diff --git a/share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.h b/share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.h index 28379c3c29..3fc5323a57 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.h +++ b/share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.h @@ -31,6 +31,7 @@ #define CHANGENODESOURCECOMMAND_H #include <QMetaType> +#include <QString> #include <QDataStream> namespace QmlDesigner { diff --git a/share/qtcreator/qml/qmlpuppet/commands/commands.pri b/share/qtcreator/qml/qmlpuppet/commands/commands.pri index 5ae623cf3f..3d347f73db 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/commands.pri +++ b/share/qtcreator/qml/qmlpuppet/commands/commands.pri @@ -1,6 +1,8 @@ INCLUDEPATH += $$PWD/ HEADERS += $$PWD/synchronizecommand.h +HEADERS += $$PWD//debugoutputcommand.h +HEADERS += $$PWD/endpuppetcommand.h HEADERS += $$PWD/tokencommand.h HEADERS += $$PWD/componentcompletedcommand.h HEADERS += $$PWD/completecomponentcommand.h @@ -22,9 +24,11 @@ HEADERS += $$PWD/removepropertiescommand.h HEADERS += $$PWD/reparentinstancescommand.h HEADERS += $$PWD/valueschangedcommand.h HEADERS += $$PWD/changeauxiliarycommand.h - +HEADERS += $$PWD/removesharedmemorycommand.h SOURCES += $$PWD/synchronizecommand.cpp +SOURCES += $$PWD/debugoutputcommand.cpp +SOURCES += $$PWD/endpuppetcommand.cpp SOURCES += $$PWD/tokencommand.cpp SOURCES += $$PWD/componentcompletedcommand.cpp SOURCES += $$PWD/completecomponentcommand.cpp @@ -46,3 +50,4 @@ SOURCES += $$PWD/createinstancescommand.cpp SOURCES += $$PWD/createscenecommand.cpp SOURCES += $$PWD/pixmapchangedcommand.cpp SOURCES += $$PWD/changeauxiliarycommand.cpp +SOURCES += $$PWD/removesharedmemorycommand.cpp diff --git a/share/qtcreator/qml/qmlpuppet/commands/completecomponentcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/completecomponentcommand.cpp index a4e77589b0..f8f6a22f34 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/completecomponentcommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/completecomponentcommand.cpp @@ -29,6 +29,8 @@ #include "completecomponentcommand.h" +#include <QDataStream> + namespace QmlDesigner { CompleteComponentCommand::CompleteComponentCommand() diff --git a/share/qtcreator/qml/qmlpuppet/commands/componentcompletedcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/componentcompletedcommand.cpp index a4a58ff500..444928e00e 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/componentcompletedcommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/componentcompletedcommand.cpp @@ -29,6 +29,8 @@ #include "componentcompletedcommand.h" +#include <QDataStream> + namespace QmlDesigner { ComponentCompletedCommand::ComponentCompletedCommand() diff --git a/share/qtcreator/qml/qmlpuppet/commands/debugoutputcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/debugoutputcommand.cpp new file mode 100644 index 0000000000..1eacfd247f --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/debugoutputcommand.cpp @@ -0,0 +1,74 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + + +#include "debugoutputcommand.h" + +namespace QmlDesigner { + +DebugOutputCommand::DebugOutputCommand() +{ +} + +DebugOutputCommand::DebugOutputCommand(const QString &text, DebugOutputCommand::Type type) + : m_text(text), + m_type(type) +{ +} + +qint32 DebugOutputCommand::type() const +{ + return m_type; +} + +QString DebugOutputCommand::text() const +{ + return m_text; +} + +QDataStream &operator<<(QDataStream &out, const DebugOutputCommand &command) +{ + out << command.type(); + out << command.text(); + + return out; +} + +QDataStream &operator>>(QDataStream &in, DebugOutputCommand &command) +{ + in >> command.m_type; + in >> command.m_text; + + return in; +} + +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/commands/debugoutputcommand.h b/share/qtcreator/qml/qmlpuppet/commands/debugoutputcommand.h new file mode 100644 index 0000000000..0c0e232b13 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/debugoutputcommand.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QMLDESIGNER_DEBUGOUTPUTCOMMAND_H +#define QMLDESIGNER_DEBUGOUTPUTCOMMAND_H + +#include <QMetaType> +#include <QString> +#include <QDataStream> + +namespace QmlDesigner { + +class DebugOutputCommand +{ + friend QDataStream &operator>>(QDataStream &in, DebugOutputCommand &command); + +public: + enum Type { + DebugType, + WarningType, + ErrorType, + FatalType + }; + + DebugOutputCommand(); + DebugOutputCommand(const QString &text, Type type); + + qint32 type() const; + QString text() const; + +private: + QString m_text; + quint32 m_type; +}; + +QDataStream &operator<<(QDataStream &out, const DebugOutputCommand &command); +QDataStream &operator>>(QDataStream &in, DebugOutputCommand &command); + +} // namespace QmlDesigner + +Q_DECLARE_METATYPE(QmlDesigner::DebugOutputCommand) + +#endif // QMLDESIGNER_DEBUGOUTPUTCOMMAND_H diff --git a/share/qtcreator/qml/qmlpuppet/commands/endpuppetcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/endpuppetcommand.cpp new file mode 100644 index 0000000000..22e8225569 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/endpuppetcommand.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "endpuppetcommand.h" + +namespace QmlDesigner { + +EndPuppetCommand::EndPuppetCommand() +{ +} + +QDataStream &operator<<(QDataStream &out, const EndPuppetCommand &/*command*/) +{ + return out; +} + +QDataStream &operator>>(QDataStream &in, EndPuppetCommand &/*command*/) +{ + return in; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/extrasplugin/extrasplugin.h b/share/qtcreator/qml/qmlpuppet/commands/endpuppetcommand.h index 5399f6aa8f..b962e1f44e 100644 --- a/src/plugins/qmldesigner/extrasplugin/extrasplugin.h +++ b/share/qtcreator/qml/qmlpuppet/commands/endpuppetcommand.h @@ -26,29 +26,24 @@ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ +#ifndef QMLDESIGNER_ENDPUPPETCOMMAND_H +#define QMLDESIGNER_ENDPUPPETCOMMAND_H -#ifndef EXTRASPLUGIN_H -#define EXTRASPLUGIN_H - -#include <iwidgetplugin.h> +#include <qmetatype.h> namespace QmlDesigner { -class ExtrasPlugin : public QObject, QmlDesigner::IWidgetPlugin +class EndPuppetCommand { - Q_OBJECT -#if QT_VERSION >= 0x050000 - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QmlDesignerPlugin" FILE "extrasplugin.json") -#endif - Q_INTERFACES(QmlDesigner::IWidgetPlugin) - public: - ExtrasPlugin(); - - QString metaInfo() const; - QString pluginName() const; + EndPuppetCommand(); }; +QDataStream &operator<<(QDataStream &out, const EndPuppetCommand &command); +QDataStream &operator>>(QDataStream &in, EndPuppetCommand &command); + } // namespace QmlDesigner -#endif // EXTRASPLUGIN_H +Q_DECLARE_METATYPE(QmlDesigner::EndPuppetCommand) + +#endif // QMLDESIGNER_ENDPUPPETCOMMAND_H diff --git a/share/qtcreator/qml/qmlpuppet/commands/removeinstancescommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/removeinstancescommand.cpp index 53556865aa..708538b5ab 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/removeinstancescommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/removeinstancescommand.cpp @@ -29,6 +29,8 @@ #include "removeinstancescommand.h" +#include <QDataStream> + namespace QmlDesigner { RemoveInstancesCommand::RemoveInstancesCommand() diff --git a/share/qtcreator/qml/qmlpuppet/commands/removesharedmemorycommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/removesharedmemorycommand.cpp new file mode 100644 index 0000000000..63bb675f7b --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/removesharedmemorycommand.cpp @@ -0,0 +1,76 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + + +#include "removesharedmemorycommand.h" + +#include <QDataStream> + +namespace QmlDesigner { + +RemoveSharedMemoryCommand::RemoveSharedMemoryCommand() +{ +} + +RemoveSharedMemoryCommand::RemoveSharedMemoryCommand(const QString &typeName, const QVector<qint32> &keyNumberVector) + : m_typeName(typeName), + m_keyNumberVector(keyNumberVector) +{ +} + +QString RemoveSharedMemoryCommand::typeName() const +{ + return m_typeName; +} + +QVector<qint32> RemoveSharedMemoryCommand::keyNumbers() const +{ + return m_keyNumberVector; +} + +QDataStream &operator<<(QDataStream &out, const RemoveSharedMemoryCommand &command) +{ + out << command.typeName(); + out << command.keyNumbers(); + + return out; +} + +QDataStream &operator>>(QDataStream &in, RemoveSharedMemoryCommand &command) +{ + in >> command.m_typeName; + in >> command.m_keyNumberVector; + + return in; +} + +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/commands/removesharedmemorycommand.h b/share/qtcreator/qml/qmlpuppet/commands/removesharedmemorycommand.h new file mode 100644 index 0000000000..da46fc0a20 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/removesharedmemorycommand.h @@ -0,0 +1,66 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + + +#ifndef QMLDESIGNER_REMOVESHAREDMEMORYCOMMAND_H +#define QMLDESIGNER_REMOVESHAREDMEMORYCOMMAND_H + +#include <QMetaType> +#include <QString> +#include <QVector> + +namespace QmlDesigner { + +class RemoveSharedMemoryCommand +{ + friend QDataStream &operator>>(QDataStream &in, RemoveSharedMemoryCommand &command); + +public: + RemoveSharedMemoryCommand(); + RemoveSharedMemoryCommand(const QString &typeName, const QVector<qint32> &keyNumberVector); + + QString typeName() const; + QVector<qint32> keyNumbers() const; + +private: + QString m_typeName; + QVector<qint32> m_keyNumberVector; +}; + +QDataStream &operator<<(QDataStream &out, const RemoveSharedMemoryCommand &command); +QDataStream &operator>>(QDataStream &in, RemoveSharedMemoryCommand &command); + +} // namespace QmlDesigner + +Q_DECLARE_METATYPE(QmlDesigner::RemoveSharedMemoryCommand) + +#endif // QMLDESIGNER_REMOVESHAREDMEMORYCOMMAND_H diff --git a/share/qtcreator/qml/qmlpuppet/commands/reparentinstancescommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/reparentinstancescommand.cpp index aec54af74a..39f811d20e 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/reparentinstancescommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/reparentinstancescommand.cpp @@ -29,6 +29,8 @@ #include "reparentinstancescommand.h" +#include <QDataStream> + namespace QmlDesigner { ReparentInstancesCommand::ReparentInstancesCommand() diff --git a/share/qtcreator/qml/qmlpuppet/commands/tokencommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/tokencommand.cpp index 64dbe59e23..450cbb69b4 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/tokencommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/tokencommand.cpp @@ -29,6 +29,8 @@ #include "tokencommand.h" +#include <QDataStream> + namespace QmlDesigner { TokenCommand::TokenCommand() diff --git a/share/qtcreator/qml/qmlpuppet/commands/tokencommand.h b/share/qtcreator/qml/qmlpuppet/commands/tokencommand.h index eba8d4edb8..84ac8dd76a 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/tokencommand.h +++ b/share/qtcreator/qml/qmlpuppet/commands/tokencommand.h @@ -33,6 +33,7 @@ #include <QMetaType> #include <QVector> +#include <QString> #include <QDataStream> namespace QmlDesigner { diff --git a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp index 1885d839e7..b244ad9936 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp @@ -29,14 +29,23 @@ #include "valueschangedcommand.h" +#include <QSharedMemory> +#include <QCache> + +#include <cstring> + namespace QmlDesigner { +static QCache<qint32, QSharedMemory> globalSharedMemoryCache(10000); + ValuesChangedCommand::ValuesChangedCommand() + : m_keyNumber(0) { } ValuesChangedCommand::ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector) - : m_valueChangeVector (valueChangeVector) + : m_valueChangeVector (valueChangeVector), + m_keyNumber(0) { } @@ -45,17 +54,91 @@ QVector<PropertyValueContainer> ValuesChangedCommand::valueChanges() const return m_valueChangeVector; } +quint32 ValuesChangedCommand::keyNumber() const +{ + return m_keyNumber; +} + +void ValuesChangedCommand::removeSharedMemorys(const QVector<qint32> &keyNumberVector) +{ + foreach (qint32 keyNumber, keyNumberVector) { + QSharedMemory *sharedMemory = globalSharedMemoryCache.take(keyNumber); + delete sharedMemory; + } +} + +static const QLatin1String valueKeyTemplateString("Values-%1"); + +static QSharedMemory *createSharedMemory(qint32 key, int byteCount) +{ + QSharedMemory *sharedMemory = new QSharedMemory(QString(valueKeyTemplateString).arg(key)); + + bool sharedMemoryIsCreated = sharedMemory->create(byteCount); + if (!sharedMemoryIsCreated) { + if (sharedMemory->isAttached()) + sharedMemory->attach(); + sharedMemory->detach(); + sharedMemoryIsCreated = sharedMemory->create(byteCount); + } + + if (sharedMemoryIsCreated) { + globalSharedMemoryCache.insert(key, sharedMemory); + return sharedMemory; + } + + return 0; +} + QDataStream &operator<<(QDataStream &out, const ValuesChangedCommand &command) { + static const bool dontUseSharedMemory = !qgetenv("DESIGNER_DONT_USE_SHARED_MEMORY").isEmpty(); + + if (!dontUseSharedMemory && command.valueChanges().count() > 5) { + static quint32 keyCounter = 0; + ++keyCounter; + command.m_keyNumber = keyCounter; + QByteArray outDataStreamByteArray; + QDataStream temporaryOutDataStream(&outDataStreamByteArray, QIODevice::WriteOnly); + temporaryOutDataStream.setVersion(QDataStream::Qt_4_8); + + temporaryOutDataStream << command.valueChanges();; + + QSharedMemory *sharedMemory = createSharedMemory(keyCounter, outDataStreamByteArray.size()); + + if (sharedMemory) { + std::memcpy(sharedMemory->data(), outDataStreamByteArray.constData(), sharedMemory->size()); + out << command.keyNumber(); + return out; + } + } + + out << qint32(0); out << command.valueChanges(); return out; } +void readSharedMemory(qint32 key, QVector<PropertyValueContainer> *valueChangeVector) +{ + QSharedMemory sharedMemory(QString(valueKeyTemplateString).arg(key)); + bool canAttach = sharedMemory.attach(QSharedMemory::ReadOnly); + + if (canAttach) { + QDataStream in(QByteArray::fromRawData(static_cast<const char*>(sharedMemory.constData()), sharedMemory.size())); + in.setVersion(QDataStream::Qt_4_8); + in >> *valueChangeVector; + } +} + QDataStream &operator>>(QDataStream &in, ValuesChangedCommand &command) { - in >> command.m_valueChangeVector; + in >> command.m_keyNumber; + if (command.keyNumber() > 0) { + readSharedMemory(command.keyNumber(), &command.m_valueChangeVector); + } else { + in >> command.m_valueChangeVector; + } return in; } diff --git a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h index b28fb68075..f2cc0d504f 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h +++ b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h @@ -39,6 +39,7 @@ namespace QmlDesigner { class ValuesChangedCommand { + friend QDataStream &operator<<(QDataStream &out, const ValuesChangedCommand &command); friend QDataStream &operator>>(QDataStream &in, ValuesChangedCommand &command); public: @@ -46,9 +47,13 @@ public: ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector); QVector<PropertyValueContainer> valueChanges() const; + quint32 keyNumber() const; + + static void removeSharedMemorys(const QVector<qint32> &keyNumberVector); private: QVector<PropertyValueContainer> m_valueChangeVector; + mutable quint32 m_keyNumber; }; QDataStream &operator<<(QDataStream &out, const ValuesChangedCommand &command); diff --git a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp index ce45b60f81..064b4423e1 100644 --- a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp +++ b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp @@ -29,15 +29,30 @@ #include "imagecontainer.h" +#include <QSharedMemory> +#include <QCache> + +#include <cstring> + +#define QTC_ASSERT_STRINGIFY_HELPER(x) #x +#define QTC_ASSERT_STRINGIFY(x) QTC_ASSERT_STRINGIFY_HELPER(x) +#define QTC_ASSERT_STRING(cond) qDebug("SOFT ASSERT: \"" cond"\" in file " __FILE__ ", line " QTC_ASSERT_STRINGIFY(__LINE__)) +#define QTC_ASSERT(cond, action) if (cond) {} else { QTC_ASSERT_STRING(#cond); action; } do {} while (0) + namespace QmlDesigner { +static QCache<qint32, QSharedMemory> globalSharedMemoryCache(10000); + ImageContainer::ImageContainer() - : m_instanceId(-1) + : m_instanceId(-1), + m_keyNumber(-2) { } -ImageContainer::ImageContainer(qint32 instanceId, const QImage &image) - : m_image(image), m_instanceId(instanceId) +ImageContainer::ImageContainer(qint32 instanceId, const QImage &image, qint32 keyNumber) + : m_image(image), + m_instanceId(instanceId), + m_keyNumber(keyNumber) { } @@ -51,39 +66,167 @@ QImage ImageContainer::image() const return m_image; } -QDataStream &operator<<(QDataStream &out, const ImageContainer &container) +qint32 ImageContainer::keyNumber() const { - out << container.instanceId(); + return m_keyNumber; +} - const QImage image = container.image(); - const QByteArray data(reinterpret_cast<const char*>(image.constBits()), image.byteCount()); +void ImageContainer::setImage(const QImage &image) +{ + QTC_ASSERT(m_image.isNull(), /**/); + + m_image = image; +} + +void ImageContainer::removeSharedMemorys(const QVector<qint32> &keyNumberVector) +{ + foreach (qint32 keyNumber, keyNumberVector) { + QSharedMemory *sharedMemory = globalSharedMemoryCache.take(keyNumber); + delete sharedMemory; + } +} + +static const QLatin1String imageKeyTemplateString("Image-%1"); + +static QSharedMemory *createSharedMemory(qint32 key, int byteCount) +{ + QSharedMemory *sharedMemory = globalSharedMemoryCache.take(key); + + if (sharedMemory == 0) + sharedMemory = new QSharedMemory(QString(imageKeyTemplateString).arg(key)); + + bool sharedMemoryIsCreated = sharedMemory->isAttached(); + if (!sharedMemoryIsCreated) + sharedMemoryIsCreated = sharedMemory->attach(); + + bool sharedMemorySizeIsSmallerThanByteCount = sharedMemory->size() < byteCount; + bool sharedMemorySizeIsDoubleBiggerThanByteCount = sharedMemory->size() * 2 > byteCount; + + if (!sharedMemoryIsCreated || sharedMemorySizeIsSmallerThanByteCount || sharedMemorySizeIsDoubleBiggerThanByteCount) { + sharedMemory->detach(); + sharedMemoryIsCreated = sharedMemory->create(byteCount); + } + + if (sharedMemoryIsCreated) { + globalSharedMemoryCache.insert(key, sharedMemory); + return sharedMemory; + } + + return 0; +} +static void writeSharedMemory(QSharedMemory *sharedMemory, const QImage &image) +{ + sharedMemory->lock(); + + qint32 headerData[5]; + headerData[0] = image.byteCount(); + headerData[1] = image.bytesPerLine(); + headerData[2] = image.size().width(); + headerData[3] = image.size().height(); + headerData[4] = image.format(); + + std::memcpy(sharedMemory->data(), headerData, 20); + std::memcpy(reinterpret_cast<char*>(sharedMemory->data()) + 20, image.constBits(), image.byteCount()); + + sharedMemory->unlock(); +} + +static void writeStream(QDataStream &out, const QImage &image) +{ out << qint32(image.bytesPerLine()); out << image.size(); out << qint32(image.format()); out << qint32(image.byteCount()); out.writeRawData(reinterpret_cast<const char*>(image.constBits()), image.byteCount()); +} + +QDataStream &operator<<(QDataStream &out, const ImageContainer &container) +{ + const int extraDataSize = 20; + static const bool dontUseSharedMemory = !qgetenv("DESIGNER_DONT_USE_SHARED_MEMORY").isEmpty(); + + out << container.instanceId(); + out << container.keyNumber(); + + const QImage image = container.image(); + + if (dontUseSharedMemory) { + out << qint32(0); + writeStream(out, image); + } else { + QSharedMemory *sharedMemory = createSharedMemory(container.keyNumber(), image.byteCount() + extraDataSize); + + out << qint32(sharedMemory != 0); // send if shared memory is used + + if (sharedMemory) + writeSharedMemory(sharedMemory, image); + else + writeStream(out, image); + } return out; } -QDataStream &operator>>(QDataStream &in, ImageContainer &container) +static void readSharedMemory(qint32 key, ImageContainer &container) { + QSharedMemory sharedMemory(QString(imageKeyTemplateString).arg(key)); + + bool canAttach = sharedMemory.attach(QSharedMemory::ReadOnly); + + if (canAttach && sharedMemory.size() >= 20) + { + sharedMemory.lock(); + qint32 headerData[5]; + std::memcpy(headerData, sharedMemory.constData(), 20); + + qint32 byteCount = headerData[0]; +// qint32 bytesPerLine = headerData[1]; + qint32 imageWidth = headerData[2]; + qint32 imageHeight = headerData[3]; + qint32 imageFormat = headerData[4]; + + QImage image = QImage(imageWidth, imageHeight, QImage::Format(imageFormat)); + + std::memcpy(image.bits(), reinterpret_cast<const qint32*>(sharedMemory.constData()) + 5, byteCount); - qint32 byteSize; + container.setImage(image); + + sharedMemory.unlock(); + } +} + +static void readStream(QDataStream &in, ImageContainer &container) +{ + qint32 byteCount; qint32 bytesPerLine; QSize imageSize; - qint32 format; - - in >> container.m_instanceId; + qint32 imageFormat; in >> bytesPerLine; in >> imageSize; - in >> format; - in >> byteSize; + in >> imageFormat; + in >> byteCount; + + QImage image = QImage(imageSize, QImage::Format(imageFormat)); + + in.readRawData(reinterpret_cast<char*>(image.bits()), byteCount); + + container.setImage(image); +} + +QDataStream &operator>>(QDataStream &in, ImageContainer &container) +{ + qint32 sharedMemoryIsUsed; + + in >> container.m_instanceId; + in >> container.m_keyNumber; + in >> sharedMemoryIsUsed; - container.m_image = QImage(imageSize, QImage::Format(format)); - in.readRawData(reinterpret_cast<char*>(container.m_image.bits()), byteSize); + if (sharedMemoryIsUsed) { + readSharedMemory(container.keyNumber(), container); + } else + readStream(in, container); return in; } diff --git a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.h b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.h index d2582747f2..a34750ef2e 100644 --- a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.h +++ b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.h @@ -40,14 +40,20 @@ class ImageContainer friend QDataStream &operator>>(QDataStream &in, ImageContainer &container); public: ImageContainer(); - ImageContainer(qint32 instanceId, const QImage &image); + ImageContainer(qint32 instanceId, const QImage &image, qint32 keyNumber); qint32 instanceId() const; QImage image() const; + qint32 keyNumber() const; + + void setImage(const QImage &image); + + static void removeSharedMemorys(const QVector<qint32> &keyNumberVector); private: QImage m_image; qint32 m_instanceId; + qint32 m_keyNumber; }; QDataStream &operator<<(QDataStream &out, const ImageContainer &container); diff --git a/share/qtcreator/qml/qmlpuppet/container/instancecontainer.cpp b/share/qtcreator/qml/qmlpuppet/container/instancecontainer.cpp index 32900b4699..644631defb 100644 --- a/share/qtcreator/qml/qmlpuppet/container/instancecontainer.cpp +++ b/share/qtcreator/qml/qmlpuppet/container/instancecontainer.cpp @@ -29,6 +29,8 @@ #include "instancecontainer.h" +#include <QDataStream> + namespace QmlDesigner { InstanceContainer::InstanceContainer() diff --git a/share/qtcreator/qml/qmlpuppet/container/reparentcontainer.cpp b/share/qtcreator/qml/qmlpuppet/container/reparentcontainer.cpp index 32cea56c0b..548064021f 100644 --- a/share/qtcreator/qml/qmlpuppet/container/reparentcontainer.cpp +++ b/share/qtcreator/qml/qmlpuppet/container/reparentcontainer.cpp @@ -29,6 +29,8 @@ #include "reparentcontainer.h" +#include <QDataStream> + namespace QmlDesigner { ReparentContainer::ReparentContainer() diff --git a/share/qtcreator/qml/qmlpuppet/container/reparentcontainer.h b/share/qtcreator/qml/qmlpuppet/container/reparentcontainer.h index 1e7bc7720d..f31b43ab52 100644 --- a/share/qtcreator/qml/qmlpuppet/container/reparentcontainer.h +++ b/share/qtcreator/qml/qmlpuppet/container/reparentcontainer.h @@ -31,6 +31,7 @@ #define REPARENTCONTAINER_H #include <qmetatype.h> +#include <QString> #include <QDataStream> namespace QmlDesigner { diff --git a/share/qtcreator/qml/qmlpuppet/instances/instances.pri b/share/qtcreator/qml/qmlpuppet/instances/instances.pri index b9ed533142..daf1d3ed51 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/instances.pri +++ b/share/qtcreator/qml/qmlpuppet/instances/instances.pri @@ -1,35 +1,5 @@ INCLUDEPATH += $$PWD/ -HEADERS += $$PWD/behaviornodeinstance.h - -HEADERS += $$PWD/dummycontextobject.h - -HEADERS += $$PWD/childrenchangeeventfilter.h -HEADERS += $$PWD/componentnodeinstance.h -HEADERS += $$PWD/dummynodeinstance.h HEADERS += $$PWD/nodeinstanceclientproxy.h -HEADERS += $$PWD/nodeinstancemetaobject.h -HEADERS += $$PWD/nodeinstanceserver.h -HEADERS += $$PWD/nodeinstancesignalspy.h -HEADERS += $$PWD/objectnodeinstance.h -HEADERS += $$PWD/qmlpropertychangesnodeinstance.h -HEADERS += $$PWD/qmlstatenodeinstance.h -HEADERS += $$PWD/qmltransitionnodeinstance.h -HEADERS += $$PWD/servernodeinstance.h -HEADERS += $$PWD/anchorchangesnodeinstance.h -SOURCES += $$PWD/behaviornodeinstance.cpp -SOURCES += $$PWD/dummycontextobject.cpp -SOURCES += $$PWD/childrenchangeeventfilter.cpp -SOURCES += $$PWD/componentnodeinstance.cpp -SOURCES += $$PWD/dummynodeinstance.cpp SOURCES += $$PWD/nodeinstanceclientproxy.cpp -SOURCES += $$PWD/nodeinstancemetaobject.cpp -SOURCES += $$PWD/nodeinstanceserver.cpp -SOURCES += $$PWD/nodeinstancesignalspy.cpp -SOURCES += $$PWD/objectnodeinstance.cpp -SOURCES += $$PWD/qmlpropertychangesnodeinstance.cpp -SOURCES += $$PWD/qmlstatenodeinstance.cpp -SOURCES += $$PWD/qmltransitionnodeinstance.cpp -SOURCES += $$PWD/servernodeinstance.cpp -SOURCES += $$PWD/anchorchangesnodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp index 7a5d50ac6a..87bf91039c 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp +++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp @@ -54,6 +54,7 @@ #include "changestatecommand.h" #include "completecomponentcommand.h" #include "synchronizecommand.h" +#include "removesharedmemorycommand.h" #include "tokencommand.h" #include "informationchangedcommand.h" @@ -64,6 +65,8 @@ #include "statepreviewimagechangedcommand.h" #include "componentcompletedcommand.h" #include "changenodesourcecommand.h" +#include "endpuppetcommand.h" +#include "debugoutputcommand.h" namespace QmlDesigner { @@ -92,7 +95,6 @@ void NodeInstanceClientProxy::writeCommand(const QVariant &command) QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_8); - out << quint32(0); out << quint32(m_writeCommandCounter); m_writeCommandCounter++; @@ -138,6 +140,11 @@ void NodeInstanceClientProxy::token(const TokenCommand &command) writeCommand(QVariant::fromValue(command)); } +void NodeInstanceClientProxy::debugOutput(const DebugOutputCommand &command) +{ + writeCommand(QVariant::fromValue(command)); +} + void NodeInstanceClientProxy::flush() { } @@ -276,11 +283,22 @@ void NodeInstanceClientProxy::changeNodeSource(const ChangeNodeSourceCommand &co { nodeInstanceServer()->changeNodeSource(command); } + +void NodeInstanceClientProxy::removeSharedMemory(const RemoveSharedMemoryCommand &command) +{ + nodeInstanceServer()->removeSharedMemory(command); +} void NodeInstanceClientProxy::redirectToken(const TokenCommand &command) { nodeInstanceServer()->token(command); } +void NodeInstanceClientProxy::redirectToken(const EndPuppetCommand & /*command*/) +{ + qDebug() << "End Process: " << QCoreApplication::applicationPid(); + QCoreApplication::exit(); +} + void NodeInstanceClientProxy::dispatchCommand(const QVariant &command) { static const int createInstancesCommandType = QMetaType::type("CreateInstancesCommand"); @@ -298,7 +316,9 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command) static const int completeComponentCommandType = QMetaType::type("CompleteComponentCommand"); static const int synchronizeCommandType = QMetaType::type("SynchronizeCommand"); static const int changeNodeSourceCommandType = QMetaType::type("ChangeNodeSourceCommand"); + static const int removeSharedMemoryCommandType = QMetaType::type("RemoveSharedMemoryCommand"); static const int tokenCommandType = QMetaType::type("TokenCommand"); + static const int endPuppetCommandType = QMetaType::type("EndPuppetCommand"); if (command.userType() == createInstancesCommandType) { createInstances(command.value<CreateInstancesCommand>()); @@ -328,8 +348,12 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command) completeComponent(command.value<CompleteComponentCommand>()); else if (command.userType() == changeNodeSourceCommandType) changeNodeSource(command.value<ChangeNodeSourceCommand>()); + else if (command.userType() == removeSharedMemoryCommandType) + removeSharedMemory(command.value<RemoveSharedMemoryCommand>()); else if (command.userType() == tokenCommandType) redirectToken(command.value<TokenCommand>()); + else if (command.userType() == endPuppetCommandType) + redirectToken(command.value<EndPuppetCommand>()); else if (command.userType() == synchronizeCommandType) { SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>(); m_synchronizeId = synchronizeCommand.synchronizeId(); diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h index 418381799a..7dc0dbe238 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h +++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h @@ -57,6 +57,7 @@ class RemovePropertiesCommand; class CompleteComponentCommand; class ChangeStateCommand; class ChangeNodeSourceCommand; +class EndPuppetCommand; class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterface @@ -71,8 +72,9 @@ public: void pixmapChanged(const PixmapChangedCommand &command); void childrenChanged(const ChildrenChangedCommand &command); void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command); - void componentCompleted(const ComponentCompletedCommand &command); + void componentCompleted(const ComponentCompletedCommand &command); void token(const TokenCommand &command); + void debugOutput(const DebugOutputCommand &command); void flush(); void synchronizeWithClientProcess(); @@ -99,7 +101,9 @@ protected: void changeState(const ChangeStateCommand &command); void completeComponent(const CompleteComponentCommand &command); void changeNodeSource(const ChangeNodeSourceCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); void redirectToken(const TokenCommand &command); + void redirectToken(const EndPuppetCommand &command); private slots: void readDataStream(); diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h index 3d560e2c4c..bb27f2c8da 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h @@ -41,6 +41,8 @@ class ChildrenChangedCommand; class StatePreviewImageChangedCommand; class ComponentCompletedCommand; class TokenCommand; +class RemoveSharedMemoryCommand; +class DebugOutputCommand; class NodeInstanceClientInterface { @@ -52,6 +54,7 @@ public: virtual void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command) = 0; virtual void componentCompleted(const ComponentCompletedCommand &command) = 0; virtual void token(const TokenCommand &command) = 0; + virtual void debugOutput(const DebugOutputCommand &command) = 0; virtual void flush() {}; virtual void synchronizeWithClientProcess() {} diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp index 6a0ca37b50..aeedc555ad 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp @@ -59,7 +59,9 @@ #include "componentcompletedcommand.h" #include "synchronizecommand.h" #include "tokencommand.h" - +#include "removesharedmemorycommand.h" +#include "endpuppetcommand.h" +#include "debugoutputcommand.h" namespace QmlDesigner { @@ -170,6 +172,15 @@ void NodeInstanceServerInterface::registerCommands() qRegisterMetaType<TokenCommand>("TokenCommand"); qRegisterMetaTypeStreamOperators<TokenCommand>("TokenCommand"); + + qRegisterMetaType<RemoveSharedMemoryCommand>("RemoveSharedMemoryCommand"); + qRegisterMetaTypeStreamOperators<RemoveSharedMemoryCommand>("RemoveSharedMemoryCommand"); + + qRegisterMetaType<EndPuppetCommand>("EndPuppetCommand"); + qRegisterMetaTypeStreamOperators<EndPuppetCommand>("EndPuppetCommand"); + + qRegisterMetaType<DebugOutputCommand>("DebugOutputCommand"); + qRegisterMetaTypeStreamOperators<DebugOutputCommand>("DebugOutputCommand"); } } diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h index 2b11b42f61..b117dbe85b 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h @@ -53,6 +53,7 @@ class ChangeStateCommand; class CompleteComponentCommand; class ChangeNodeSourceCommand; class TokenCommand; +class RemoveSharedMemoryCommand; class NodeInstanceServerInterface : public QObject { @@ -80,6 +81,7 @@ public: virtual void completeComponent(const CompleteComponentCommand &command) = 0; virtual void changeNodeSource(const ChangeNodeSourceCommand &command) = 0; virtual void token(const TokenCommand &command) = 0; + virtual void removeSharedMemory(const RemoveSharedMemoryCommand &command) = 0; static void registerCommands(); }; diff --git a/share/qtcreator/qml/qmlpuppet/instances/anchorchangesnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/anchorchangesnodeinstance.cpp index d1cbe5ba23..d1cbe5ba23 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/anchorchangesnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/anchorchangesnodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/anchorchangesnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/anchorchangesnodeinstance.h new file mode 100644 index 0000000000..9205bd1cfd --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/anchorchangesnodeinstance.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + + +#ifndef QMLDESIGNER_ANCHORCHANGESNODEINSTANCE_H +#define QMLDESIGNER_ANCHORCHANGESNODEINSTANCE_H + +#include "objectnodeinstance.h" + +#include <QPair> +#include <QWeakPointer> + +QT_BEGIN_NAMESPACE +class QQmlProperty; +QT_END_NAMESPACE + +namespace QmlDesigner { + +namespace Internal { + +class AnchorChangesNodeInstance : public ObjectNodeInstance +{ +public: + typedef QSharedPointer<AnchorChangesNodeInstance> Pointer; + typedef QWeakPointer<AnchorChangesNodeInstance> WeakPointer; + + static Pointer create(QObject *objectToBeWrapped); + + virtual void setPropertyVariant(const QString &name, const QVariant &value); + virtual void setPropertyBinding(const QString &name, const QString &expression); + virtual QVariant property(const QString &name) const; + virtual void resetProperty(const QString &name); + + using ObjectNodeInstance::reparent; // keep the virtual reparent(...) method around + void reparent(const ServerNodeInstance &oldParentInstance, + const QString &oldParentProperty, + const ServerNodeInstance &newParentInstance, + const QString &newParentProperty); + +protected: + AnchorChangesNodeInstance(QObject *object); + QObject *changesObject() const; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // QMLDESIGNER_ANCHORCHANGESNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.cpp new file mode 100644 index 0000000000..ac8bd0f6ad --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "behaviornodeinstance.h" + +#include <private/qquickbehavior_p.h> + +namespace QmlDesigner { +namespace Internal { + +BehaviorNodeInstance::BehaviorNodeInstance(QObject *object) + : ObjectNodeInstance(object), + m_isEnabled(true) +{ +} + +BehaviorNodeInstance::Pointer BehaviorNodeInstance::create(QObject *object) +{ + QQuickBehavior* behavior = qobject_cast<QQuickBehavior*>(object); + + Q_ASSERT(behavior); + + Pointer instance(new BehaviorNodeInstance(behavior)); + + instance->populateResetHashes(); + + behavior->setEnabled(false); + + return instance; +} + +void BehaviorNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) +{ + if (name == "enabled") + return; + + ObjectNodeInstance::setPropertyVariant(name, value); +} + +void BehaviorNodeInstance::setPropertyBinding(const QString &name, const QString &expression) +{ + if (name == "enabled") + return; + + ObjectNodeInstance::setPropertyBinding(name, expression); +} + +QVariant BehaviorNodeInstance::property(const QString &name) const +{ + if (name == "enabled") + return QVariant::fromValue(m_isEnabled); + + return ObjectNodeInstance::property(name); +} + +void BehaviorNodeInstance::resetProperty(const QString &name) +{ + if (name == "enabled") + m_isEnabled = true; + + ObjectNodeInstance::resetProperty(name); +} + + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/instances/behaviornodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.h index 3d8d7f890d..3d8d7f890d 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/behaviornodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.h diff --git a/share/qtcreator/qml/qmlpuppet/instances/childrenchangeeventfilter.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/childrenchangeeventfilter.cpp index e636519c0d..e636519c0d 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/childrenchangeeventfilter.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/childrenchangeeventfilter.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/childrenchangeeventfilter.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/childrenchangeeventfilter.h index b891604531..b891604531 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/childrenchangeeventfilter.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/childrenchangeeventfilter.h diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp new file mode 100644 index 0000000000..59f090f970 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "componentnodeinstance.h" + +#include <QQmlComponent> +#include <QQmlContext> + +#include <QDebug> + +namespace QmlDesigner { +namespace Internal { + + +ComponentNodeInstance::ComponentNodeInstance(QQmlComponent *component) + : ObjectNodeInstance(component) +{ +} + +QQmlComponent *ComponentNodeInstance::component() const +{ + Q_ASSERT(qobject_cast<QQmlComponent*>(object())); + return static_cast<QQmlComponent*>(object()); +} + +ComponentNodeInstance::Pointer ComponentNodeInstance::create(QObject *object) +{ + QQmlComponent *component = qobject_cast<QQmlComponent *>(object); + + Q_ASSERT(component); + + Pointer instance(new ComponentNodeInstance(component)); + + instance->populateResetHashes(); + + return instance; +} + +bool ComponentNodeInstance::hasContent() const +{ + return true; +} + +void ComponentNodeInstance::setNodeSource(const QString &source) +{ + QByteArray importArray; + foreach (const QString &import, nodeInstanceServer()->imports()) { + importArray.append(import.toUtf8()); + } + + QByteArray data(source.toUtf8()); + + data.prepend(importArray); + data.append("\n"); + + component()->setData(data, QUrl(nodeInstanceServer()->fileUrl().toString() + + QLatin1Char('_')+ id())); + setId(id()); + + if (component()->isError()) { + foreach (const QQmlError &error, component()->errors()) + qDebug() << error; + } + +} + +} // Internal +} // QmlDesigner diff --git a/src/plugins/qmldesigner/components/integration/integrationcore.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.h index d54e1a93b9..a16f798de9 100644 --- a/src/plugins/qmldesigner/components/integration/integrationcore.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.h @@ -27,38 +27,36 @@ ** ****************************************************************************/ -#ifndef QMLDESIGNERCORE_H -#define QMLDESIGNERCORE_H +#ifndef COMPONENTNODEINSTANCE_H +#define COMPONENTNODEINSTANCE_H -#include <QObject> +#include "objectnodeinstance.h" QT_BEGIN_NAMESPACE -class QWidget; -class QDialog; +class QQmlComponent; QT_END_NAMESPACE namespace QmlDesigner { +namespace Internal { -class ItemLibraryWidget; -class FormWindowManager; -class PluginManager; -class CorePrivate; - -class IntegrationCore +class ComponentNodeInstance : public ObjectNodeInstance { - Q_DISABLE_COPY(IntegrationCore) public: - IntegrationCore(); - ~IntegrationCore(); + typedef QSharedPointer<ComponentNodeInstance> Pointer; + typedef QWeakPointer<ComponentNodeInstance> WeakPointer; + ComponentNodeInstance(QQmlComponent *component); + static Pointer create(QObject *objectToBeWrapped); + + bool hasContent() const; - PluginManager *pluginManager() const; + void setNodeSource(const QString &source); - static IntegrationCore *instance(); +private: //function + QQmlComponent *component() const; -private: - CorePrivate *d; }; -} // namspace QmlDesigner +} // Internal +} // QmlDesigner -#endif // QMLDESIGNERCORE_H +#endif // COMPONENTNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/instances/dummycontextobject.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.cpp index 4b6ab40f48..4b6ab40f48 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/dummycontextobject.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.cpp diff --git a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h index 68455be812..1ab0b4f407 100644 --- a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h @@ -27,30 +27,34 @@ ** ****************************************************************************/ -#ifndef CUSTOMSTYLEPLUGIN_H -#define CUSTOMSTYLEPLUGIN_H +#ifndef DUMMYCONTEXTOBJECT_H +#define DUMMYCONTEXTOBJECT_H -#include <iwidgetplugin.h> +#include <QObject> +#include <QPointer> +#include <qqml.h> namespace QmlDesigner { -class CustomStylePlugin : public QObject, QmlDesigner::IWidgetPlugin +class DummyContextObject : public QObject { Q_OBJECT -#if QT_VERSION >= 0x050000 - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QmlDesignerPlugin" FILE "customstyleplugin.json") -#endif - Q_INTERFACES(QmlDesigner::IWidgetPlugin) + Q_PROPERTY(QObject * parent READ parentDummy WRITE setParentDummy NOTIFY parentDummyChanged DESIGNABLE false FINAL) public: - CustomStylePlugin(); - ~CustomStylePlugin() {} + explicit DummyContextObject(QObject *parent = 0); - QString metaInfo() const; - QString pluginName() const; + QObject *parentDummy() const; + void setParentDummy(QObject *parentDummy); +signals: + void parentDummyChanged(); + +private: + QPointer<QObject> m_dummyParent; }; } // namespace QmlDesigner -#endif // CUSTOMSTYLEPLUGIN_H +QML_DECLARE_TYPE(QmlDesigner::DummyContextObject) +#endif // DUMMYCONTEXTOBJECT_H diff --git a/share/qtcreator/qml/qmlpuppet/instances/dummynodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummynodeinstance.cpp index ab06dfed8d..ab06dfed8d 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/dummynodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummynodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/dummynodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummynodeinstance.h index 846cf5630c..846cf5630c 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/dummynodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummynodeinstance.h diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri index 1eeb3d40b5..28a733cf66 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri @@ -1,15 +1,45 @@ INCLUDEPATH += $$PWD/ -HEADERS += $$PWD/qt5nodeinstanceserver.h \ - instances/qt5informationnodeinstanceserver.h \ - instances/qt5rendernodeinstanceserver.h \ - instances/qt5previewnodeinstanceserver.h +HEADERS += $$PWD/qt5nodeinstanceserver.h +HEADERS += $$PWD/qt5informationnodeinstanceserver.h +HEADERS += $$PWD/qt5rendernodeinstanceserver.h +HEADERS += $$PWD/qt5previewnodeinstanceserver.h HEADERS += $$PWD/qt5nodeinstanceclientproxy.h -HEADERS += $$PWD/sgitemnodeinstance.h +HEADERS += $$PWD/quickitemnodeinstance.h +HEADERS += $$PWD/behaviornodeinstance.h +HEADERS += $$PWD/dummycontextobject.h +HEADERS += $$PWD/childrenchangeeventfilter.h +HEADERS += $$PWD/componentnodeinstance.h +HEADERS += $$PWD/dummynodeinstance.h +HEADERS += $$PWD/nodeinstancemetaobject.h +HEADERS += $$PWD/nodeinstanceserver.h +HEADERS += $$PWD/nodeinstancesignalspy.h +HEADERS += $$PWD/objectnodeinstance.h +HEADERS += $$PWD/qmlpropertychangesnodeinstance.h +HEADERS += $$PWD/qmlstatenodeinstance.h +HEADERS += $$PWD/qmltransitionnodeinstance.h +HEADERS += $$PWD/servernodeinstance.h +HEADERS += $$PWD/anchorchangesnodeinstance.h +HEADERS += $$PWD/positionernodeinstance.h -SOURCES += $$PWD/qt5nodeinstanceserver.cpp \ - instances/qt5informationnodeinstanceserver.cpp \ - instances/qt5rendernodeinstanceserver.cpp \ - instances/qt5previewnodeinstanceserver.cpp +SOURCES += $$PWD/qt5nodeinstanceserver.cpp +SOURCES += $$PWD/qt5informationnodeinstanceserver.cpp +SOURCES += $$PWD/qt5rendernodeinstanceserver.cpp +SOURCES += $$PWD/qt5previewnodeinstanceserver.cpp SOURCES += $$PWD/qt5nodeinstanceclientproxy.cpp -SOURCES += $$PWD/sgitemnodeinstance.cpp +SOURCES += $$PWD/quickitemnodeinstance.cpp +SOURCES += $$PWD/behaviornodeinstance.cpp +SOURCES += $$PWD/dummycontextobject.cpp +SOURCES += $$PWD/childrenchangeeventfilter.cpp +SOURCES += $$PWD/componentnodeinstance.cpp +SOURCES += $$PWD/dummynodeinstance.cpp +SOURCES += $$PWD/nodeinstancemetaobject.cpp +SOURCES += $$PWD/nodeinstanceserver.cpp +SOURCES += $$PWD/nodeinstancesignalspy.cpp +SOURCES += $$PWD/objectnodeinstance.cpp +SOURCES += $$PWD/qmlpropertychangesnodeinstance.cpp +SOURCES += $$PWD/qmlstatenodeinstance.cpp +SOURCES += $$PWD/qmltransitionnodeinstance.cpp +SOURCES += $$PWD/servernodeinstance.cpp +SOURCES += $$PWD/anchorchangesnodeinstance.cpp +SOURCES += $$PWD/positionernodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancemetaobject.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancemetaobject.cpp new file mode 100644 index 0000000000..ce1297ea97 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancemetaobject.cpp @@ -0,0 +1,366 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "nodeinstancemetaobject.h" + +#include "objectnodeinstance.h" +#include <QSharedPointer> +#include <QMetaProperty> +#include <qnumeric.h> +#include <QDebug> + +#include <private/qqmlengine_p.h> +#include <private/qqmlpropertycache_p.h> + +namespace QmlDesigner { +namespace Internal { + +static QHash<QDynamicMetaObjectData *, bool> nodeInstanceMetaObjectList; + +struct MetaPropertyData { + inline QPair<QVariant, bool> &getDataRef(int idx) { + while (m_data.count() <= idx) + m_data << QPair<QVariant, bool>(QVariant(), false); + return m_data[idx]; + } + + inline QVariant &getData(int idx) { + QPair<QVariant, bool> &prop = getDataRef(idx); + if (!prop.second) { + prop.first = QVariant(); + prop.second = true; + } + return prop.first; + } + + inline bool hasData(int idx) const { + if (idx >= m_data.count()) + return false; + return m_data[idx].second; + } + + inline int count() { return m_data.count(); } + + QList<QPair<QVariant, bool> > m_data; +}; + +static bool constructedMetaData(const QQmlVMEMetaData* data) +{ + return data->varPropertyCount == 0 + && data->propertyCount == 0 + && data->aliasCount == 0 + && data->signalCount == 0 + && data->methodCount == 0; +} + +static QQmlVMEMetaData* fakeMetaData() +{ + QQmlVMEMetaData* data = new QQmlVMEMetaData; + data->varPropertyCount = 0; + data->propertyCount = 0; + data->aliasCount = 0; + data->signalCount = 0; + data->methodCount = 0; + + return data; +} + +static const QQmlVMEMetaData* vMEMetaDataForObject(QObject *object) +{ + QQmlVMEMetaObject *metaObject = QQmlVMEMetaObject::get(object); + if (metaObject) + return metaObject->metaData; + + return fakeMetaData(); +} + +static QQmlPropertyCache *cacheForObject(QObject *object, QQmlEngine *engine) +{ + QQmlVMEMetaObject *metaObject = QQmlVMEMetaObject::get(object); + if (metaObject) + return metaObject->cache; + + return QQmlEnginePrivate::get(engine)->cache(object); +} + +static QAbstractDynamicMetaObject *abstractDynamicMetaObject(QObject *object) +{ + QObjectPrivate *op = QObjectPrivate::get(object); + if (op->metaObject) + return static_cast<QAbstractDynamicMetaObject *>(op->metaObject); + return const_cast<QAbstractDynamicMetaObject *>(static_cast<const QAbstractDynamicMetaObject *>(object->metaObject())); +} + + +NodeInstanceMetaObject *NodeInstanceMetaObject::createNodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QQmlEngine *engine) +{ + //Avoid setting up multiple NodeInstanceMetaObjects on the same QObject + QObjectPrivate *op = QObjectPrivate::get(nodeInstance->object()); + QDynamicMetaObjectData *parent = op->metaObject; + if (nodeInstanceMetaObjectList.contains(parent)) + return static_cast<NodeInstanceMetaObject *>(parent); + + return new NodeInstanceMetaObject(nodeInstance, engine); +} + +NodeInstanceMetaObject *NodeInstanceMetaObject::createNodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine) +{ + //Avoid setting up multiple NodeInstanceMetaObjects on the same QObject + QObjectPrivate *op = QObjectPrivate::get(nodeInstance->object()); + QDynamicMetaObjectData *parent = op->metaObject; + if (nodeInstanceMetaObjectList.contains(parent)) + return static_cast<NodeInstanceMetaObject *>(parent); + + return new NodeInstanceMetaObject(nodeInstance, object, prefix, engine); +} + +void NodeInstanceMetaObject::init(QObject *object, QQmlEngine *engine) +{ + //Creating QQmlOpenMetaObjectType + m_type = new QQmlOpenMetaObjectType(metaObjectParent(), engine); + m_type->addref(); + //Assigning type to this + copyTypeMetaObject(); + + //Assign this to object + QObjectPrivate *op = QObjectPrivate::get(object); + op->metaObject = this; + + //create cache + cache = m_cache = QQmlEnginePrivate::get(engine)->cache(this); + cache->addref(); + + //If our parent is not a VMEMetaObject we just se the flag to false again + if (constructedMetaData(metaData)) + QQmlData::get(object)->hasVMEMetaObject = false; + + nodeInstanceMetaObjectList.insert(this, true); + hasAssignedMetaObjectData = true; +} + +NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstance::Pointer &nodeInstance, QQmlEngine *engine) + : QQmlVMEMetaObject(nodeInstance->object(), cacheForObject(nodeInstance->object(), engine), vMEMetaDataForObject(nodeInstance->object())), + m_nodeInstance(nodeInstance), + m_context(engine->contextForObject(nodeInstance->object())), + m_data(new MetaPropertyData), + m_cache(0) +{ + init(nodeInstance->object(), engine); + + QQmlData *ddata = QQmlData::get(nodeInstance->object(), false); + + //Assign cache to object + if (ddata && ddata->propertyCache) { + cache->setParent(ddata->propertyCache); + cache->invalidate(engine, this); + ddata->propertyCache = m_cache; + } + +} + +NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine) + : QQmlVMEMetaObject(object, cacheForObject(object, engine), vMEMetaDataForObject(object)), + m_nodeInstance(nodeInstance), + m_context(engine->contextForObject(object)), + m_prefix(prefix), + + m_data(new MetaPropertyData), + m_cache(0) +{ + init(object, engine); +} + +NodeInstanceMetaObject::~NodeInstanceMetaObject() +{ + cache->release(); + m_type->release(); + + nodeInstanceMetaObjectList.remove(this); +} + +void NodeInstanceMetaObject::createNewProperty(const QString &name) +{ + int id = createProperty(name.toLatin1(), 0); + setValue(id, QVariant()); + Q_ASSERT(id >= 0); + Q_UNUSED(id); + + + //Updating cache + QQmlPropertyCache *oldParent = m_cache->parent(); + QQmlEnginePrivate::get(m_context->engine())->cache(this)->invalidate(m_context->engine(), this); + m_cache->setParent(oldParent); + + QQmlProperty property(myObject(), name, m_context); + Q_ASSERT(property.isValid()); +} + +int NodeInstanceMetaObject::createProperty(const char *name, const char *) +{ + int id = m_type->createProperty(name); + copyTypeMetaObject(); + return id; +} + +void NodeInstanceMetaObject::setValue(int id, const QVariant &value) +{ + QPair<QVariant, bool> &prop = m_data->getDataRef(id); + prop.first = propertyWriteValue(id, value); + prop.second = true; + QMetaObject::activate(myObject(), id + m_type->signalOffset(), 0); +} + +QVariant NodeInstanceMetaObject::propertyWriteValue(int, const QVariant &value) +{ + return value; +} + +int NodeInstanceMetaObject::openMetaCall(QMetaObject::Call call, int id, void **a) +{ + if ((call == QMetaObject::ReadProperty || call == QMetaObject::WriteProperty) + && id >= m_type->propertyOffset()) { + int propId = id - m_type->propertyOffset(); + if (call == QMetaObject::ReadProperty) { + //propertyRead(propId); + *reinterpret_cast<QVariant *>(a[0]) = m_data->getData(propId); + } else if (call == QMetaObject::WriteProperty) { + if (propId <= m_data->count() || m_data->m_data[propId].first != *reinterpret_cast<QVariant *>(a[0])) { + //propertyWrite(propId); + QPair<QVariant, bool> &prop = m_data->getDataRef(propId); + prop.first = propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0])); + prop.second = true; + //propertyWritten(propId); + activate(myObject(), m_type->signalOffset() + propId, 0); + } + } + return -1; + } else { + QAbstractDynamicMetaObject *directParent = parent(); + if (directParent) + return directParent->metaCall(call, id, a); + else + return myObject()->qt_metacall(call, id, a); + } +} + +int NodeInstanceMetaObject::metaCall(QMetaObject::Call call, int id, void **a) +{ + int metaCallReturnValue = -1; + + const QMetaProperty propertyById = QQmlVMEMetaObject::property(id); + + if (call == QMetaObject::WriteProperty + && propertyById.userType() == QMetaType::QVariant + && reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double + && qIsNaN(reinterpret_cast<QVariant *>(a[0])->toDouble())) { + return -1; + } + + if (call == QMetaObject::WriteProperty + && propertyById.userType() == QMetaType::Double + && qIsNaN(*reinterpret_cast<double*>(a[0]))) { + return -1; + } + + if (call == QMetaObject::WriteProperty + && propertyById.userType() == QMetaType::Float + && qIsNaN(*reinterpret_cast<float*>(a[0]))) { + return -1; + } + + QVariant oldValue; + + if (call == QMetaObject::WriteProperty && !propertyById.hasNotifySignal()) + { + oldValue = propertyById.read(myObject()); + } + + ObjectNodeInstance::Pointer objectNodeInstance = m_nodeInstance.toStrongRef(); + + QAbstractDynamicMetaObject *directParent = parent(); + if (directParent && id < directParent->propertyOffset()) { + metaCallReturnValue = directParent->metaCall(call, id, a); + } else { + openMetaCall(call, id, a); + } + + if ((call == QMetaObject::WriteProperty || call == QMetaObject::ReadProperty) && metaCallReturnValue < 0) { + if (objectNodeInstance + && objectNodeInstance->nodeInstanceServer() + && objectNodeInstance->nodeInstanceServer()->dummyContextObject() + && !(objectNodeInstance && !objectNodeInstance->isRootNodeInstance() + && property(id).name() == QLatin1String("parent"))) { + + QObject *contextDummyObject = objectNodeInstance->nodeInstanceServer()->dummyContextObject(); + int properyIndex = contextDummyObject->metaObject()->indexOfProperty(propertyById.name()); + if (properyIndex >= 0) + metaCallReturnValue = contextDummyObject->qt_metacall(call, properyIndex, a); + } + } + + if (metaCallReturnValue >= 0 + && call == QMetaObject::WriteProperty + && !propertyById.hasNotifySignal() + && oldValue != propertyById.read(myObject())) + notifyPropertyChange(id); + + return metaCallReturnValue; +} + +void NodeInstanceMetaObject::notifyPropertyChange(int id) +{ + ObjectNodeInstance::Pointer objectNodeInstance = m_nodeInstance.toStrongRef(); + const QMetaProperty propertyById = property(id); + + if (objectNodeInstance && objectNodeInstance->nodeInstanceServer()) { + if (id < propertyOffset()) { + objectNodeInstance->nodeInstanceServer()->notifyPropertyChange(objectNodeInstance->instanceId(), m_prefix + propertyById.name()); + } else { + objectNodeInstance->nodeInstanceServer()->notifyPropertyChange(objectNodeInstance->instanceId(), m_prefix + name(id - propertyOffset())); + } + } +} + +int NodeInstanceMetaObject::count() const +{ + return m_type->propertyCount(); +} + +QByteArray NodeInstanceMetaObject::name(int idx) const +{ + return m_type->propertyName(idx); +} + +void NodeInstanceMetaObject::copyTypeMetaObject() +{ + *static_cast<QMetaObject *>(this) = *m_type->metaObject(); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancemetaobject.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancemetaobject.h new file mode 100644 index 0000000000..bd24359b16 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancemetaobject.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef NODEINSTANCEMETAOBJECT_H +#define NODEINSTANCEMETAOBJECT_H + +#include <QQmlContext> +#include <QScopedPointer> +#include <private/qqmlopenmetaobject_p.h> +#include <private/qqmlvmemetaobject_p.h> + +namespace QmlDesigner { +namespace Internal { + +class ObjectNodeInstance; +typedef QSharedPointer<ObjectNodeInstance> ObjectNodeInstancePointer; +typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer; + +struct MetaPropertyData; + +class NodeInstanceMetaObject : public QQmlVMEMetaObject +{ +public: + static NodeInstanceMetaObject *createNodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QQmlEngine *engine); + static NodeInstanceMetaObject *createNodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine); + ~NodeInstanceMetaObject(); + void createNewProperty(const QString &name); + +protected: + NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QQmlEngine *engine); + NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine); + + int openMetaCall(QMetaObject::Call _c, int _id, void **_a); + int metaCall(QMetaObject::Call _c, int _id, void **_a); + void notifyPropertyChange(int id); + void setValue(int id, const QVariant &value); + int createProperty(const char *, const char *); + QVariant propertyWriteValue(int, const QVariant &); + + QObject *myObject() const { return QQmlVMEMetaObject::object; } + QAbstractDynamicMetaObject *parent() const { return const_cast<QAbstractDynamicMetaObject *>(dynamicMetaObjectParent()); } + + const QAbstractDynamicMetaObject *dynamicMetaObjectParent() const + { + if (QQmlVMEMetaObject::parent.isT1()) + return QQmlVMEMetaObject::parent.asT1()->toDynamicMetaObject(QQmlVMEMetaObject::object); + else + return 0; + } + + const QMetaObject *metaObjectParent() const + { + if (QQmlVMEMetaObject::parent.isT1()) + return QQmlVMEMetaObject::parent.asT1()->toDynamicMetaObject(QQmlVMEMetaObject::object); + + return QQmlVMEMetaObject::parent.asT2(); + } + + int propertyOffset() const { return cache->propertyOffset(); } + + int count() const; + QByteArray name(int) const; + + void copyTypeMetaObject(); + +private: + void init(QObject *, QQmlEngine *engine); + + ObjectNodeInstanceWeakPointer m_nodeInstance; + QString m_prefix; + QPointer<QQmlContext> m_context; + QQmlOpenMetaObjectType *m_type; + QScopedPointer<MetaPropertyData> m_data; + //QAbstractDynamicMetaObject *m_parent; + QQmlPropertyCache *m_cache; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // NODEINSTANCEMETAOBJECT_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp new file mode 100644 index 0000000000..c2ed5183dd --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -0,0 +1,1177 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "nodeinstanceserver.h" + +#include <QQmlEngine> +#include <QFileSystemWatcher> +#include <QUrl> +#include <QSet> +#include <QDir> +#include <QVariant> +#include <QMetaType> +#include <QQmlComponent> +#include <QQmlContext> +#include <qqmllist.h> +#include <QAbstractAnimation> +#include <private/qabstractanimation_p.h> +#include <QMutableVectorIterator> +#include <private/qquickview_p.h> + +#include "servernodeinstance.h" +#include "objectnodeinstance.h" +#include "childrenchangeeventfilter.h" +#include "propertyabstractcontainer.h" +#include "propertybindingcontainer.h" +#include "propertyvaluecontainer.h" +#include "instancecontainer.h" +#include "createinstancescommand.h" +#include "changefileurlcommand.h" +#include "clearscenecommand.h" +#include "reparentinstancescommand.h" +#include "changevaluescommand.h" +#include "changeauxiliarycommand.h" +#include "changebindingscommand.h" +#include "changeidscommand.h" +#include "removeinstancescommand.h" +#include "nodeinstanceclientinterface.h" +#include "removepropertiescommand.h" +#include "valueschangedcommand.h" +#include "informationchangedcommand.h" +#include "pixmapchangedcommand.h" +#include "commondefines.h" +#include "childrenchangeeventfilter.h" +#include "changestatecommand.h" +#include "childrenchangedcommand.h" +#include "completecomponentcommand.h" +#include "componentcompletedcommand.h" +#include "createscenecommand.h" +#include "changenodesourcecommand.h" +#include "tokencommand.h" +#include "removesharedmemorycommand.h" + +#include "dummycontextobject.h" + + +namespace QmlDesigner { + +NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : + NodeInstanceServerInterface(), + m_childrenChangeEventFilter(new Internal::ChildrenChangeEventFilter(this)), + m_nodeInstanceClient(nodeInstanceClient), + m_timer(0), + m_renderTimerInterval(16), + m_slowRenderTimer(false), + m_slowRenderTimerInterval(200) +{ + qmlRegisterType<DummyContextObject>("QmlDesigner", 1, 0, "DummyContextObject"); + + connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*))); +} + +NodeInstanceServer::~NodeInstanceServer() +{ +} + +QList<ServerNodeInstance> NodeInstanceServer::createInstances(const QVector<InstanceContainer> &containerVector) +{ + Q_ASSERT(declarativeView() || quickView()); + QList<ServerNodeInstance> instanceList; + foreach (const InstanceContainer &instanceContainer, containerVector) { + ServerNodeInstance instance; + if (instanceContainer.nodeSourceType() == InstanceContainer::ComponentSource) { + instance = ServerNodeInstance::create(this, instanceContainer, ServerNodeInstance::WrapAsComponent); + } else { + instance = ServerNodeInstance::create(this, instanceContainer, ServerNodeInstance::DoNotWrapAsComponent); + } + insertInstanceRelationship(instance); + instanceList.append(instance); + instance.internalObject()->installEventFilter(childrenChangeEventFilter()); + if (instanceContainer.instanceId() == 0) { + m_rootNodeInstance = instance; + resizeCanvasSizeToRootItemSize(); + } + + foreach (QQmlContext* context, allSubContextsForObject(instance.internalObject())) + setupDummysForContext(context); + } + + return instanceList; +} + +void NodeInstanceServer::createInstances(const CreateInstancesCommand &command) +{ + createInstances(command.instances()); + refreshBindings(); + startRenderTimer(); +} + +ServerNodeInstance NodeInstanceServer::instanceForId(qint32 id) const +{ + if (id < 0) + return ServerNodeInstance(); + + Q_ASSERT(m_idInstanceHash.contains(id)); + return m_idInstanceHash.value(id); +} + +bool NodeInstanceServer::hasInstanceForId(qint32 id) const +{ + if (id < 0) + return false; + + return m_idInstanceHash.contains(id); +} + +ServerNodeInstance NodeInstanceServer::instanceForObject(QObject *object) const +{ + Q_ASSERT(m_objectInstanceHash.contains(object)); + return m_objectInstanceHash.value(object); +} + +bool NodeInstanceServer::hasInstanceForObject(QObject *object) const +{ + if (object == 0) + return false; + + return m_objectInstanceHash.contains(object); +} + +void NodeInstanceServer::setRenderTimerInterval(int timerInterval) +{ + m_renderTimerInterval = timerInterval; +} + +void NodeInstanceServer::setSlowRenderTimerInterval(int timerInterval) +{ + m_slowRenderTimerInterval = timerInterval; +} + +void NodeInstanceServer::setTimerId(int timerId) +{ + m_timer = timerId; +} + +int NodeInstanceServer::timerId() const +{ + return m_timer; +} + +int NodeInstanceServer::renderTimerInterval() const +{ + return m_renderTimerInterval; +} + +void NodeInstanceServer::startRenderTimer() +{ + if (m_slowRenderTimer) + stopRenderTimer(); + + if (m_timer == 0) + m_timer = startTimer(m_renderTimerInterval); + + m_slowRenderTimer = false; +} + +void NodeInstanceServer::slowDownRenderTimer() +{ + if (!m_slowRenderTimer) + stopRenderTimer(); + + if (m_timer != 0) { + killTimer(m_timer); + m_timer = 0; + } + + if (m_timer == 0) + m_timer = startTimer(m_slowRenderTimerInterval); + + m_slowRenderTimer = true; +} + +void NodeInstanceServer::stopRenderTimer() +{ + if (m_timer) { + killTimer(m_timer); + m_timer = 0; + } +} + +void NodeInstanceServer::createScene(const CreateSceneCommand &command) +{ + initializeView(command.imports()); + QUnifiedTimer::instance()->setSlowdownFactor(0.00001); + QUnifiedTimer::instance()->setSlowModeEnabled(true); + + QList<ServerNodeInstance> instanceList = setupScene(command); + + refreshBindings(); + + startRenderTimer(); +} + +void NodeInstanceServer::clearScene(const ClearSceneCommand &/*command*/) +{ + stopRenderTimer(); + + removeAllInstanceRelationships(); + m_fileSystemWatcherHash.clear(); + m_rootNodeInstance.makeInvalid(); + m_changedPropertyList.clear(); + m_fileUrl.clear(); +} + +void NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) +{ + ServerNodeInstance oldState = activeStateInstance(); + if (activeStateInstance().isValid()) + activeStateInstance().deactivateState(); + + foreach (qint32 instanceId, command.instanceIds()) { + removeInstanceRelationsip(instanceId); + } + + if (oldState.isValid()) + oldState.activateState(); + + refreshBindings(); + startRenderTimer(); +} + +void NodeInstanceServer::removeProperties(const RemovePropertiesCommand &command) +{ + bool hasDynamicProperties = false; + foreach (const PropertyAbstractContainer &container, command.properties()) { + hasDynamicProperties |= container.isDynamic(); + resetInstanceProperty(container); + } + + if (hasDynamicProperties) + refreshBindings(); + + startRenderTimer(); +} + +void NodeInstanceServer::reparentInstances(const QVector<ReparentContainer> &containerVector) +{ + foreach (const ReparentContainer &container, containerVector) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isValid()) { + instance.reparent(instanceForId(container.oldParentInstanceId()), container.oldParentProperty(), instanceForId(container.newParentInstanceId()), container.newParentProperty()); + } + } + +} + +void NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command) +{ + reparentInstances(command.reparentInstances()); + refreshBindings(); + startRenderTimer(); +} + +void NodeInstanceServer::changeState(const ChangeStateCommand &command) +{ + if (hasInstanceForId(command.stateInstanceId())) { + if (activeStateInstance().isValid()) + activeStateInstance().deactivateState(); + ServerNodeInstance instance = instanceForId(command.stateInstanceId()); + instance.activateState(); + } else { + if (activeStateInstance().isValid()) + activeStateInstance().deactivateState(); + } + + startRenderTimer(); +} + +void NodeInstanceServer::completeComponent(const CompleteComponentCommand &command) +{ + QList<ServerNodeInstance> instanceList; + + foreach (qint32 instanceId, command.instances()) { + if (hasInstanceForId(instanceId)) { + ServerNodeInstance instance = instanceForId(instanceId); + instance.doComponentComplete(); + instanceList.append(instance); + } + } + + refreshBindings(); + + startRenderTimer(); +} + +void NodeInstanceServer::changeNodeSource(const ChangeNodeSourceCommand &command) +{ + if (hasInstanceForId(command.instanceId())) { + ServerNodeInstance instance = instanceForId(command.instanceId()); + if (instance.isValid()) + instance.setNodeSource(command.nodeSource()); + } + + startRenderTimer(); +} + +void NodeInstanceServer::token(const TokenCommand &/*command*/) +{ + +} + +void NodeInstanceServer::removeSharedMemory(const RemoveSharedMemoryCommand &/*command*/) +{ +} + +void NodeInstanceServer::setupImports(const QVector<AddImportContainer> &containerVector) +{ + foreach (const AddImportContainer &container, containerVector) { + QString importStatement = QString("import "); + + if (!container.fileName().isEmpty()) + importStatement += '"' + container.fileName() + '"'; + else if (!container.url().isEmpty()) + importStatement += container.url().toString(); + + if (!container.version().isEmpty()) + importStatement += ' ' + container.version(); + + if (!container.alias().isEmpty()) + importStatement += " as " + container.alias(); + + importStatement.append('\n'); + + if (!m_importList.contains(importStatement)) + m_importList.append(importStatement); + } + + delete m_importComponent.data(); + delete m_importComponentObject.data(); + + QString componentString; + foreach (const QString &importStatement, m_importList) + componentString += QString("%1").arg(importStatement); + + componentString += QString("Item {}\n"); + + if (quickView()) { + QQuickViewPrivate::get(quickView())->component = new QQmlComponent(engine(), quickView()); + m_importComponent = QQuickViewPrivate::get(quickView())->component; + } else { + m_importComponent = new QQmlComponent(engine(), 0); + } + + m_importComponent->setData(componentString.toUtf8(), fileUrl()); + m_importComponentObject = m_importComponent->create(); + + if (!m_importComponent->errorString().isEmpty()) + qDebug() << "QmlDesigner.NodeInstances: import wrong: " << m_importComponent->errorString(); +} + +void NodeInstanceServer::setupFileUrl(const QUrl &fileUrl) +{ + if (!fileUrl.isEmpty()) { + engine()->setBaseUrl(fileUrl); + m_fileUrl = fileUrl; + } +} + +void NodeInstanceServer::setupDummyData(const QUrl &fileUrl) +{ + if (!fileUrl.isEmpty()) { + QStringList dummyDataDirectoryList = dummyDataDirectories(QFileInfo(fileUrl.toLocalFile()).path()); + foreach (const QString &dummyDataDirectory, dummyDataDirectoryList) { + loadDummyDataFiles(dummyDataDirectory); + loadDummyDataContext(dummyDataDirectory); + } + } + + if (m_dummyContextObject.isNull()) + setupDefaultDummyData(); +} + +void NodeInstanceServer::setupDefaultDummyData() +{ + QQmlComponent component(engine()); + QByteArray defaultContextObjectArray("import QtQuick 1.0\n" + "import QmlDesigner 1.0\n" + "DummyContextObject {\n" + " parent: QtObject {\n" + " property real width: 360\n" + " property real height: 640\n" + " }\n" + "}\n"); + + component.setData(defaultContextObjectArray, fileUrl()); + m_dummyContextObject = component.create(); + + if (component.isError()) { + QList<QQmlError> errors = component.errors(); + foreach (const QQmlError &error, errors) { + qWarning() << error; + } + } + + if (m_dummyContextObject) { + qWarning() << "Loaded default dummy context object."; + m_dummyContextObject->setParent(this); + } + + refreshBindings(); +} + +QList<ServerNodeInstance> NodeInstanceServer::setupInstances(const CreateSceneCommand &command) +{ + QList<ServerNodeInstance> instanceList = createInstances(command.instances()); + + foreach (const IdContainer &container, command.ids()) { + if (hasInstanceForId(container.instanceId())) + instanceForId(container.instanceId()).setId(container.id()); + } + + foreach (const PropertyValueContainer &container, command.valueChanges()) { + if (container.isDynamic()) + setInstancePropertyVariant(container); + } + + foreach (const PropertyValueContainer &container, command.valueChanges()) { + if (!container.isDynamic()) + setInstancePropertyVariant(container); + } + + reparentInstances(command.reparentInstances()); + + foreach (const PropertyBindingContainer &container, command.bindingChanges()) { + if (container.isDynamic()) + setInstancePropertyBinding(container); + } + + foreach (const PropertyBindingContainer &container, command.bindingChanges()) { + if (!container.isDynamic()) + setInstancePropertyBinding(container); + } + + foreach (const PropertyValueContainer &container, command.auxiliaryChanges()) { + setInstanceAuxiliaryData(container); + } + + foreach (ServerNodeInstance instance, instanceList) + instance.doComponentComplete(); + + return instanceList; +} + +void NodeInstanceServer::changeFileUrl(const ChangeFileUrlCommand &command) +{ + m_fileUrl = command.fileUrl(); + + if (engine()) + engine()->setBaseUrl(m_fileUrl); + + refreshBindings(); + startRenderTimer(); +} + +void NodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command) +{ + bool hasDynamicProperties = false; + foreach (const PropertyValueContainer &container, command.valueChanges()) { + hasDynamicProperties |= container.isDynamic(); + setInstancePropertyVariant(container); + } + + if (hasDynamicProperties) + refreshBindings(); + + startRenderTimer(); +} + +void NodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command) +{ + foreach (const PropertyValueContainer &container, command.auxiliaryChanges()) { + setInstanceAuxiliaryData(container); + } + + startRenderTimer(); +} + +void NodeInstanceServer::changePropertyBindings(const ChangeBindingsCommand &command) +{ + bool hasDynamicProperties = false; + foreach (const PropertyBindingContainer &container, command.bindingChanges()) { + hasDynamicProperties |= container.isDynamic(); + setInstancePropertyBinding(container); + } + + if (hasDynamicProperties) + refreshBindings(); + + startRenderTimer(); +} + +void NodeInstanceServer::changeIds(const ChangeIdsCommand &command) +{ + foreach (const IdContainer &container, command.ids()) { + if (hasInstanceForId(container.instanceId())) + instanceForId(container.instanceId()).setId(container.id()); + } + + refreshBindings(); + startRenderTimer(); +} + +QQmlContext *NodeInstanceServer::context() const +{ + if (m_importComponentObject) { + QQmlContext *importComponentContext = QQmlEngine::contextForObject(m_importComponentObject.data()); + if (importComponentContext) // this should be the default + return importComponentContext; + } + + if (engine()) + return rootContext(); + + return 0; +} + +QQmlContext *NodeInstanceServer::rootContext() const +{ + return engine()->rootContext(); +} + +const QVector<NodeInstanceServer::InstancePropertyPair> NodeInstanceServer::changedPropertyList() const +{ + return m_changedPropertyList; +} + +void NodeInstanceServer::clearChangedPropertyList() +{ + m_changedPropertyList.clear(); +} + +void NodeInstanceServer::setupDummysForContext(QQmlContext *context) +{ + foreach (const DummyPair& dummyPair, m_dummyObjectList) { + if (dummyPair.second) { + context->setContextProperty(dummyPair.first, dummyPair.second.data()); + } + } +} + + +QList<QQmlContext*> NodeInstanceServer::allSubContextsForObject(QObject *object) +{ + QList<QQmlContext*> contextList; + + if (object) { + foreach (QObject *subObject, allSubObjectsForObject(object)) { + QQmlContext *contextOfObject = QQmlEngine::contextForObject(subObject); + if (contextOfObject) { + if (contextOfObject != context() && !contextList.contains(contextOfObject)) + contextList.append(contextOfObject); + } + } + } + + return contextList; +} + +QList<QObject*> NodeInstanceServer::allSubObjectsForObject(QObject *object) +{ + QList<QObject*> subChildren; + if (object) { + subChildren = object->findChildren<QObject*>(); + } + + return subChildren; +} + +void NodeInstanceServer::removeAllInstanceRelationships() +{ + // prevent destroyed() signals calling back + + foreach (ServerNodeInstance instance, m_objectInstanceHash) { + if (instance.isValid()) + instance.setId(QString()); + } + + //first the root object + if (rootNodeInstance().internalObject()) + rootNodeInstance().internalObject()->disconnect(); + + rootNodeInstance().makeInvalid(); + + + foreach (ServerNodeInstance instance, m_objectInstanceHash) { + if (instance.internalObject()) + instance.internalObject()->disconnect(); + instance.makeInvalid(); + } + + m_idInstanceHash.clear(); + m_objectInstanceHash.clear(); +} + +QFileSystemWatcher *NodeInstanceServer::dummydataFileSystemWatcher() +{ + if (m_dummdataFileSystemWatcher.isNull()) { + m_dummdataFileSystemWatcher = new QFileSystemWatcher(this); + connect(m_dummdataFileSystemWatcher.data(), SIGNAL(fileChanged(QString)), this, SLOT(refreshDummyData(QString))); + } + + return m_dummdataFileSystemWatcher.data(); +} + +QFileSystemWatcher *NodeInstanceServer::fileSystemWatcher() +{ + if (m_fileSystemWatcher.isNull()) { + m_fileSystemWatcher = new QFileSystemWatcher(this); + connect(m_fileSystemWatcher.data(), SIGNAL(fileChanged(QString)), this, SLOT(refreshLocalFileProperty(QString))); + } + + return m_fileSystemWatcher.data(); +} + +Internal::ChildrenChangeEventFilter *NodeInstanceServer::childrenChangeEventFilter() const +{ + return m_childrenChangeEventFilter.data(); +} + +void NodeInstanceServer::addFilePropertyToFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path) +{ + if (!m_fileSystemWatcherHash.contains(path)) { + m_fileSystemWatcherHash.insert(path, ObjectPropertyPair(object, propertyName)); + fileSystemWatcher()->addPath(path); + } +} + +void NodeInstanceServer::removeFilePropertyFromFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path) +{ + if (m_fileSystemWatcherHash.contains(path)) { + fileSystemWatcher()->removePath(path); + m_fileSystemWatcherHash.remove(path, ObjectPropertyPair(object, propertyName)); + } +} + +void NodeInstanceServer::refreshLocalFileProperty(const QString &path) +{ + if (m_fileSystemWatcherHash.contains(path)) { + foreach (const ObjectPropertyPair &objectPropertyPair, m_fileSystemWatcherHash) { + QObject *object = objectPropertyPair.first.data(); + QString propertyName = objectPropertyPair.second; + + if (hasInstanceForObject(object)) { + instanceForObject(object).refreshProperty(propertyName); + } + } + } +} + +void NodeInstanceServer::refreshDummyData(const QString &path) +{ + engine()->clearComponentCache(); + QFileInfo filePath(path); + if (filePath.completeBaseName().contains("_dummycontext")) { + loadDummyContextObjectFile(filePath); + } else { + loadDummyDataFile(filePath); + } + + refreshBindings(); + startRenderTimer(); +} + +void NodeInstanceServer::addChangedProperty(const InstancePropertyPair &property) +{ + if (!m_changedPropertyList.contains(property)) + m_changedPropertyList.append(property); +} + +void NodeInstanceServer::emitParentChanged(QObject *child) +{ + if (hasInstanceForObject(child)) { + addChangedProperty(InstancePropertyPair(instanceForObject(child), "parent")); + } +} + +Internal::ChildrenChangeEventFilter *NodeInstanceServer::childrenChangeEventFilter() +{ + if (m_childrenChangeEventFilter.isNull()) { + m_childrenChangeEventFilter = new Internal::ChildrenChangeEventFilter(this); + connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*))); + } + + return m_childrenChangeEventFilter.data(); +} + +void NodeInstanceServer::resetInstanceProperty(const PropertyAbstractContainer &propertyContainer) +{ + if (hasInstanceForId(propertyContainer.instanceId())) { // TODO ugly workaround + ServerNodeInstance instance = instanceForId(propertyContainer.instanceId()); + Q_ASSERT(instance.isValid()); + + const QString name = propertyContainer.name(); + + if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) { + bool statePropertyWasReseted = activeStateInstance().resetStateProperty(instance, name, instance.resetVariant(name)); + if (!statePropertyWasReseted) + instance.resetProperty(name); + } else { + instance.resetProperty(name); + } + + if (propertyContainer.isDynamic() && propertyContainer.instanceId() == 0 && engine()) + rootContext()->setContextProperty(name, QVariant()); + } +} + + +void NodeInstanceServer::setInstancePropertyBinding(const PropertyBindingContainer &bindingContainer) +{ + if (hasInstanceForId(bindingContainer.instanceId())) { + ServerNodeInstance instance = instanceForId(bindingContainer.instanceId()); + + const QString name = bindingContainer.name(); + const QString expression = bindingContainer.expression(); + + + if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) { + bool stateBindingWasUpdated = activeStateInstance().updateStateBinding(instance, name, expression); + if (!stateBindingWasUpdated) { + if (bindingContainer.isDynamic()) + instance.setPropertyDynamicBinding(name, bindingContainer.dynamicTypeName(), expression); + else + instance.setPropertyBinding(name, expression); + } + } else { + if (bindingContainer.isDynamic()) + instance.setPropertyDynamicBinding(name, bindingContainer.dynamicTypeName(), expression); + else + instance.setPropertyBinding(name, expression); + } + } +} + + +void NodeInstanceServer::removeProperties(const QList<PropertyAbstractContainer> &propertyList) +{ + foreach (const PropertyAbstractContainer &property, propertyList) + resetInstanceProperty(property); +} + +void NodeInstanceServer::setInstancePropertyVariant(const PropertyValueContainer &valueContainer) +{ + if (hasInstanceForId(valueContainer.instanceId())) { + ServerNodeInstance instance = instanceForId(valueContainer.instanceId()); + + + const QString name = valueContainer.name(); + const QVariant value = valueContainer.value(); + + + if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) { + bool stateValueWasUpdated = activeStateInstance().updateStateVariant(instance, name, value); + if (!stateValueWasUpdated) { + if (valueContainer.isDynamic()) + instance.setPropertyDynamicVariant(name, valueContainer.dynamicTypeName(), value); + else + instance.setPropertyVariant(name, value); + } + } else { //base state + if (valueContainer.isDynamic()) + instance.setPropertyDynamicVariant(name, valueContainer.dynamicTypeName(), value); + else + instance.setPropertyVariant(name, value); + } + + if (valueContainer.isDynamic() && valueContainer.instanceId() == 0 && engine()) + rootContext()->setContextProperty(name, Internal::ObjectNodeInstance::fixResourcePaths(value)); + } +} + +void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &auxiliaryContainer) +{ + //instanceId() == 0: the item is root + if (auxiliaryContainer.instanceId() == 0 && (auxiliaryContainer.name() == QLatin1String("width") || + auxiliaryContainer.name() == QLatin1String("height"))) { + + if (!auxiliaryContainer.value().isNull()) { + setInstancePropertyVariant(auxiliaryContainer); + } else { + rootNodeInstance().resetProperty(auxiliaryContainer.name()); + } + } + if (auxiliaryContainer.name().endsWith(QLatin1String("@NodeInstance"))) { + QString propertyName = auxiliaryContainer.name().leftRef(auxiliaryContainer.name().count() - 12).toString(); + if (!auxiliaryContainer.value().isNull()) { + setInstancePropertyVariant(PropertyValueContainer(auxiliaryContainer.instanceId(), + propertyName, + auxiliaryContainer.value(), + auxiliaryContainer.dynamicTypeName())); + } else { + rootNodeInstance().resetProperty(propertyName); + } + } +} + + +QUrl NodeInstanceServer::fileUrl() const +{ + return m_fileUrl; +} + +ServerNodeInstance NodeInstanceServer::activeStateInstance() const +{ + return m_activeStateInstance; +} + +ServerNodeInstance NodeInstanceServer::rootNodeInstance() const +{ + return m_rootNodeInstance; +} + +void NodeInstanceServer::setStateInstance(const ServerNodeInstance &stateInstance) +{ + m_activeStateInstance = stateInstance; +} + +void NodeInstanceServer::clearStateInstance() +{ + m_activeStateInstance = ServerNodeInstance(); +} + +void NodeInstanceServer::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == m_timer) { + collectItemChangesAndSendChangeCommands(); + } + + NodeInstanceServerInterface::timerEvent(event); +} + +NodeInstanceClientInterface *NodeInstanceServer::nodeInstanceClient() const +{ + return m_nodeInstanceClient; +} + +static QVector<InformationContainer> createInformationVector(const QList<ServerNodeInstance> &instanceList, bool initial) +{ + QVector<InformationContainer> informationVector; + + foreach (const ServerNodeInstance &instance, instanceList) { + informationVector.append(InformationContainer(instance.instanceId(), Position, instance.position())); + informationVector.append(InformationContainer(instance.instanceId(), Transform, instance.transform())); + informationVector.append(InformationContainer(instance.instanceId(), SceneTransform, instance.sceneTransform())); + informationVector.append(InformationContainer(instance.instanceId(), Size, instance.size())); + informationVector.append(InformationContainer(instance.instanceId(), BoundingRect, instance.boundingRect())); + informationVector.append(InformationContainer(instance.instanceId(), Transform, instance.transform())); + informationVector.append(InformationContainer(instance.instanceId(), HasContent, instance.hasContent())); + informationVector.append(InformationContainer(instance.instanceId(), IsMovable, instance.isMovable())); + informationVector.append(InformationContainer(instance.instanceId(), IsResizable, instance.isResizable())); + informationVector.append(InformationContainer(instance.instanceId(), IsInPositioner, instance.isInPositioner())); + informationVector.append(InformationContainer(instance.instanceId(), PenWidth, instance.penWidth())); + informationVector.append(InformationContainer(instance.instanceId(), IsAnchoredByChildren, instance.isAnchoredByChildren())); + informationVector.append(InformationContainer(instance.instanceId(), IsAnchoredBySibling, instance.isAnchoredBySibling())); + + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.fill"), instance.hasAnchor("anchors.fill"))); + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.centerIn"), instance.hasAnchor("anchors.centerIn"))); + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.right"), instance.hasAnchor("anchors.right"))); + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.top"), instance.hasAnchor("anchors.top"))); + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.left"), instance.hasAnchor("anchors.left"))); + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.bottom"), instance.hasAnchor("anchors.bottom"))); + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.horizontalCenter"), instance.hasAnchor("anchors.horizontalCenter"))); + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.verticalCenter"), instance.hasAnchor("anchors.verticalCenter"))); + informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.baseline"), instance.hasAnchor("anchors.baseline"))); + + QPair<QString, ServerNodeInstance> anchorPair = instance.anchor("anchors.fill"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.fill"), anchorPair.first, anchorPair.second.instanceId())); + + anchorPair = instance.anchor("anchors.centerIn"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.centerIn"), anchorPair.first, anchorPair.second.instanceId())); + + anchorPair = instance.anchor("anchors.right"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.right"), anchorPair.first, anchorPair.second.instanceId())); + + anchorPair = instance.anchor("anchors.top"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.top"), anchorPair.first, anchorPair.second.instanceId())); + + anchorPair = instance.anchor("anchors.left"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.left"), anchorPair.first, anchorPair.second.instanceId())); + + anchorPair = instance.anchor("anchors.bottom"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.bottom"), anchorPair.first, anchorPair.second.instanceId())); + + anchorPair = instance.anchor("anchors.horizontalCenter"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.horizontalCenter"), anchorPair.first, anchorPair.second.instanceId())); + + anchorPair = instance.anchor("anchors.verticalCenter"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.verticalCenter"), anchorPair.first, anchorPair.second.instanceId())); + + anchorPair = instance.anchor("anchors.baseline"); + informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.baseline"), anchorPair.first, anchorPair.second.instanceId())); + + QStringList propertyNames = instance.propertyNames(); + + if (initial) { + foreach (const QString &propertyName,propertyNames) + informationVector.append(InformationContainer(instance.instanceId(), InstanceTypeForProperty, propertyName, instance.instanceType(propertyName))); + } + + foreach (const QString &propertyName,instance.propertyNames()) { + bool hasChanged = false; + bool hasBinding = instance.hasBindingForProperty(propertyName, &hasChanged); + if (hasChanged) + informationVector.append(InformationContainer(instance.instanceId(), HasBindingForProperty, propertyName, hasBinding)); + } + + } + + return informationVector; +} + + +ChildrenChangedCommand NodeInstanceServer::createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const +{ + QVector<qint32> instanceVector; + + foreach (const ServerNodeInstance &instance, instanceList) + instanceVector.append(instance.instanceId()); + + return ChildrenChangedCommand(parentInstance.instanceId(), instanceVector, createInformationVector(instanceList, false)); +} + +InformationChangedCommand NodeInstanceServer::createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial) const +{ + return InformationChangedCommand(createInformationVector(instanceList, initial)); +} + +static bool supportedVariantType(int type) +{ + return type < int(QVariant::UserType) && type != QMetaType::QObjectStar; +} + +ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList<ServerNodeInstance> &instanceList) const +{ + QVector<PropertyValueContainer> valueVector; + + foreach (const ServerNodeInstance &instance, instanceList) { + foreach (const QString &propertyName, instance.propertyNames()) { + QVariant propertyValue = instance.property(propertyName); + if (supportedVariantType(propertyValue.userType())) + valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, QString())); + } + } + + return ValuesChangedCommand(valueVector); +} + +ComponentCompletedCommand NodeInstanceServer::createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList) +{ + QVector<qint32> idVector; + foreach (const ServerNodeInstance &instance, instanceList) { + if (instance.instanceId() >= 0) + idVector.append(instance.instanceId()); + } + + return ComponentCompletedCommand(idVector); +} + +ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const +{ + QVector<PropertyValueContainer> valueVector; + + foreach (const InstancePropertyPair &property, propertyList) { + const QString propertyName = property.second; + const ServerNodeInstance instance = property.first; + + if (instance.isValid()) { + QVariant propertyValue = instance.property(propertyName); + if (QMetaType::isRegistered(propertyValue.userType()) && supportedVariantType(propertyValue.type())) { + valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, QString())); + } + } + } + + return ValuesChangedCommand(valueVector); +} + +QStringList NodeInstanceServer::imports() const +{ + return m_importList; +} + +void NodeInstanceServer::addImportString(const QString &import) +{ + m_importList.append(import); +} + +QObject *NodeInstanceServer::dummyContextObject() const +{ + return m_dummyContextObject.data(); +} + +void NodeInstanceServer::notifyPropertyChange(qint32 instanceid, const QString &propertyName) +{ + if (hasInstanceForId(instanceid)) + addChangedProperty(InstancePropertyPair(instanceForId(instanceid), propertyName)); +} + +void NodeInstanceServer::insertInstanceRelationship(const ServerNodeInstance &instance) +{ + Q_ASSERT(instance.isValid()); + Q_ASSERT(!m_idInstanceHash.contains(instance.instanceId())); + Q_ASSERT(!m_objectInstanceHash.contains(instance.internalObject())); + m_objectInstanceHash.insert(instance.internalObject(), instance); + m_idInstanceHash.insert(instance.instanceId(), instance); +} + +void NodeInstanceServer::removeInstanceRelationsip(qint32 instanceId) +{ + if (hasInstanceForId(instanceId)) { + ServerNodeInstance instance = instanceForId(instanceId); + if (instance.isValid()) + instance.setId(QString()); + m_idInstanceHash.remove(instanceId); + m_objectInstanceHash.remove(instance.internalObject()); + instance.makeInvalid(); + } +} + +PixmapChangedCommand NodeInstanceServer::createPixmapChangedCommand(const QList<ServerNodeInstance> &instanceList) const +{ + QVector<ImageContainer> imageVector; + + foreach (const ServerNodeInstance &instance, instanceList) { + if (instance.isValid() && instance.hasContent()) + imageVector.append(ImageContainer(instance.instanceId(), instance.renderImage(), instance.instanceId())); + } + + return PixmapChangedCommand(imageVector); +} + +void NodeInstanceServer::loadDummyDataFile(const QFileInfo& qmlFileInfo) +{ + QQmlComponent component(engine(), qmlFileInfo.filePath()); + QObject *dummyData = component.create(); + if (component.isError()) { + QList<QQmlError> errors = component.errors(); + foreach (const QQmlError &error, errors) { + qWarning() << error; + } + } + + QVariant oldDummyDataObject = rootContext()->contextProperty(qmlFileInfo.completeBaseName()); + + if (dummyData) { + qWarning() << "Loaded dummy data:" << qmlFileInfo.filePath(); + rootContext()->setContextProperty(qmlFileInfo.completeBaseName(), dummyData); + dummyData->setParent(this); + m_dummyObjectList.append(DummyPair(qmlFileInfo.completeBaseName(), dummyData)); + } + + if (!oldDummyDataObject.isNull()) + delete oldDummyDataObject.value<QObject*>(); + + if (!dummydataFileSystemWatcher()->files().contains(qmlFileInfo.filePath())) + dummydataFileSystemWatcher()->addPath(qmlFileInfo.filePath()); + + if (rootNodeInstance().isValid() && rootNodeInstance().internalObject()) { + foreach (QQmlContext *context, allSubContextsForObject(rootNodeInstance().internalObject())) + setupDummysForContext(context); + } +} + +void NodeInstanceServer::loadDummyContextObjectFile(const QFileInfo& qmlFileInfo) +{ + delete m_dummyContextObject.data(); + + QQmlComponent component(engine(), qmlFileInfo.filePath()); + m_dummyContextObject = component.create(); + + if (component.isError()) { + QList<QQmlError> errors = component.errors(); + foreach (const QQmlError &error, errors) { + qWarning() << error; + } + } + + if (m_dummyContextObject) { + qWarning() << "Loaded dummy context object:" << qmlFileInfo.filePath(); + m_dummyContextObject->setParent(this); + } + + if (!dummydataFileSystemWatcher()->files().contains(qmlFileInfo.filePath())) + dummydataFileSystemWatcher()->addPath(qmlFileInfo.filePath()); + + refreshBindings(); +} + +void NodeInstanceServer::loadDummyDataFiles(const QString& directory) +{ + QDir dir(directory, "*.qml"); + QList<QFileInfo> filePathList = dir.entryInfoList(); + foreach (const QFileInfo &qmlFileInfo, filePathList) { + loadDummyDataFile(qmlFileInfo); + } +} + +void NodeInstanceServer::loadDummyDataContext(const QString& directory) +{ + QDir dir(directory+"/context", "*.qml"); + QList<QFileInfo> filePathList = dir.entryInfoList(); + QString baseName = QFileInfo(fileUrl().toLocalFile()).completeBaseName(); + foreach (const QFileInfo &qmlFileInfo, filePathList) { + if (qmlFileInfo.completeBaseName() == baseName) + loadDummyContextObjectFile(qmlFileInfo); + } +} + +void NodeInstanceServer::sendDebugOutput(DebugOutputCommand::Type type, const QString &message) +{ + DebugOutputCommand command(message, type); + nodeInstanceClient()->debugOutput(command); +} + +QStringList NodeInstanceServer::dummyDataDirectories(const QString& directoryPath) +{ + QStringList dummyDataDirectoryList; + QDir directory(directoryPath); + while (true) { + if (directory.isRoot() || !directory.exists()) + return dummyDataDirectoryList; + + if (directory.exists("dummydata")) + dummyDataDirectoryList.prepend(directory.absoluteFilePath("dummydata")); + + directory.cdUp(); + } +} + +} + + + diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h new file mode 100644 index 0000000000..031fa6b401 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef NODEINSTANCESERVER_H +#define NODEINSTANCESERVER_H + +#include <QUrl> +#include <QVector> +#include <QSet> +#include <QStringList> +#include <QPointer> + +#include <nodeinstanceserverinterface.h> +#include "servernodeinstance.h" +#include "debugoutputcommand.h" + +QT_BEGIN_NAMESPACE +class QFileSystemWatcher; +class QQmlView; +class QQuickView; +class QQmlEngine; +class QFileInfo; +class QQmlComponent; +QT_END_NAMESPACE + +namespace QmlDesigner { + +class NodeInstanceClientInterface; +class ValuesChangedCommand; +class PixmapChangedCommand; +class InformationChangedCommand; +class ChildrenChangedCommand; +class ReparentContainer; +class ComponentCompletedCommand; +class AddImportContainer; + +namespace Internal { + class ChildrenChangeEventFilter; +} + +class NodeInstanceServer : public NodeInstanceServerInterface +{ + Q_OBJECT +public: + typedef QPair<QPointer<QObject>, QString> ObjectPropertyPair; + typedef QPair<qint32, QString> IdPropertyPair; + typedef QPair<ServerNodeInstance, QString> InstancePropertyPair; + typedef QPair<QString, QPointer<QObject> > DummyPair; + + explicit NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient); + ~NodeInstanceServer(); + + void createInstances(const CreateInstancesCommand &command); + void changeFileUrl(const ChangeFileUrlCommand &command); + void changePropertyValues(const ChangeValuesCommand &command); + void changePropertyBindings(const ChangeBindingsCommand &command); + void changeAuxiliaryValues(const ChangeAuxiliaryCommand &command); + void changeIds(const ChangeIdsCommand &command); + void createScene(const CreateSceneCommand &command); + void clearScene(const ClearSceneCommand &command); + void removeInstances(const RemoveInstancesCommand &command); + void removeProperties(const RemovePropertiesCommand &command); + void reparentInstances(const ReparentInstancesCommand &command); + void changeState(const ChangeStateCommand &command); + void completeComponent(const CompleteComponentCommand &command); + void changeNodeSource(const ChangeNodeSourceCommand &command); + void token(const TokenCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); + + ServerNodeInstance instanceForId(qint32 id) const; + bool hasInstanceForId(qint32 id) const; + + ServerNodeInstance instanceForObject(QObject *object) const; + bool hasInstanceForObject(QObject *object) const; + + virtual QQmlEngine *engine() const = 0; + QQmlContext *context() const; + + void removeAllInstanceRelationships(); + + QFileSystemWatcher *fileSystemWatcher(); + QFileSystemWatcher *dummydataFileSystemWatcher(); + Internal::ChildrenChangeEventFilter *childrenChangeEventFilter() const; + void addFilePropertyToFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path); + void removeFilePropertyFromFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path); + + QUrl fileUrl() const; + + ServerNodeInstance activeStateInstance() const; + void setStateInstance(const ServerNodeInstance &stateInstance); + void clearStateInstance(); + + ServerNodeInstance rootNodeInstance() const; + + void notifyPropertyChange(qint32 instanceid, const QString &propertyName); + + QStringList imports() const; + QObject *dummyContextObject() const; + + virtual QQmlView *declarativeView() const = 0; + virtual QQuickView *quickView() const = 0; + + void sendDebugOutput(DebugOutputCommand::Type type, const QString &message); + +public slots: + void refreshLocalFileProperty(const QString &path); + void refreshDummyData(const QString &path); + void emitParentChanged(QObject *child); + +protected: + QList<ServerNodeInstance> createInstances(const QVector<InstanceContainer> &container); + void reparentInstances(const QVector<ReparentContainer> &containerVector); + void addImportString(const QString &import); + + Internal::ChildrenChangeEventFilter *childrenChangeEventFilter(); + void resetInstanceProperty(const PropertyAbstractContainer &propertyContainer); + void setInstancePropertyBinding(const PropertyBindingContainer &bindingContainer); + void setInstancePropertyVariant(const PropertyValueContainer &valueContainer); + void setInstanceAuxiliaryData(const PropertyValueContainer &auxiliaryContainer); + void removeProperties(const QList<PropertyAbstractContainer> &propertyList); + + void insertInstanceRelationship(const ServerNodeInstance &instance); + void removeInstanceRelationsip(qint32 instanceId); + + NodeInstanceClientInterface *nodeInstanceClient() const; + + void timerEvent(QTimerEvent *); + + virtual void collectItemChangesAndSendChangeCommands() = 0; + + ValuesChangedCommand createValuesChangedCommand(const QList<ServerNodeInstance> &instanceList) const; + ValuesChangedCommand createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const; + PixmapChangedCommand createPixmapChangedCommand(const QList<ServerNodeInstance> &instanceList) const; + InformationChangedCommand createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial = false) const; + ChildrenChangedCommand createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const; + ComponentCompletedCommand createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList); + + void addChangedProperty(const InstancePropertyPair &property); + + virtual void startRenderTimer(); + void slowDownRenderTimer(); + void stopRenderTimer(); + void setRenderTimerInterval(int timerInterval); + int renderTimerInterval() const; + void setSlowRenderTimerInterval(int timerInterval); + + virtual void initializeView(const QVector<AddImportContainer> &importVector) = 0; + virtual QList<ServerNodeInstance> setupScene(const CreateSceneCommand &command) = 0; + void loadDummyDataFiles(const QString& directory); + void loadDummyDataContext(const QString& directory); + void loadDummyDataFile(const QFileInfo& fileInfo); + void loadDummyContextObjectFile(const QFileInfo& fileInfo); + static QStringList dummyDataDirectories(const QString& directoryPath); + + void setTimerId(int timerId); + int timerId() const; + + QQmlContext *rootContext() const; + + + const QVector<InstancePropertyPair> changedPropertyList() const; + void clearChangedPropertyList(); + + virtual void refreshBindings() = 0; + + void setupDummysForContext(QQmlContext *context); + + void setupFileUrl(const QUrl &fileUrl); + void setupImports(const QVector<AddImportContainer> &container); + void setupDummyData(const QUrl &fileUrl); + void setupDefaultDummyData(); + QList<ServerNodeInstance> setupInstances(const CreateSceneCommand &command); + + QList<QQmlContext*> allSubContextsForObject(QObject *object); + static QList<QObject*> allSubObjectsForObject(QObject *object); + + virtual void resizeCanvasSizeToRootItemSize() = 0; + +private: + ServerNodeInstance m_rootNodeInstance; + ServerNodeInstance m_activeStateInstance; + QHash<qint32, ServerNodeInstance> m_idInstanceHash; + QHash<QObject*, ServerNodeInstance> m_objectInstanceHash; + QMultiHash<QString, ObjectPropertyPair> m_fileSystemWatcherHash; + QList<QPair<QString, QPointer<QObject> > > m_dummyObjectList; + QPointer<QFileSystemWatcher> m_fileSystemWatcher; + QPointer<QFileSystemWatcher> m_dummdataFileSystemWatcher; + QPointer<Internal::ChildrenChangeEventFilter> m_childrenChangeEventFilter; + QUrl m_fileUrl; + NodeInstanceClientInterface *m_nodeInstanceClient; + int m_timer; + int m_renderTimerInterval; + bool m_slowRenderTimer; + int m_slowRenderTimerInterval; + QVector<InstancePropertyPair> m_changedPropertyList; + QStringList m_importList; + QPointer<QObject> m_dummyContextObject; + QPointer<QQmlComponent> m_importComponent; + QPointer<QObject> m_importComponentObject; +}; + +} + +#endif // NODEINSTANCESERVER_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.cpp new file mode 100644 index 0000000000..f8e737b307 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "nodeinstancesignalspy.h" +#include "objectnodeinstance.h" + +#include <QMetaProperty> +#include <QMetaObject> +#include <QDebug> +#include <QSharedPointer> +#include <private/qqmlmetatype_p.h> + +namespace QmlDesigner { +namespace Internal { + +NodeInstanceSignalSpy::NodeInstanceSignalSpy() : + QObject() +{ + blockSignals(true); +} + +void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Pointer &nodeInstance) +{ + methodeOffset = QObject::staticMetaObject.methodCount() + 1; + registerObject(nodeInstance->object()); + m_objectNodeInstance = nodeInstance; + +} + +void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const QString &prefix) +{ + if (m_registeredObjectList.contains(spiedObject)) // prevent cycles + return; + + m_registeredObjectList.append(spiedObject); + for (int index = QObject::staticMetaObject.propertyOffset(); + index < spiedObject->metaObject()->propertyCount(); + index++) { + QMetaProperty metaProperty = spiedObject->metaObject()->property(index); + + // handle dot properties and connect the signals to the object + if (metaProperty.isReadable() + && !metaProperty.isWritable() + && QQmlMetaType::isQObject(metaProperty.userType())) { + QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject)); + if (propertyObject) + registerObject(propertyObject, prefix + metaProperty.name() + QLatin1Char('.')); + } else if (metaProperty.hasNotifySignal()) { + QMetaMethod metaMethod = metaProperty.notifySignal(); + bool isConnecting = QMetaObject::connect(spiedObject, metaMethod.methodIndex(), this, methodeOffset, Qt::DirectConnection); + Q_ASSERT(isConnecting); + Q_UNUSED(isConnecting); + m_indexPropertyHash.insert(methodeOffset, prefix + metaProperty.name()); + methodeOffset++; + } + + // search recursive in objects + if (metaProperty.isReadable() + && metaProperty.isWritable() + && QQmlMetaType::isQObject(metaProperty.userType())) { + QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject)); + if (propertyObject) + registerObject(propertyObject, prefix + metaProperty.name() + QLatin1Char('/')); + } + + // search recursive in objects list + if (metaProperty.isReadable() + && QQmlMetaType::isList(metaProperty.userType())) { + QQmlListReference list(spiedObject, metaProperty.name()); + + if (list.canCount() && list.canAt()) { + + for (int i = 0; i < list.count(); i++) { + QObject *propertyObject = list.at(i); + if (propertyObject) + registerObject(propertyObject, prefix + metaProperty.name() + QLatin1Char('/')); + } + } + } + } +} + +int NodeInstanceSignalSpy::qt_metacall(QMetaObject::Call call, int methodId, void **a) +{ + if (call == QMetaObject::InvokeMetaMethod && methodId > QObject::staticMetaObject.methodCount()) { + ObjectNodeInstance::Pointer nodeInstance = m_objectNodeInstance.toStrongRef(); + + if (nodeInstance && nodeInstance->nodeInstanceServer() && nodeInstance->isValid()) { + nodeInstance->nodeInstanceServer()->notifyPropertyChange(nodeInstance->instanceId(), m_indexPropertyHash.value(methodId)); + } + + } + + return QObject::qt_metacall(call, methodId, a); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstancesignalspy.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.h index ae0b94c108..ae0b94c108 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstancesignalspy.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.h diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp new file mode 100644 index 0000000000..d74a517fbc --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -0,0 +1,1180 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "objectnodeinstance.h" + + + +#include <QEvent> +#include <QQmlContext> +#include <QQmlError> +#include <QQmlEngine> +#include <QQmlProperty> +#include <QQmlComponent> +#include <QSharedPointer> +#include <QFileInfo> +#include <QFileSystemWatcher> +#include <QPixmapCache> +#include <QQuickItem> + +#include <QTextDocument> +#include <QLibraryInfo> + +#include <private/qqmlbinding_p.h> +#include <private/qqmlmetatype_p.h> +#include <private/qqmlvaluetype_p.h> +#include <private/qquicktransition_p.h> +#include <private/qquickanimation_p.h> +#include <private/qquicktimer_p.h> +#include <private/qqmlengine_p.h> + +namespace QmlDesigner { +namespace Internal { + +ObjectNodeInstance::ObjectNodeInstance(QObject *object) + : m_instanceId(-1), + m_deleteHeldInstance(true), + m_object(object), + m_metaObject(0), + m_isInPositioner(false) +{ + +} + +ObjectNodeInstance::~ObjectNodeInstance() +{ + destroy(); +} + +void ObjectNodeInstance::destroy() +{ + if (deleteHeldInstance()) { + // Remove from old property + if (object()) { + setId(QString()); + if (m_instanceId >= 0) { + reparent(parentInstance(), m_parentProperty, ObjectNodeInstance::Pointer(), QString()); + } + } + + if (object()) { + QObject *obj = object(); + m_object.clear(); + delete obj; + } + } + + m_metaObject = 0; + m_instanceId = -1; +} + +void ObjectNodeInstance::setInstanceId(qint32 id) +{ + m_instanceId = id; +} + +qint32 ObjectNodeInstance::instanceId() const +{ + return m_instanceId; +} + +NodeInstanceServer *ObjectNodeInstance::nodeInstanceServer() const +{ + return m_nodeInstanceServer.data(); +} + +void ObjectNodeInstance::setNodeInstanceServer(NodeInstanceServer *server) +{ + Q_ASSERT(!m_nodeInstanceServer.data()); + + m_nodeInstanceServer = server; +} + +static bool hasPropertiesWitoutNotifications(const QMetaObject *metaObject) +{ + for (int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) { + if (!metaObject->property(propertyIndex).hasNotifySignal()) + return true; + } + + return false; +} + +void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance) +{ + const QMetaObject *metaObject = objectNodeInstance->object()->metaObject(); + m_metaObject = NodeInstanceMetaObject::createNodeInstanceMetaObject(objectNodeInstance, nodeInstanceServer()->engine()); + for (int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) { + if (QQmlMetaType::isQObject(metaObject->property(propertyIndex).userType())) { + QObject *propertyObject = QQmlMetaType::toQObject(metaObject->property(propertyIndex).read(objectNodeInstance->object())); + if (propertyObject && hasPropertiesWitoutNotifications(propertyObject->metaObject())) { + NodeInstanceMetaObject::createNodeInstanceMetaObject(objectNodeInstance, + propertyObject, + metaObject->property(propertyIndex).name(), + nodeInstanceServer()->engine()); + } + } + } + + m_signalSpy.setObjectNodeInstance(objectNodeInstance); +} + +void ObjectNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance) +{ + initializePropertyWatcher(objectNodeInstance); +} + +void ObjectNodeInstance::setId(const QString &id) +{ + if (!m_id.isEmpty() && context()) { + context()->engine()->rootContext()->setContextProperty(m_id, 0); + } + + if (!id.isEmpty() && context()) { + context()->engine()->rootContext()->setContextProperty(id, object()); // will also force refresh of all bindings + } + + m_id = id; +} + +QString ObjectNodeInstance::id() const +{ + return m_id; +} + +bool ObjectNodeInstance::isTransition() const +{ + return false; +} + +bool ObjectNodeInstance::isPositioner() const +{ + return false; +} + +bool ObjectNodeInstance::isQuickItem() const +{ + return false; +} + +bool ObjectNodeInstance::equalGraphicsItem(QGraphicsItem * /*item*/) const +{ + return false; +} + +QTransform ObjectNodeInstance::transform() const +{ + return QTransform(); +} + +QTransform ObjectNodeInstance::customTransform() const +{ + return QTransform(); +} + +QTransform ObjectNodeInstance::sceneTransform() const +{ + return QTransform(); +} + +double ObjectNodeInstance::rotation() const +{ + return 0.0; +} + +double ObjectNodeInstance::scale() const +{ + return 1.0; +} + +QList<QGraphicsTransform *> ObjectNodeInstance::transformations() const +{ + QList<QGraphicsTransform *> transformationsList; + + return transformationsList; +} + +QPointF ObjectNodeInstance::transformOriginPoint() const +{ + return QPoint(); +} + +double ObjectNodeInstance::zValue() const +{ + return 0.0; +} + +double ObjectNodeInstance::opacity() const +{ + return 1.0; +} + +bool ObjectNodeInstance::hasAnchor(const QString &/*name*/) const +{ + return false; +} + +bool ObjectNodeInstance::isAnchoredBySibling() const +{ + return false; +} + +bool ObjectNodeInstance::isAnchoredByChildren() const +{ + return false; +} + +QPair<QString, ServerNodeInstance> ObjectNodeInstance::anchor(const QString &/*name*/) const +{ + return qMakePair(QString(), ServerNodeInstance()); +} + + +static bool isList(const QQmlProperty &property) +{ + return property.propertyTypeCategory() == QQmlProperty::List; +} + +static bool isObject(const QQmlProperty &property) +{ + return (property.propertyTypeCategory() == QQmlProperty::Object) || + //QVariant can also store QObjects. Lets trust our model. + (QLatin1String(property.propertyTypeName()) == QLatin1String("QVariant")); +} + +static QVariant objectToVariant(QObject *object) +{ + return QVariant::fromValue(object); +} + +static bool hasFullImplementedListInterface(const QQmlListReference &list) +{ + return list.isValid() && list.canCount() && list.canAt() && list.canAppend() && list.canClear(); +} + +static void removeObjectFromList(const QQmlProperty &property, QObject *objectToBeRemoved, QQmlEngine * engine) +{ + QQmlListReference listReference(property.object(), property.name().toLatin1(), engine); + + if (!hasFullImplementedListInterface(listReference)) { + qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!"; + return; + } + + int count = listReference.count(); + + QObjectList objectList; + + for (int i = 0; i < count; i ++) { + QObject *listItem = listReference.at(i); + if (listItem && listItem != objectToBeRemoved) + objectList.append(listItem); + } + + listReference.clear(); + + foreach (QObject *object, objectList) + listReference.append(object); +} + +void ObjectNodeInstance::removeFromOldProperty(QObject *object, QObject *oldParent, const QString &oldParentProperty) +{ + QQmlProperty property(oldParent, oldParentProperty, context()); + + if (!property.isValid()) + return; + + if (isList(property)) { + removeObjectFromList(property, object, nodeInstanceServer()->engine()); + } else if (isObject(property)) { + if (nodeInstanceServer()->hasInstanceForObject(oldParent)) { + nodeInstanceServer()->instanceForObject(oldParent).resetProperty(oldParentProperty); + } + } + + if (object && object->parent()) + object->setParent(0); +} + +void ObjectNodeInstance::addToNewProperty(QObject *object, QObject *newParent, const QString &newParentProperty) +{ + QQmlProperty property(newParent, newParentProperty, context()); + + if (isList(property)) { + QQmlListReference list = qvariant_cast<QQmlListReference>(property.read()); + + if (!hasFullImplementedListInterface(list)) { + qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!"; + return; + } + + list.append(object); + } else if (isObject(property)) { + property.write(objectToVariant(object)); + } + + QQuickItem *quickItem = qobject_cast<QQuickItem*>(object); + + if (object && !(quickItem && quickItem->parentItem())) + object->setParent(newParent); + + Q_ASSERT(objectToVariant(object).isValid()); +} + +void ObjectNodeInstance::reparent(const ObjectNodeInstance::Pointer &oldParentInstance, const QString &oldParentProperty, const ObjectNodeInstance::Pointer &newParentInstance, const QString &newParentProperty) +{ + if (oldParentInstance) { + removeFromOldProperty(object(), oldParentInstance->object(), oldParentProperty); + m_parentProperty.clear(); + } + + if (newParentInstance) { + m_parentProperty = newParentProperty; + addToNewProperty(object(), newParentInstance->object(), newParentProperty); + } +} +QVariant ObjectNodeInstance::convertSpecialCharacter(const QVariant& value) const +{ + QVariant specialCharacterConvertedValue = value; + if (value.type() == QVariant::String) { + QString string = value.toString(); + string.replace(QLatin1String("\\n"), QLatin1String("\n")); + string.replace(QLatin1String("\\t"), QLatin1String("\t")); + specialCharacterConvertedValue = string; + } + + return specialCharacterConvertedValue; +} + + +QVariant ObjectNodeInstance::fixResourcePaths(const QVariant &value) +{ + if (value.type() == QVariant::Url) + { + const QUrl url = value.toUrl(); + if (url.scheme() == QLatin1String("qrc")) { + const QString path = QLatin1String("qrc:") + url.path(); + QString qrcSearchPath = qgetenv("QMLDESIGNER_RC_PATHS"); + if (!qrcSearchPath.isEmpty()) { + const QStringList searchPaths = qrcSearchPath.split(QLatin1Char(';')); + foreach (const QString &qrcPath, searchPaths) { + const QStringList qrcDefintion = qrcPath.split(QLatin1Char('=')); + if (qrcDefintion.count() == 2) { + QString fixedPath = path; + fixedPath.replace(QLatin1String("qrc:") + qrcDefintion.first(), qrcDefintion.last() + QLatin1Char('/')); + if (QFileInfo(fixedPath).exists()) { + fixedPath.replace(QLatin1String("//"), QLatin1String("/")); + fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/')); + return QUrl(fixedPath); + } + } + } + } + } + } + if (value.type() == QVariant::String) { + const QString str = value.toString(); + if (str.contains(QLatin1String("qrc:"))) { + QString qrcSearchPath = qgetenv("QMLDESIGNER_RC_PATHS"); + if (!qrcSearchPath.isEmpty()) { + const QStringList searchPaths = qrcSearchPath.split(QLatin1Char(';')); + foreach (const QString &qrcPath, searchPaths) { + const QStringList qrcDefintion = qrcPath.split(QLatin1Char('=')); + if (qrcDefintion.count() == 2) { + QString fixedPath = str; + fixedPath.replace(QLatin1String("qrc:") + qrcDefintion.first(), qrcDefintion.last() + QLatin1Char('/')); + if (QFileInfo(fixedPath).exists()) { + fixedPath.replace(QLatin1String("//"), QLatin1String("/")); + fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/')); + return fixedPath; + } + } + } + } + } + } + return value; +} + +void ObjectNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) +{ + QQmlProperty property(object(), name, context()); + + if (!property.isValid()) + return; + + QVariant fixedValue = fixResourcePaths(value); + + QVariant oldValue = property.read(); + if (oldValue.type() == QVariant::Url) { + QUrl url = oldValue.toUrl(); + QString path = url.toLocalFile(); + if (QFileInfo(path).exists() && nodeInstanceServer() && !path.isEmpty()) + nodeInstanceServer()->removeFilePropertyFromFileSystemWatcher(object(), name, path); + } + + if (hasValidResetBinding(name)) { + QQmlPropertyPrivate::setBinding(property, 0, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); + } + + bool isWritten = property.write(convertSpecialCharacter(fixedValue)); + + if (!isWritten) + qDebug() << "ObjectNodeInstance.setPropertyVariant: Cannot be written: " << object() << name << fixedValue; + + QVariant newValue = property.read(); + if (newValue.type() == QVariant::Url) { + QUrl url = newValue.toUrl(); + QString path = url.toLocalFile(); + if (QFileInfo(path).exists() && nodeInstanceServer() && !path.isEmpty()) + nodeInstanceServer()->addFilePropertyToFileSystemWatcher(object(), name, path); + } +} + +void ObjectNodeInstance::setPropertyBinding(const QString &name, const QString &expression) +{ + QQmlProperty property(object(), name, context()); + + if (!property.isValid()) + return; + + if (property.isProperty()) { + QQmlBinding *binding = new QQmlBinding(expression, object(), context()); + binding->setTarget(property); + binding->setNotifyOnValueChanged(true); + QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::setBinding(property, binding); + if (oldBinding && !hasValidResetBinding(name)) + oldBinding->destroy(); + binding->update(); + if (binding->hasError()) { + //qDebug() <<" ObjectNodeInstance.setPropertyBinding has Error: " << object() << name << expression << binding->error(engine()).toString(); + if (property.property().userType() == QVariant::String) + property.write(QVariant(QString("#%1#").arg(expression))); + } + + } else { + qWarning() << "ObjectNodeInstance.setPropertyBinding: Cannot set binding for property" << name << ": property is unknown for type"; + } +} + +void ObjectNodeInstance::deleteObjectsInList(const QQmlProperty &property) +{ + QObjectList objectList; + QQmlListReference list = qvariant_cast<QQmlListReference>(property.read()); + + if (!hasFullImplementedListInterface(list)) { + qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!"; + return; + } + + for (int i = 0; i < list.count(); i++) { + objectList += list.at(i); + } + + list.clear(); +} + +void ObjectNodeInstance::resetProperty(const QString &name) +{ + doResetProperty(name); + + if (name == "font.pixelSize") + doResetProperty("font.pointSize"); + + if (name == "font.pointSize") + doResetProperty("font.pixelSize"); +} + +void ObjectNodeInstance::refreshProperty(const QString &name) +{ + QQmlProperty property(object(), name, context()); + + if (!property.isValid()) + return; + + QVariant oldValue(property.read()); + + if (property.isResettable()) + property.reset(); + else + property.write(resetValue(name)); + + if (oldValue.type() == QVariant::Url) { + QByteArray key = oldValue.toUrl().toEncoded(QUrl::UrlFormattingOption(0x100)); + QString pixmapKey = QString::fromLatin1(key.constData(), key.count()); + QPixmapCache::remove(pixmapKey); + } + + property.write(oldValue); +} + +bool ObjectNodeInstance::hasBindingForProperty(const QString &name, bool *hasChanged) const +{ + QQmlProperty property(object(), name, context()); + + bool hasBinding = QQmlPropertyPrivate::binding(property); + + if (hasChanged) { + *hasChanged = hasBinding != m_hasBindingHash.value(name, false); + if (*hasChanged) + m_hasBindingHash.insert(name, hasBinding); + } + + return QQmlPropertyPrivate::binding(property); +} + +void ObjectNodeInstance::doResetProperty(const QString &propertyName) +{ + m_modelAbstractPropertyHash.remove(propertyName); + + QQmlProperty property(object(), propertyName, context()); + + if (!property.isValid()) + return; + + QVariant oldValue = property.read(); + if (oldValue.type() == QVariant::Url) { + QUrl url = oldValue.toUrl(); + QString path = url.toLocalFile(); + if (QFileInfo(path).exists() && nodeInstanceServer()) + nodeInstanceServer()->removeFilePropertyFromFileSystemWatcher(object(), propertyName, path); + } + + + QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(property); + if (binding && !(hasValidResetBinding(propertyName) && resetBinding(propertyName) == binding)) { + binding->setEnabled(false, 0); + binding->destroy(); + } + + + if (hasValidResetBinding(propertyName)) { + QQmlAbstractBinding *binding = resetBinding(propertyName); + QQmlPropertyPrivate::setBinding(property, binding, QQmlPropertyPrivate::DontRemoveBinding); + binding->update(); + } else if (property.isResettable()) { + property.reset(); + } else if (property.propertyTypeCategory() == QQmlProperty::List) { + QQmlListReference list = qvariant_cast<QQmlListReference>(property.read()); + + if (!hasFullImplementedListInterface(list)) { + qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!"; + return; + } + + list.clear(); + } else if (property.isWritable()) { + if (property.read() == resetValue(propertyName)) + return; + + property.write(resetValue(propertyName)); + } +} + +QVariant ObjectNodeInstance::property(const QString &name) const +{ + if (m_modelAbstractPropertyHash.contains(name)) + return QVariant::fromValue(m_modelAbstractPropertyHash.value(name)); + + // TODO: handle model nodes + + QQmlProperty property(object(), name, context()); + if (property.property().isEnumType()) { + QVariant value = property.read(); + return property.property().enumerator().valueToKey(value.toInt()); + } + + if (property.propertyType() == QVariant::Url) { + QUrl url = property.read().toUrl(); + if (url.isEmpty()) + return QVariant(); + + if (url.scheme() == "file") { + int basePathLength = nodeInstanceServer()->fileUrl().toLocalFile().lastIndexOf('/'); + return QUrl(url.toLocalFile().mid(basePathLength + 1)); + } + } + + return property.read(); +} + +QStringList allPropertyNames(QObject *object, const QString &baseName = QString(), QObjectList *inspectedObjects = new QObjectList) +{ + QStringList propertyNameList; + + + if (inspectedObjects== 0 || inspectedObjects->contains(object)) + return propertyNameList; + + inspectedObjects->append(object); + + + const QMetaObject *metaObject = object->metaObject(); + for (int index = 0; index < metaObject->propertyCount(); ++index) { + QMetaProperty metaProperty = metaObject->property(index); + QQmlProperty declarativeProperty(object, QLatin1String(metaProperty.name())); + if (declarativeProperty.isValid() && declarativeProperty.propertyTypeCategory() == QQmlProperty::Object) { + if (declarativeProperty.name() != "parent") { + QObject *childObject = QQmlMetaType::toQObject(declarativeProperty.read()); + if (childObject) + propertyNameList.append(allPropertyNames(childObject, baseName + QString::fromUtf8(metaProperty.name()) + '.', inspectedObjects)); + } + } else if (QQmlValueTypeFactory::valueType(metaProperty.userType())) { + QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType()); + valueType->setValue(metaProperty.read(object)); + propertyNameList.append(allPropertyNames(valueType, baseName + QString::fromUtf8(metaProperty.name()) + '.', inspectedObjects)); + } else { + propertyNameList.append(baseName + QString::fromUtf8(metaProperty.name())); + } + } + + return propertyNameList; +} + +QStringList ObjectNodeInstance::propertyNames() const +{ + if (isValid()) + return allPropertyNames(object()); + return QStringList(); +} + +QString ObjectNodeInstance::instanceType(const QString &name) const +{ + QQmlProperty property(object(), name, context()); + if (!property.isValid()) + return QLatin1String("undefined"); + return property.propertyTypeName(); +} + +QList<ServerNodeInstance> ObjectNodeInstance::childItems() const +{ + return QList<ServerNodeInstance>(); +} + +QList<ServerNodeInstance> ObjectNodeInstance::stateInstances() const +{ + return QList<ServerNodeInstance>(); +} + +void ObjectNodeInstance::setNodeSource(const QString & /*source*/) +{ +} + +void ObjectNodeInstance::setDeleteHeldInstance(bool deleteInstance) +{ + m_deleteHeldInstance = deleteInstance; +} + +bool ObjectNodeInstance::deleteHeldInstance() const +{ + return m_deleteHeldInstance; +} + +ObjectNodeInstance::Pointer ObjectNodeInstance::create(QObject *object) +{ + Pointer instance(new ObjectNodeInstance(object)); + + instance->populateResetHashes(); + + return instance; +} + +static void stopAnimation(QObject *object) +{ + if (object == 0) + return; + + QQuickTransition *transition = qobject_cast<QQuickTransition*>(object); + QQuickAbstractAnimation *animation = qobject_cast<QQuickAbstractAnimation*>(object); + QQuickTimer *timer = qobject_cast<QQuickTimer*>(object); + if (transition) { + transition->setFromState(""); + transition->setToState(""); + } else if (animation) { +// QQuickScriptAction *scriptAimation = qobject_cast<QQuickScriptAction*>(animation); +// if (scriptAimation) FIXME +// scriptAimation->setScript(QQmlScriptString()); + animation->setLoops(1); + animation->complete(); + animation->setDisableUserControl(); + } else if (timer) { + timer->blockSignals(true); + } +} + +void allSubObject(QObject *object, QObjectList &objectList) +{ + // don't add null pointer and stop if the object is already in the list + if (!object || objectList.contains(object)) + return; + + objectList.append(object); + + for (int index = QObject::staticMetaObject.propertyOffset(); + index < object->metaObject()->propertyCount(); + index++) { + QMetaProperty metaProperty = object->metaObject()->property(index); + + // search recursive in property objects + if (metaProperty.isReadable() + && metaProperty.isWritable() + && QQmlMetaType::isQObject(metaProperty.userType())) { + if (metaProperty.name() != QLatin1String("parent")) { + QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(object)); + allSubObject(propertyObject, objectList); + } + + } + + // search recursive in property object lists + if (metaProperty.isReadable() + && QQmlMetaType::isList(metaProperty.userType())) { + QQmlListReference list(object, metaProperty.name()); + if (list.canCount() && list.canAt()) { + for (int i = 0; i < list.count(); i++) { + QObject *propertyObject = list.at(i); + allSubObject(propertyObject, objectList); + + } + } + } + } + + // search recursive in object children list + foreach (QObject *childObject, object->children()) { + allSubObject(childObject, objectList); + } + + // search recursive in quick item childItems list + QQuickItem *quickItem = qobject_cast<QQuickItem*>(object); + if (quickItem) { + foreach (QQuickItem *childItem, quickItem->childItems()) { + allSubObject(childItem, objectList); + } + } +} + +static void disableTiledBackingStore(QObject *object) +{ + Q_UNUSED(object); +} + +QStringList propertyNameForWritableProperties(QObject *object, const QString &baseName = QString(), QObjectList *inspectedObjects = new QObjectList()) +{ + QStringList propertyNameList; + + if (inspectedObjects == 0 || inspectedObjects->contains(object)) + return propertyNameList; + + inspectedObjects->append(object); + + const QMetaObject *metaObject = object->metaObject(); + for (int index = 0; index < metaObject->propertyCount(); ++index) { + QMetaProperty metaProperty = metaObject->property(index); + QQmlProperty declarativeProperty(object, QLatin1String(metaProperty.name())); + if (declarativeProperty.isValid() && !declarativeProperty.isWritable() && declarativeProperty.propertyTypeCategory() == QQmlProperty::Object) { + if (declarativeProperty.name() != "parent") { + QObject *childObject = QQmlMetaType::toQObject(declarativeProperty.read()); + if (childObject) + propertyNameList.append(propertyNameForWritableProperties(childObject, baseName + QString::fromUtf8(metaProperty.name()) + '.', inspectedObjects)); + } + } else if (QQmlValueTypeFactory::valueType(metaProperty.userType())) { + QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType()); + valueType->setValue(metaProperty.read(object)); + propertyNameList.append(propertyNameForWritableProperties(valueType, baseName + QString::fromUtf8(metaProperty.name()) + '.', inspectedObjects)); + } + + if (metaProperty.isReadable() && metaProperty.isWritable()) { + propertyNameList.append(baseName + QString::fromUtf8(metaProperty.name())); + } + } + + return propertyNameList; +} + +static void fixResourcePathsForObject(QObject *object) +{ + if (qgetenv("QMLDESIGNER_RC_PATHS").isEmpty()) + return; + + QStringList propertyNameList = propertyNameForWritableProperties(object); + + foreach (const QString &propertyName, propertyNameList) { + QQmlProperty property(object, propertyName, QQmlEngine::contextForObject(object)); + + const QVariant value = property.read(); + const QVariant fixedValue = ObjectNodeInstance::fixResourcePaths(value); + if (value != fixedValue) { + property.write(fixedValue); + } + } +} + +void tweakObjects(QObject *object) +{ + QObjectList objectList; + allSubObject(object, objectList); + foreach (QObject* childObject, objectList) { + disableTiledBackingStore(childObject); + stopAnimation(childObject); + fixResourcePathsForObject(childObject); + } +} + +QObject *ObjectNodeInstance::createComponentWrap(const QString &nodeSource, const QStringList &imports, QQmlContext *context) +{ + QQmlComponent *component = new QQmlComponent(context->engine()); + + QByteArray importArray; + + foreach (const QString &import, imports) { + importArray.append(import.toUtf8()); + } + + QByteArray data(nodeSource.toUtf8()); + + data.prepend(importArray); + + component->setData(data, context->baseUrl().resolved(QUrl("createComponent.qml"))); + + QObject *object = component; + tweakObjects(object); + + if (object && context) + QQmlEngine::setContextForObject(object, context); + + QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); + + return object; +} + + +//The component might also be shipped with Creator. +//To avoid trouble with import "." we use the component shipped with Creator. +static inline QString fixComponentPathForIncompatibleQt(const QString &componentPath) +{ + QString result = componentPath; + const QLatin1String importString("/imports/"); + + if (componentPath.contains(importString)) { + int index = componentPath.indexOf(importString) + 8; + const QString relativeImportPath = componentPath.right(componentPath.length() - index); + QString fixedComponentPath = QLibraryInfo::location(QLibraryInfo::ImportsPath) + relativeImportPath; + fixedComponentPath.replace(QLatin1Char('\\'), QLatin1Char('/')); + if (QFileInfo(fixedComponentPath).exists()) + return fixedComponentPath; + QString fixedPath = QFileInfo(fixedComponentPath).path(); + if (fixedPath.endsWith(QLatin1String(".1.0"))) { + //plugin directories might contain the version number + fixedPath.chop(4); + fixedPath += QLatin1Char('/') + QFileInfo(componentPath).fileName(); + if (QFileInfo(fixedPath).exists()) + return fixedPath; + } + } + + return result; +} + +QObject *ObjectNodeInstance::createComponent(const QString &componentPath, QQmlContext *context) +{ + QQmlComponent component(context->engine(), fixComponentPathForIncompatibleQt(componentPath)); + QObject *object = component.beginCreate(context); + + tweakObjects(object); + component.completeCreate(); + + if (component.isError()) { + qDebug() << componentPath; + foreach (const QQmlError &error, component.errors()) + qDebug() << error; + } + + QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); + + return object; +} + +QObject *ObjectNodeInstance::createCustomParserObject(const QString &nodeSource, const QStringList &imports, QQmlContext *context) +{ + QQmlComponent component(context->engine()); + + QByteArray importArray; + foreach (const QString &import, imports) { + importArray.append(import.toUtf8()); + } + + QByteArray data(nodeSource.toUtf8()); + + data.prepend(importArray); + + component.setData(data, context->baseUrl().resolved(QUrl("createCustomParserObject.qml"))); + + QObject *object = component.beginCreate(context); + tweakObjects(object); + component.completeCreate(); + + QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); + + return object; +} + +QObject *ObjectNodeInstance::createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context) +{ + QObject *object = 0; + QQmlType *type = QQmlMetaType::qmlType(typeName.toUtf8(), majorNumber, minorNumber); + if (type) { + if (type->typeName() == "QQmlComponent") { + object = new QQmlComponent(context->engine(), 0); + } else { + object = type->create(); + } + } else { + qWarning() << "QuickDesigner: Cannot create an object of type" + << QString("%1 %2,%3").arg(typeName).arg(majorNumber).arg(minorNumber) + << "- type isn't known to declarative meta type system"; + } + + tweakObjects(object); + + if (object && context) + QQmlEngine::setContextForObject(object, context); + + QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); + + return object; +} + +QObject *ObjectNodeInstance::object() const +{ + if (!m_object.isNull() && !QObjectPrivate::get(m_object.data())->wasDeleted) + return m_object.data(); + return 0; +} + +bool ObjectNodeInstance::hasContent() const +{ + return false; +} + +bool ObjectNodeInstance::isResizable() const +{ + return false; +} + +bool ObjectNodeInstance::isMovable() const +{ + return false; +} + +bool ObjectNodeInstance::isInPositioner() const +{ + return m_isInPositioner; +} + +void ObjectNodeInstance::setInPositioner(bool isInPositioner) +{ + m_isInPositioner = isInPositioner; +} + +void ObjectNodeInstance::refreshPositioner() +{ +} + +void ObjectNodeInstance::updateAnchors() +{ +} + +QQmlContext *ObjectNodeInstance::context() const +{ + if (nodeInstanceServer()) + return nodeInstanceServer()->context(); + + qWarning() << "Error: No NodeInstanceServer"; + return 0; +} + +QQmlEngine *ObjectNodeInstance::engine() const +{ + return nodeInstanceServer()->engine(); +} + +void ObjectNodeInstance::paintUpdate() +{ +} + +void ObjectNodeInstance::activateState() +{ +} + +void ObjectNodeInstance::deactivateState() +{ +} + +void ObjectNodeInstance::populateResetHashes() +{ + QStringList propertyNameList = propertyNameForWritableProperties(object()); + + foreach (const QString &propertyName, propertyNameList) { + QQmlProperty property(object(), propertyName, QQmlEngine::contextForObject(object())); + + QQmlAbstractBinding::Pointer binding = QQmlAbstractBinding::getPointer(QQmlPropertyPrivate::binding(property)); + if (binding) { + m_resetBindingHash.insert(propertyName, binding); + } else if (property.isWritable()) { + m_resetValueHash.insert(propertyName, property.read()); + } + } +} + +QQmlAbstractBinding *ObjectNodeInstance::resetBinding(const QString &propertyName) const +{ + return m_resetBindingHash.value(propertyName).data(); +} + +bool ObjectNodeInstance::hasValidResetBinding(const QString &propertyName) const +{ + return m_resetBindingHash.contains(propertyName) && m_resetBindingHash.value(propertyName).data(); +} + +QVariant ObjectNodeInstance::resetValue(const QString &propertyName) const +{ + return m_resetValueHash.value(propertyName); +} + +void ObjectNodeInstance::setResetValue(const QString &propertyName, const QVariant &value) +{ + m_resetValueHash.insert(propertyName, value); +} + +void ObjectNodeInstance::paint(QPainter * /*painter*/) +{ +} + +QImage ObjectNodeInstance::renderImage() const +{ + return QImage(); +} + +QObject *ObjectNodeInstance::parent() const +{ + if (!object()) + return 0; + + return object()->parent(); +} + +QObject *parentObject(QObject *object) +{ + QQuickItem *quickItem = qobject_cast<QQuickItem*>(object); + if (quickItem) + return quickItem->parentItem(); + + return object->parent(); +} + +ObjectNodeInstance::Pointer ObjectNodeInstance::parentInstance() const +{ + QObject *parentHolder = parent(); + if (!nodeInstanceServer()) + return Pointer(); + + while (parentHolder) { + if (nodeInstanceServer()->hasInstanceForObject(parentHolder)) + return nodeInstanceServer()->instanceForObject(parentHolder).internalInstance(); + + parentHolder = parentObject(parentHolder); + } + + return Pointer(); +} + +QRectF ObjectNodeInstance::boundingRect() const +{ + return QRect(); +} + +QPointF ObjectNodeInstance::position() const +{ + return QPointF(); +} + +QSizeF ObjectNodeInstance::size() const +{ + return QSizeF(); +} + +int ObjectNodeInstance::penWidth() const +{ + return 0; +} + +void ObjectNodeInstance::createDynamicProperty(const QString &name, const QString &/*typeName*/) +{ + if (m_metaObject == 0) { + qWarning() << "ObjectNodeInstance.createDynamicProperty: No Metaobject."; + return; + } + + m_metaObject->createNewProperty(name); +} + +bool ObjectNodeInstance::updateStateVariant(const ObjectNodeInstance::Pointer &/*target*/, const QString &/*propertyName*/, const QVariant &/*value*/) +{ + return false; +} + +bool ObjectNodeInstance::updateStateBinding(const ObjectNodeInstance::Pointer &/*target*/, const QString &/*propertyName*/, const QString &/*expression*/) +{ + return false; +} + +bool ObjectNodeInstance::resetStateProperty(const ObjectNodeInstance::Pointer &/*target*/, const QString &/*propertyName*/, const QVariant &/*resetValue*/) +{ + return false; +} + +void ObjectNodeInstance::doComponentComplete() +{ + +} + +bool ObjectNodeInstance::isRootNodeInstance() const +{ + return nodeInstanceServer()->rootNodeInstance().isWrappingThisObject(object()); +} + +bool ObjectNodeInstance::isValid() const +{ + return instanceId() >= 0 && object(); +} + +} +} + diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h new file mode 100644 index 0000000000..b8451d5b0c --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef ABSTRACTNODEINSTANCE_H +#define ABSTRACTNODEINSTANCE_H + +#include "nodeinstanceserver.h" +#include "nodeinstancemetaobject.h" +#include "nodeinstancesignalspy.h" + +#include <QPainter> +#include <QSharedPointer> +#include <QWeakPointer> + +QT_BEGIN_NAMESPACE +class QGraphicsItem; +class QQmlContext; +class QQmlEngine; +class QQmlProperty; +class QQmlAbstractBinding; +QT_END_NAMESPACE + +namespace QmlDesigner { + +class NodeInstanceServer; + +namespace Internal { + +class QmlGraphicsItemNodeInstance; +class GraphicsWidgetNodeInstance; +class GraphicsViewNodeInstance; +class GraphicsSceneNodeInstance; +class ProxyWidgetNodeInstance; +class WidgetNodeInstance; + +class ObjectNodeInstance +{ +public: + typedef QSharedPointer<ObjectNodeInstance> Pointer; + typedef QWeakPointer<ObjectNodeInstance> WeakPointer; + explicit ObjectNodeInstance(QObject *object); + + virtual ~ObjectNodeInstance(); + void destroy(); + //void setModelNode(const ModelNode &node); + + static Pointer create(QObject *objectToBeWrapped); + static QObject *createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context); + static QObject *createCustomParserObject(const QString &nodeSource, const QStringList &imports, QQmlContext *context); + static QObject *createComponent(const QString &componentPath, QQmlContext *context); + static QObject *createComponentWrap(const QString &nodeSource, const QStringList &imports, QQmlContext *context); + + void setInstanceId(qint32 id); + qint32 instanceId() const; + + NodeInstanceServer *nodeInstanceServer() const; + void setNodeInstanceServer(NodeInstanceServer *server); + virtual void initializePropertyWatcher(const Pointer &objectNodeInstance); + virtual void initialize(const Pointer &objectNodeInstance); + virtual void paint(QPainter *painter); + virtual QImage renderImage() const; + + virtual QObject *parent() const; + + Pointer parentInstance() const; + + virtual void reparent(const ObjectNodeInstance::Pointer &oldParentInstance, const QString &oldParentProperty, const ObjectNodeInstance::Pointer &newParentInstance, const QString &newParentProperty); + + virtual void setId(const QString &id); + virtual QString id() const; + + virtual bool isTransition() const; + virtual bool isPositioner() const; + virtual bool isQuickItem() const; + + virtual bool equalGraphicsItem(QGraphicsItem *item) const; + + virtual QRectF boundingRect() const; + + virtual QPointF position() const; + virtual QSizeF size() const; + virtual QTransform transform() const; + virtual QTransform customTransform() const; + virtual QTransform sceneTransform() const; + virtual double opacity() const; + + virtual int penWidth() const; + + virtual bool hasAnchor(const QString &name) const; + virtual QPair<QString, ServerNodeInstance> anchor(const QString &name) const; + virtual bool isAnchoredBySibling() const; + virtual bool isAnchoredByChildren() const; + + virtual double rotation() const; + virtual double scale() const; + virtual QList<QGraphicsTransform *> transformations() const; + virtual QPointF transformOriginPoint() const; + virtual double zValue() const; + + virtual void setPropertyVariant(const QString &name, const QVariant &value); + virtual void setPropertyBinding(const QString &name, const QString &expression); + virtual QVariant property(const QString &name) const; + virtual void resetProperty(const QString &name); + virtual void refreshProperty(const QString &name); + virtual QString instanceType(const QString &name) const; + QStringList propertyNames() const; + + virtual QList<ServerNodeInstance> childItems() const; + + void createDynamicProperty(const QString &name, const QString &typeName); + void setDeleteHeldInstance(bool deleteInstance); + bool deleteHeldInstance() const; + + virtual void updateAnchors(); + virtual void paintUpdate(); + + virtual void activateState(); + virtual void deactivateState(); + + void populateResetHashes(); + bool hasValidResetBinding(const QString &propertyName) const; + QQmlAbstractBinding *resetBinding(const QString &propertyName) const; + QVariant resetValue(const QString &propertyName) const; + void setResetValue(const QString &propertyName, const QVariant &value); + + QObject *object() const; + + virtual bool hasContent() const; + virtual bool isResizable() const; + virtual bool isMovable() const; + bool isInPositioner() const; + void setInPositioner(bool isInPositioner); + virtual void refreshPositioner(); + + bool hasBindingForProperty(const QString &name, bool *hasChanged = 0) const; + + QQmlContext *context() const; + QQmlEngine *engine() const; + + virtual bool updateStateVariant(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QVariant &value); + virtual bool updateStateBinding(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QString &expression); + virtual bool resetStateProperty(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QVariant &resetValue); + + + bool isValid() const; + bool isRootNodeInstance() const; + + virtual void doComponentComplete(); + + virtual QList<ServerNodeInstance> stateInstances() const; + + virtual void setNodeSource(const QString &source); + + static QVariant fixResourcePaths(const QVariant &value); + +protected: + void doResetProperty(const QString &propertyName); + void removeFromOldProperty(QObject *object, QObject *oldParent, const QString &oldParentProperty); + void addToNewProperty(QObject *object, QObject *newParent, const QString &newParentProperty); + void deleteObjectsInList(const QQmlProperty &metaProperty); + QVariant convertSpecialCharacter(const QVariant& value) const; + +private: + QHash<QString, QVariant> m_resetValueHash; + QHash<QString, QWeakPointer<QQmlAbstractBinding> > m_resetBindingHash; + QHash<QString, ServerNodeInstance> m_modelAbstractPropertyHash; + mutable QHash<QString, bool> m_hasBindingHash; + qint32 m_instanceId; + QString m_id; + + QPointer<NodeInstanceServer> m_nodeInstanceServer; + QString m_parentProperty; + bool m_deleteHeldInstance; + QPointer<QObject> m_object; + NodeInstanceMetaObject *m_metaObject; + NodeInstanceSignalSpy m_signalSpy; + bool m_isInPositioner; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // ABSTRACTNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.cpp new file mode 100644 index 0000000000..4504bbb268 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "positionernodeinstance.h" +#include <private/qquickpositioners_p.h> + +namespace QmlDesigner { +namespace Internal { + +PositionerNodeInstance::PositionerNodeInstance(QQuickBasePositioner *item) + : QuickItemNodeInstance(item) +{ +} + +bool PositionerNodeInstance::isPositioner() const +{ + return true; +} + +bool PositionerNodeInstance::isResizable() const +{ + return true; +} + +void PositionerNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) +{ + if (name == "move" || name == "add" || name == "populate") + return; + + QuickItemNodeInstance::setPropertyVariant(name, value); +} + +void PositionerNodeInstance::setPropertyBinding(const QString &name, const QString &expression) +{ + if (name == "move" || name == "add" || name == "populate") + return; + + QuickItemNodeInstance::setPropertyBinding(name, expression); +} + +PositionerNodeInstance::Pointer PositionerNodeInstance::create(QObject *object) +{ + QQuickBasePositioner *positioner = qobject_cast<QQuickBasePositioner*>(object); + + Q_ASSERT(positioner); + + Pointer instance(new PositionerNodeInstance(positioner)); + + instance->setHasContent(anyItemHasContent(positioner)); + positioner->setFlag(QQuickItem::ItemHasContents, true); + + static_cast<QQmlParserStatus*>(positioner)->classBegin(); + + instance->populateResetHashes(); + + return instance; +} + +QQuickBasePositioner *PositionerNodeInstance::positioner() const +{ + Q_ASSERT(qobject_cast<QQuickBasePositioner*>(object())); + return static_cast<QQuickBasePositioner*>(object()); +} + +void PositionerNodeInstance::refreshPositioner() +{ + bool success = QMetaObject::invokeMethod(positioner(), "prePositioning"); + Q_ASSERT(success); +} + +} +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.h new file mode 100644 index 0000000000..456591ed23 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef POSITIONERNODEINSTANCE_H +#define POSITIONERNODEINSTANCE_H + +#include "quickitemnodeinstance.h" + +QT_BEGIN_NAMESPACE +class QQuickBasePositioner; +QT_END_NAMESPACE + +namespace QmlDesigner { +namespace Internal { + +class PositionerNodeInstance : public QuickItemNodeInstance +{ +public: + typedef QSharedPointer<PositionerNodeInstance> Pointer; + typedef QWeakPointer<PositionerNodeInstance> WeakPointer; + + static Pointer create(QObject *objectToBeWrapped); + + void setPropertyVariant(const QString &name, const QVariant &value); + void setPropertyBinding(const QString &name, const QString &expression); + + bool isPositioner() const; + + bool isResizable() const; + + void refreshPositioner(); + +protected: + PositionerNodeInstance(QQuickBasePositioner *item); + QQuickBasePositioner *positioner() const; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // POSITIONERNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.cpp new file mode 100644 index 0000000000..6d2d220185 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmlpropertychangesnodeinstance.h" +#include "qmlstatenodeinstance.h" +#include <QQmlEngine> +#include <QQmlContext> +#include <QQmlExpression> +#include <private/qqmlbinding_p.h> +#include <QMutableListIterator> + + +#include <private/qquickstate_p_p.h> +#include <private/qquickpropertychanges_p.h> +#include <private/qqmlproperty_p.h> + +namespace QmlDesigner { +namespace Internal { + +QmlPropertyChangesNodeInstance::QmlPropertyChangesNodeInstance(QQuickPropertyChanges *propertyChangesObject) : + ObjectNodeInstance(propertyChangesObject) +{ +} + +QmlPropertyChangesNodeInstance::Pointer QmlPropertyChangesNodeInstance::create(QObject *object) +{ + QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(object); + + Q_ASSERT(propertyChange); + + Pointer instance(new QmlPropertyChangesNodeInstance(propertyChange)); + + instance->populateResetHashes(); + + return instance; +} + +void QmlPropertyChangesNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) +{ + QMetaObject metaObject = QQuickPropertyChanges::staticMetaObject; + + if (metaObject.indexOfProperty(name.toLatin1()) > 0) { // 'restoreEntryValues', 'explicit' + ObjectNodeInstance::setPropertyVariant(name, value); + } else { + changesObject()->changeValue(name.toLatin1(), value); + QObject *targetObject = changesObject()->object(); + if (targetObject && nodeInstanceServer()->activeStateInstance().isWrappingThisObject(changesObject()->state())) { + ServerNodeInstance targetInstance = nodeInstanceServer()->instanceForObject(targetObject); + targetInstance.setPropertyVariant(name, value); + } + } +} + +void QmlPropertyChangesNodeInstance::setPropertyBinding(const QString &name, const QString &expression) +{ + QMetaObject metaObject = QQuickPropertyChanges::staticMetaObject; + + if (metaObject.indexOfProperty(name.toLatin1()) > 0) { // 'restoreEntryValues', 'explicit' + ObjectNodeInstance::setPropertyBinding(name, expression); + } else { + changesObject()->changeExpression(name.toLatin1(), expression); + } +} + +QVariant QmlPropertyChangesNodeInstance::property(const QString &name) const +{ + return changesObject()->property(name.toLatin1()); +} + +void QmlPropertyChangesNodeInstance::resetProperty(const QString &name) +{ + changesObject()->removeProperty(name.toLatin1()); +} + + +void QmlPropertyChangesNodeInstance::reparent(const ServerNodeInstance &oldParentInstance, const QString &oldParentProperty, const ServerNodeInstance &newParentInstance, const QString &newParentProperty) +{ + changesObject()->detachFromState(); + + ObjectNodeInstance::reparent(oldParentInstance.internalInstance(), oldParentProperty, newParentInstance.internalInstance(), newParentProperty); + + changesObject()->attachToState(); +} + +QQuickPropertyChanges *QmlPropertyChangesNodeInstance::changesObject() const +{ + Q_ASSERT(qobject_cast<QQuickPropertyChanges*>(object())); + return static_cast<QQuickPropertyChanges*>(object()); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.h new file mode 100644 index 0000000000..d8a75e8c66 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#ifndef QMLPROPERTYCHANGESNODEINSTANCE_H +#define QMLPROPERTYCHANGESNODEINSTANCE_H + +#include "objectnodeinstance.h" +#include <private/qquickstateoperations_p.h> +#include <private/qquickpropertychanges_p.h> + +#include <QPair> +#include <QWeakPointer> + +QT_BEGIN_NAMESPACE +class QQuickProperty; +QT_END_NAMESPACE + +namespace QmlDesigner { + +namespace Internal { + +class QmlPropertyChangesNodeInstance; + +class QmlPropertyChangesNodeInstance : public ObjectNodeInstance +{ +public: + typedef QSharedPointer<QmlPropertyChangesNodeInstance> Pointer; + typedef QWeakPointer<QmlPropertyChangesNodeInstance> WeakPointer; + + static Pointer create(QObject *objectToBeWrapped); + + virtual void setPropertyVariant(const QString &name, const QVariant &value); + virtual void setPropertyBinding(const QString &name, const QString &expression); + virtual QVariant property(const QString &name) const; + virtual void resetProperty(const QString &name); + + using ObjectNodeInstance::reparent; // keep the virtual reparent(...) method around + void reparent(const ServerNodeInstance &oldParentInstance, const QString &oldParentProperty, const ServerNodeInstance &newParentInstance, const QString &newParentProperty); + +protected: + QmlPropertyChangesNodeInstance(QQuickPropertyChanges *object); + QQuickPropertyChanges *changesObject() const; +}; + +} // namespace Internal +} // namespace QmlDesigner + +//QML_DECLARE_TYPE(QmlDesigner::Internal::QmlPropertyChangesObject) + +#endif // QMLPROPERTYCHANGESNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp new file mode 100644 index 0000000000..0a4e830665 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmlstatenodeinstance.h" + +#include <private/qquickstategroup_p.h> + +#include "qmlpropertychangesnodeinstance.h" +#include <private/qquickstateoperations_p.h> + +namespace QmlDesigner { +namespace Internal { + +/** + \class QmlStateNodeInstance + + QmlStateNodeInstance manages a QQuickState object. + */ + +QmlStateNodeInstance::QmlStateNodeInstance(QQuickState *object) : + ObjectNodeInstance(object) +{ +} + +QmlStateNodeInstance::Pointer + QmlStateNodeInstance::create(QObject *object) +{ + QQuickState *stateObject = qobject_cast<QQuickState*>(object); + + Q_ASSERT(stateObject); + + Pointer instance(new QmlStateNodeInstance(stateObject)); + + instance->populateResetHashes(); + + return instance; +} + +void QmlStateNodeInstance::activateState() +{ + if (stateGroup()) { + if (!isStateActive()) { + nodeInstanceServer()->setStateInstance(nodeInstanceServer()->instanceForObject(object())); + stateGroup()->setState(property("name").toString()); + } + } +} + +void QmlStateNodeInstance::deactivateState() +{ + if (stateGroup()) { + if (isStateActive()) { + nodeInstanceServer()->clearStateInstance(); + stateGroup()->setState(QString()); + } + } +} + +QQuickState *QmlStateNodeInstance::stateObject() const +{ + Q_ASSERT(object()); + Q_ASSERT(qobject_cast<QQuickState*>(object())); + return static_cast<QQuickState*>(object()); +} + +QQuickStateGroup *QmlStateNodeInstance::stateGroup() const +{ + return stateObject()->stateGroup(); +} + +bool QmlStateNodeInstance::isStateActive() const +{ + return stateObject() && stateGroup() && stateGroup()->state() == property("name"); +} + +void QmlStateNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) +{ + bool hasParent = parent(); + bool isStateOfTheRootModelNode = parentInstance() && parentInstance()->isRootNodeInstance(); + if (name == "when" && (!hasParent || isStateOfTheRootModelNode)) + return; + + ObjectNodeInstance::setPropertyVariant(name, value); +} + +void QmlStateNodeInstance::setPropertyBinding(const QString &name, const QString &expression) +{ + bool hasParent = parent(); + bool isStateOfTheRootModelNode = parentInstance() && parentInstance()->isRootNodeInstance(); + if (name == "when" && (!hasParent || isStateOfTheRootModelNode)) + return; + + ObjectNodeInstance::setPropertyBinding(name, expression); +} + +bool QmlStateNodeInstance::updateStateVariant(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QVariant &value) +{ + return stateObject()->changeValueInRevertList(target->object(), propertyName.toLatin1(), value); +} + +bool QmlStateNodeInstance::updateStateBinding(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QString &expression) +{ + return stateObject()->changeValueInRevertList(target->object(), propertyName.toLatin1(), expression); +} + +bool QmlStateNodeInstance::resetStateProperty(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QVariant & /* resetValue */) +{ + return stateObject()->removeEntryFromRevertList(target->object(), propertyName.toLatin1()); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h new file mode 100644 index 0000000000..d93dcc8afb --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#ifndef QMLSTATENODEINSTANCE_H +#define QMLSTATENODEINSTANCE_H + +#include "objectnodeinstance.h" + +QT_BEGIN_NAMESPACE +class QQuickState; +class QQuickStateGroup; +QT_END_NAMESPACE + +namespace QmlDesigner { + +namespace Internal { + +class QmlStateNodeInstance : public ObjectNodeInstance +{ +public: + typedef QSharedPointer<QmlStateNodeInstance> Pointer; + typedef QWeakPointer<QmlStateNodeInstance> WeakPointer; + + static Pointer create(QObject *objectToBeWrapped); + + void setPropertyVariant(const QString &name, const QVariant &value); + void setPropertyBinding(const QString &name, const QString &expression); + + void activateState(); + void deactivateState(); + + bool updateStateVariant(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QVariant &value); + bool updateStateBinding(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QString &expression); + bool resetStateProperty(const ObjectNodeInstance::Pointer &target, const QString &propertyName, const QVariant &resetValue); + + +protected: + + QmlStateNodeInstance(QQuickState *object); + + bool isStateActive() const; + + QQuickState *stateObject() const; + QQuickStateGroup *stateGroup() const; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // QMLSTATENODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.cpp new file mode 100644 index 0000000000..e2f713b5aa --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmltransitionnodeinstance.h" +#include <private/qquicktransition_p.h> + +namespace QmlDesigner { +namespace Internal { + +QmlTransitionNodeInstance::QmlTransitionNodeInstance(QQuickTransition *transition) + : ObjectNodeInstance(transition) +{ +} + +QmlTransitionNodeInstance::Pointer QmlTransitionNodeInstance::create(QObject *object) +{ + QQuickTransition *transition = qobject_cast<QQuickTransition*>(object); + + Q_ASSERT(transition); + + Pointer instance(new QmlTransitionNodeInstance(transition)); + + instance->populateResetHashes(); + + transition->setToState("invalidState"); + transition->setFromState("invalidState"); + + return instance; +} + +bool QmlTransitionNodeInstance::isTransition() const +{ + return true; +} + +void QmlTransitionNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) +{ + if (name == "from" || name == "to") + return; + + ObjectNodeInstance::setPropertyVariant(name, value); +} + +QQuickTransition *QmlTransitionNodeInstance::qmlTransition() const +{ + Q_ASSERT(qobject_cast<QQuickTransition*>(object())); + return static_cast<QQuickTransition*>(object()); +} +} +} diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.h new file mode 100644 index 0000000000..3603516ee9 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QMLTRANSITIONNODEINSTANCE_H +#define QMLTRANSITIONNODEINSTANCE_H + +#include "objectnodeinstance.h" + +QT_BEGIN_NAMESPACE +class QQuickTransition; +QT_END_NAMESPACE + +namespace QmlDesigner { +namespace Internal { + +class QmlTransitionNodeInstance : public ObjectNodeInstance +{ +public: + typedef QSharedPointer<QmlTransitionNodeInstance> Pointer; + typedef QWeakPointer<QmlTransitionNodeInstance> WeakPointer; + + static Pointer create(QObject *objectToBeWrapped); + + void setPropertyVariant(const QString &name, const QVariant &value); + + bool isTransition() const; + +protected: + QQuickTransition *qmlTransition() const; + +private: + QmlTransitionNodeInstance(QQuickTransition *transition); +}; +} +} +#endif // QMLTRANSITIONNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 461c16400e..71f0e7533d 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -29,7 +29,8 @@ #include "qt5informationnodeinstanceserver.h" -#include <QSGItem> +#include <QQuickItem> +#include <QQuickView> #include "servernodeinstance.h" #include "childrenchangeeventfilter.h" @@ -58,6 +59,7 @@ #include "componentcompletedcommand.h" #include "createscenecommand.h" #include "tokencommand.h" +#include "removesharedmemorycommand.h" #include "dummycontextobject.h" @@ -90,12 +92,14 @@ void Qt5InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands() if (!inFunction) { inFunction = true; + DesignerSupport::polishItems(quickView()); + QSet<ServerNodeInstance> informationChangedInstanceSet; QVector<InstancePropertyPair> propertyChangedList; bool adjustSceneRect = false; - if (sgView()) { - foreach (QSGItem *item, allItems()) { + if (quickView()) { + foreach (QQuickItem *item, allItems()) { if (item && hasInstanceForObject(item)) { ServerNodeInstance instance = instanceForObject(item); @@ -255,4 +259,10 @@ void Qt5InformationNodeInstanceServer::completeComponent(const CompleteComponent nodeInstanceClient()->informationChanged(createAllInformationChangedCommand(instanceList, true)); } +void QmlDesigner::Qt5InformationNodeInstanceServer::removeSharedMemory(const QmlDesigner::RemoveSharedMemoryCommand &command) +{ + if (command.typeName() == "Values") + ValuesChangedCommand::removeSharedMemorys(command.keyNumbers()); +} + } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index 29b3e3cd8d..3037282640 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -46,6 +46,7 @@ public: void createScene(const CreateSceneCommand &command); void completeComponent(const CompleteComponentCommand &command); void token(const TokenCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); protected: void collectItemChangesAndSendChangeCommands(); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp index a844acca8b..55fe6be533 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp @@ -35,11 +35,14 @@ #include "qt5previewnodeinstanceserver.h" #include "qt5rendernodeinstanceserver.h" +#include <designersupport.h> + namespace QmlDesigner { Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) : NodeInstanceClientProxy(parent) { + DesignerSupport::activateDesignerWindowManager(); if (QCoreApplication::arguments().at(2) == QLatin1String("previewmode")) { setNodeInstanceServer(new Qt5PreviewNodeInstanceServer(this)); } else if (QCoreApplication::arguments().at(2) == QLatin1String("editormode")) { diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index 26b3022704..26d78ead60 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -30,8 +30,8 @@ #include "qt5nodeinstanceserver.h" -#include <QSGItem> -#include <QSGView> +#include <QQuickItem> +#include <QQuickView> #include <designersupport.h> #include <addimportcontainer.h> @@ -44,44 +44,38 @@ Qt5NodeInstanceServer::Qt5NodeInstanceServer(NodeInstanceClientInterface *nodeIn m_designerSupport(new DesignerSupport) { addImportString("import QtQuick 2.0\n"); + DesignerSupport::activateDesignerMode(); } Qt5NodeInstanceServer::~Qt5NodeInstanceServer() { - delete sgView(); + delete quickView(); delete m_designerSupport; m_designerSupport = 0; } -QSGView *Qt5NodeInstanceServer::sgView() const +QQuickView *Qt5NodeInstanceServer::quickView() const { - return m_sgView.data(); + return m_quickView.data(); } void Qt5NodeInstanceServer::initializeView(const QVector<AddImportContainer> &/*importVector*/) { - Q_ASSERT(!sgView()); - - m_sgView = new QSGView; -#ifndef Q_OS_MAC - sgView()->setAttribute(Qt::WA_DontShowOnScreen, true); -#endif - sgView()->show(); -#ifdef Q_OS_MAC - sgView()->setAttribute(Qt::WA_DontShowOnScreen, true); -#endif - sgView()->setUpdatesEnabled(false); + Q_ASSERT(!quickView()); + + m_quickView = new QQuickView; + DesignerSupport::createOpenGLContext(m_quickView.data()); } -QDeclarativeView *Qt5NodeInstanceServer::declarativeView() const +QQmlView *Qt5NodeInstanceServer::declarativeView() const { return 0; } -QDeclarativeEngine *Qt5NodeInstanceServer::engine() const +QQmlEngine *Qt5NodeInstanceServer::engine() const { - if (sgView()) - return sgView()->engine(); + if (quickView()) + return quickView()->engine(); return 0; } @@ -92,7 +86,7 @@ void Qt5NodeInstanceServer::resizeCanvasSizeToRootItemSize() void Qt5NodeInstanceServer::resetAllItems() { - foreach (QSGItem *item, allItems()) + foreach (QQuickItem *item, allItems()) DesignerSupport::resetDirty(item); } @@ -104,29 +98,29 @@ QList<ServerNodeInstance> Qt5NodeInstanceServer::setupScene(const CreateSceneCom QList<ServerNodeInstance> instanceList = setupInstances(command); - sgView()->resize(rootNodeInstance().boundingRect().size().toSize()); + quickView()->resize(rootNodeInstance().boundingRect().size().toSize()); return instanceList; } -QList<QSGItem*> subItems(QSGItem *parentItem) +QList<QQuickItem*> subItems(QQuickItem *parentItem) { - QList<QSGItem*> itemList; + QList<QQuickItem*> itemList; itemList.append(parentItem->childItems()); - foreach (QSGItem *childItem, parentItem->childItems()) + foreach (QQuickItem *childItem, parentItem->childItems()) itemList.append(subItems(childItem)); return itemList; } -QList<QSGItem*> Qt5NodeInstanceServer::allItems() const +QList<QQuickItem*> Qt5NodeInstanceServer::allItems() const { - QList<QSGItem*> itemList; + QList<QQuickItem*> itemList; - if (sgView()) { - itemList.append(sgView()->rootItem()); - itemList.append(subItems(sgView()->rootItem())); + if (quickView()) { + itemList.append(quickView()->rootObject()); + itemList.append(subItems(quickView()->rootObject())); } return itemList; @@ -150,9 +144,9 @@ void Qt5NodeInstanceServer::createScene(const CreateSceneCommand &command) void Qt5NodeInstanceServer::clearScene(const ClearSceneCommand &command) { - NodeInstanceServer::clearScene(command); delete m_designerSupport; m_designerSupport = 0; + NodeInstanceServer::clearScene(command); } } // QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h index c6a74890ba..8609ebd875 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h @@ -35,7 +35,7 @@ #include "nodeinstanceserver.h" QT_BEGIN_NAMESPACE -class QSGItem; +class QQuickItem; class DesignerSupport; QT_END_NAMESPACE @@ -48,9 +48,9 @@ public: Qt5NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient); ~Qt5NodeInstanceServer(); - QSGView *sgView() const; - QDeclarativeView *declarativeView() const; - QDeclarativeEngine *engine() const; + QQuickView *quickView() const; + QQmlView *declarativeView() const; + QQmlEngine *engine() const; void refreshBindings(); DesignerSupport *designerSupport() const; @@ -63,10 +63,10 @@ protected: void resizeCanvasSizeToRootItemSize(); void resetAllItems(); QList<ServerNodeInstance> setupScene(const CreateSceneCommand &command); - QList<QSGItem*> allItems() const; + QList<QQuickItem*> allItems() const; private: - QWeakPointer<QSGView> m_sgView; + QPointer<QQuickView> m_quickView; DesignerSupport *m_designerSupport; }; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp index f6da6f5563..f8b3dcdd4a 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp @@ -32,8 +32,9 @@ #include "nodeinstanceclientinterface.h" #include "statepreviewimagechangedcommand.h" #include "createscenecommand.h" - -#include <QSGItem> +#include "removesharedmemorycommand.h" +#include <QQuickView> +#include <QQuickItem> #include <designersupport.h> namespace QmlDesigner { @@ -64,14 +65,22 @@ void Qt5PreviewNodeInstanceServer::collectItemChangesAndSendChangeCommands() { static bool inFunction = false; + if (rootNodeInstance().internalSGItem() == 0) + return; + if (!inFunction && nodeInstanceClient()->bytesToWrite() < 10000) { inFunction = true; + + DesignerSupport::polishItems(quickView()); + QVector<ImageContainer> imageContainerVector; - imageContainerVector.append(ImageContainer(0, renderPreviewImage())); + imageContainerVector.append(ImageContainer(0, renderPreviewImage(), -1)); foreach (ServerNodeInstance instance, rootNodeInstance().stateInstances()) { instance.activateState(); - imageContainerVector.append(ImageContainer(instance.instanceId(), renderPreviewImage())); + QImage previewImage = renderPreviewImage(); + if (!previewImage.isNull()) + imageContainerVector.append(ImageContainer(instance.instanceId(), renderPreviewImage(), instance.instanceId())); instance.deactivateState(); } @@ -87,9 +96,9 @@ void Qt5PreviewNodeInstanceServer::changeState(const ChangeStateCommand &/*comma } -static void updateDirtyNodeRecursive(QSGItem *parentItem) +static void updateDirtyNodeRecursive(QQuickItem *parentItem) { - foreach (QSGItem *childItem, parentItem->childItems()) + foreach (QQuickItem *childItem, parentItem->childItems()) updateDirtyNodeRecursive(childItem); DesignerSupport::updateDirtyNode(parentItem); @@ -114,4 +123,10 @@ QImage Qt5PreviewNodeInstanceServer::renderPreviewImage() return previewImage; } +void QmlDesigner::Qt5PreviewNodeInstanceServer::removeSharedMemory(const QmlDesigner::RemoveSharedMemoryCommand &command) +{ + if (command.typeName() == "Image") + ImageContainer::removeSharedMemorys(command.keyNumbers()); +} + } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.h index 5eab64de7d..ce47777ca1 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.h @@ -42,6 +42,7 @@ public: void createScene(const CreateSceneCommand &command); void changeState(const ChangeStateCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); QImage renderPreviewImage(); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp index 67ec984963..c0c5078f5a 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp @@ -29,7 +29,8 @@ #include "qt5rendernodeinstanceserver.h" -#include <QSGItem> +#include <QQuickItem> +#include <QQuickView> #include "servernodeinstance.h" #include "childrenchangeeventfilter.h" @@ -57,8 +58,8 @@ #include "completecomponentcommand.h" #include "componentcompletedcommand.h" #include "createscenecommand.h" -#include "sgitemnodeinstance.h" - +#include "quickitemnodeinstance.h" +#include "removesharedmemorycommand.h" #include "dummycontextobject.h" @@ -69,7 +70,7 @@ namespace QmlDesigner { Qt5RenderNodeInstanceServer::Qt5RenderNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : Qt5NodeInstanceServer(nodeInstanceClient) { - Internal::SGItemNodeInstance::createEffectItem(true); + Internal::QuickItemNodeInstance::createEffectItem(true); } void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() @@ -78,12 +79,20 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() if (!inFunction) { inFunction = true; - if (sgView() && nodeInstanceClient()->bytesToWrite() < 10000) { - foreach (QSGItem *item, allItems()) { - if (item && hasInstanceForObject(item)) { - ServerNodeInstance instance = instanceForObject(item); - if (DesignerSupport::isDirty(item, DesignerSupport::ContentUpdateMask)) - m_dirtyInstanceSet.insert(instance); + DesignerSupport::polishItems(quickView()); + + if (quickView() && nodeInstanceClient()->bytesToWrite() < 10000) { + foreach (QQuickItem *item, allItems()) { + if (item) { + if (hasInstanceForObject(item) + && DesignerSupport::isDirty(item, DesignerSupport::ContentUpdateMask)) { + m_dirtyInstanceSet.insert(instanceForObject(item)); + } else if (DesignerSupport::isDirty(item, DesignerSupport::AllMask)) { + ServerNodeInstance ancestorInstance = findNodeInstanceForItem(item->parentItem()); + if (ancestorInstance.isValid()) + m_dirtyInstanceSet.insert(ancestorInstance); + } + DesignerSupport::updateDirtyNode(item); } } @@ -94,8 +103,6 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() m_dirtyInstanceSet.clear(); } - resetAllItems(); - slowDownRenderTimer(); nodeInstanceClient()->flush(); nodeInstanceClient()->synchronizeWithClientProcess(); @@ -105,6 +112,18 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() } } +ServerNodeInstance Qt5RenderNodeInstanceServer::findNodeInstanceForItem(QQuickItem *item) const +{ + if (item) { + if (hasInstanceForObject(item)) + return instanceForObject(item); + else if (item->parentItem()) + return findNodeInstanceForItem(item->parentItem()); + } + + return ServerNodeInstance(); +} + void Qt5RenderNodeInstanceServer::createScene(const CreateSceneCommand &command) { @@ -144,4 +163,10 @@ void Qt5RenderNodeInstanceServer::completeComponent(const CompleteComponentComma nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(instanceList)); } +void QmlDesigner::Qt5RenderNodeInstanceServer::removeSharedMemory(const QmlDesigner::RemoveSharedMemoryCommand &command) +{ + if (command.typeName() == "Image") + ImageContainer::removeSharedMemorys(command.keyNumbers()); +} + } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.h index 7579435f73..3e342a0de1 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.h @@ -43,9 +43,11 @@ public: void createScene(const CreateSceneCommand &command); void clearScene(const ClearSceneCommand &command); void completeComponent(const CompleteComponentCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); protected: void collectItemChangesAndSendChangeCommands(); + ServerNodeInstance findNodeInstanceForItem(QQuickItem *item) const; private: QSet<ServerNodeInstance> m_dirtyInstanceSet; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/sgitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index 182fe0be81..25c34efb40 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/sgitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -27,14 +27,17 @@ ** ****************************************************************************/ -#include "sgitemnodeinstance.h" +#include "quickitemnodeinstance.h" #include "qt5nodeinstanceserver.h" -#include <QDeclarativeExpression> -#include <QSGView> +#include <QQmlExpression> +#include <QQuickView> #include <cmath> +#include <private/qquicktextinput_p.h> +#include <private/qquicktextedit_p.h> + #include <QHash> #include <QDebug> @@ -42,9 +45,9 @@ namespace QmlDesigner { namespace Internal { -bool SGItemNodeInstance::s_createEffectItem = false; +bool QuickItemNodeInstance::s_createEffectItem = false; -SGItemNodeInstance::SGItemNodeInstance(QSGItem *item) +QuickItemNodeInstance::QuickItemNodeInstance(QQuickItem *item) : ObjectNodeInstance(item), m_hasHeight(false), m_hasWidth(false), @@ -58,22 +61,25 @@ SGItemNodeInstance::SGItemNodeInstance(QSGItem *item) { } -SGItemNodeInstance::~SGItemNodeInstance() +QuickItemNodeInstance::~QuickItemNodeInstance() { - if (sgItem()) - designerSupport()->derefFromEffectItem(sgItem()); + if (quickItem()) + designerSupport()->derefFromEffectItem(quickItem()); } -bool SGItemNodeInstance::hasContent() const +bool QuickItemNodeInstance::hasContent() const { - return m_hasContent; + if (m_hasContent) + return true; + + return childItemsHaveContent(quickItem()); } -QList<ServerNodeInstance> SGItemNodeInstance::childItems() const +QList<ServerNodeInstance> QuickItemNodeInstance::childItems() const { QList<ServerNodeInstance> instanceList; - foreach (QSGItem *childItem, sgItem()->childItems()) + foreach (QQuickItem *childItem, quickItem()->childItems()) { if (childItem && nodeInstanceServer()->hasInstanceForObject(childItem)) { instanceList.append(nodeInstanceServer()->instanceForObject(childItem)); @@ -89,12 +95,12 @@ QList<ServerNodeInstance> SGItemNodeInstance::childItems() const return instanceList; } -QList<ServerNodeInstance> SGItemNodeInstance::childItemsForChild(QSGItem *childItem) const +QList<ServerNodeInstance> QuickItemNodeInstance::childItemsForChild(QQuickItem *childItem) const { QList<ServerNodeInstance> instanceList; if (childItem) { - foreach (QSGItem *childItem, childItem->childItems()) + foreach (QQuickItem *childItem, childItem->childItems()) { if (childItem && nodeInstanceServer()->hasInstanceForObject(childItem)) { instanceList.append(nodeInstanceServer()->instanceForObject(childItem)); @@ -106,18 +112,28 @@ QList<ServerNodeInstance> SGItemNodeInstance::childItemsForChild(QSGItem *childI return instanceList; } -void SGItemNodeInstance::setHasContent(bool hasContent) +void QuickItemNodeInstance::setHasContent(bool hasContent) { m_hasContent = hasContent; } -bool anyItemHasContent(QSGItem *graphicsItem) +bool QuickItemNodeInstance::anyItemHasContent(QQuickItem *quickItem) { - if (graphicsItem->flags().testFlag(QSGItem::ItemHasContents)) + if (quickItem->flags().testFlag(QQuickItem::ItemHasContents)) return true; - foreach (QSGItem *childItem, graphicsItem->childItems()) { + foreach (QQuickItem *childItem, quickItem->childItems()) { + if (anyItemHasContent(childItem)) + return true; + } + + return false; +} + +bool QuickItemNodeInstance::childItemsHaveContent(QQuickItem *quickItem) +{ + foreach (QQuickItem *childItem, quickItem->childItems()) { if (anyItemHasContent(childItem)) return true; } @@ -125,67 +141,76 @@ bool anyItemHasContent(QSGItem *graphicsItem) return false; } -QPointF SGItemNodeInstance::position() const +QPointF QuickItemNodeInstance::position() const { - return sgItem()->pos(); + return quickItem()->pos(); } -QTransform SGItemNodeInstance::transform() const +static QTransform transformForItem(QQuickItem *item, NodeInstanceServer *nodeInstanceServer) { - return DesignerSupport::parentTransform(sgItem()); + QTransform toParentTransform = DesignerSupport::parentTransform(item); + if (item->parentItem() && !nodeInstanceServer->hasInstanceForObject(item->parentItem())) + return transformForItem(item->parentItem(), nodeInstanceServer) * toParentTransform; + + return toParentTransform; } -QTransform SGItemNodeInstance::customTransform() const +QTransform QuickItemNodeInstance::transform() const +{ + return transformForItem(quickItem(), nodeInstanceServer()); +} + +QTransform QuickItemNodeInstance::customTransform() const { return QTransform(); } -QTransform SGItemNodeInstance::sceneTransform() const +QTransform QuickItemNodeInstance::sceneTransform() const { - return DesignerSupport::canvasTransform(sgItem()); + return DesignerSupport::windowTransform(quickItem()); } -double SGItemNodeInstance::rotation() const +double QuickItemNodeInstance::rotation() const { - return sgItem()->rotation(); + return quickItem()->rotation(); } -double SGItemNodeInstance::scale() const +double QuickItemNodeInstance::scale() const { - return sgItem()->scale(); + return quickItem()->scale(); } -QPointF SGItemNodeInstance::transformOriginPoint() const +QPointF QuickItemNodeInstance::transformOriginPoint() const { - return sgItem()->transformOriginPoint(); + return quickItem()->transformOriginPoint(); } -double SGItemNodeInstance::zValue() const +double QuickItemNodeInstance::zValue() const { - return sgItem()->z(); + return quickItem()->z(); } -double SGItemNodeInstance::opacity() const +double QuickItemNodeInstance::opacity() const { - return sgItem()->opacity(); + return quickItem()->opacity(); } -QObject *SGItemNodeInstance::parent() const +QObject *QuickItemNodeInstance::parent() const { - if (!sgItem() || !sgItem()->parentItem()) + if (!quickItem() || !quickItem()->parentItem()) return 0; - return sgItem()->parentItem(); + return quickItem()->parentItem(); } -bool SGItemNodeInstance::equalSGItem(QSGItem *item) const +bool QuickItemNodeInstance::equalQuickItem(QQuickItem *item) const { - return item == sgItem(); + return item == quickItem(); } -void SGItemNodeInstance::updateDirtyNodeRecursive(QSGItem *parentItem) const +void QuickItemNodeInstance::updateDirtyNodeRecursive(QQuickItem *parentItem) const { - foreach (QSGItem *childItem, parentItem->childItems()) { + foreach (QQuickItem *childItem, parentItem->childItems()) { if (!nodeInstanceServer()->hasInstanceForObject(childItem)) updateDirtyNodeRecursive(childItem); } @@ -193,86 +218,102 @@ void SGItemNodeInstance::updateDirtyNodeRecursive(QSGItem *parentItem) const DesignerSupport::updateDirtyNode(parentItem); } -QImage SGItemNodeInstance::renderImage() const +QImage QuickItemNodeInstance::renderImage() const { - updateDirtyNodeRecursive(sgItem()); + updateDirtyNodeRecursive(quickItem()); - QRectF boundingRect = boundingRectWithStepChilds(sgItem()); + QRectF boundingRect = boundingRectWithStepChilds(quickItem()); - QImage renderImage = designerSupport()->renderImageForItem(sgItem(), boundingRect, boundingRect.size().toSize()); + QImage renderImage = designerSupport()->renderImageForItem(quickItem(), boundingRect, boundingRect.size().toSize()); renderImage = renderImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); return renderImage; } -bool SGItemNodeInstance::isMovable() const +bool QuickItemNodeInstance::isMovable() const { if (isRootNodeInstance()) return false; - return m_isMovable && sgItem() && sgItem()->parentItem(); + return m_isMovable && quickItem() && quickItem()->parentItem(); } -void SGItemNodeInstance::setMovable(bool movable) +void QuickItemNodeInstance::setMovable(bool movable) { m_isMovable = movable; } -SGItemNodeInstance::Pointer SGItemNodeInstance::create(QObject *object) +QuickItemNodeInstance::Pointer QuickItemNodeInstance::create(QObject *object) { - QSGItem *sgItem = qobject_cast<QSGItem*>(object); + QQuickItem *quickItem = qobject_cast<QQuickItem*>(object); - Q_ASSERT(sgItem); + Q_ASSERT(quickItem); - Pointer instance(new SGItemNodeInstance(sgItem)); + Pointer instance(new QuickItemNodeInstance(quickItem)); - instance->setHasContent(anyItemHasContent(sgItem)); - sgItem->setFlag(QSGItem::ItemHasContents, true); + instance->setHasContent(anyItemHasContent(quickItem)); + quickItem->setFlag(QQuickItem::ItemHasContents, true); - static_cast<QDeclarativeParserStatus*>(sgItem)->classBegin(); + static_cast<QQmlParserStatus*>(quickItem)->classBegin(); instance->populateResetHashes(); return instance; } -void SGItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance) +static void disableTextCursor(QQuickItem *item) { + foreach (QQuickItem *childItem, item->childItems()) + disableTextCursor(childItem); + + QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(item); + if (textInput) + textInput->setCursorVisible(false); + + QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(item); + if (textEdit) + textEdit->setCursorVisible(false); +} + +void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance) +{ + disableTextCursor(quickItem()); + if (instanceId() == 0) { - DesignerSupport::setRootItem(nodeInstanceServer()->sgView(), sgItem()); + DesignerSupport::setRootItem(nodeInstanceServer()->quickView(), quickItem()); } else { - sgItem()->setParentItem(qobject_cast<QSGItem*>(nodeInstanceServer()->sgView()->rootObject())); + quickItem()->setParentItem(qobject_cast<QQuickItem*>(nodeInstanceServer()->quickView()->rootObject())); } if (s_createEffectItem || instanceId() == 0) - designerSupport()->refFromEffectItem(sgItem()); + designerSupport()->refFromEffectItem(quickItem()); ObjectNodeInstance::initialize(objectNodeInstance); - sgItem()->update(); + quickItem()->update(); } -bool SGItemNodeInstance::isSGItem() const +bool QuickItemNodeInstance::isQuickItem() const { return true; } -QSizeF SGItemNodeInstance::size() const +QSizeF QuickItemNodeInstance::size() const { double width; - if (DesignerSupport::isValidWidth(sgItem())) { - width = sgItem()->width(); + if (DesignerSupport::isValidWidth(quickItem())) { + width = quickItem()->width(); } else { - width = sgItem()->implicitWidth(); + width = quickItem()->implicitWidth(); } double height; - if (DesignerSupport::isValidHeight(sgItem())) { - height = sgItem()->height(); + if (DesignerSupport::isValidHeight(quickItem())) { + height = quickItem()->height(); } else { - height = sgItem()->implicitHeight(); + height = quickItem()->implicitHeight(); } @@ -284,11 +325,11 @@ static inline bool isRectangleSane(const QRectF &rect) return rect.isValid() && (rect.width() < 10000) && (rect.height() < 10000); } -QRectF SGItemNodeInstance::boundingRectWithStepChilds(QSGItem *parentItem) const +QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem) const { QRectF boundingRect = parentItem->boundingRect(); - foreach (QSGItem *childItem, parentItem->childItems()) { + foreach (QQuickItem *childItem, parentItem->childItems()) { if (!nodeInstanceServer()->hasInstanceForObject(childItem)) { QRectF transformedRect = childItem->mapRectToItem(parentItem, boundingRectWithStepChilds(childItem)); if (isRectangleSane(transformedRect)) @@ -299,20 +340,20 @@ QRectF SGItemNodeInstance::boundingRectWithStepChilds(QSGItem *parentItem) const return boundingRect; } -QRectF SGItemNodeInstance::boundingRect() const +QRectF QuickItemNodeInstance::boundingRect() const { - if (sgItem()) { - if (sgItem()->clip()) { - return sgItem()->boundingRect(); + if (quickItem()) { + if (quickItem()->clip()) { + return quickItem()->boundingRect(); } else { - return boundingRectWithStepChilds(sgItem()); + return boundingRectWithStepChilds(quickItem()); } } return QRectF(); } -void SGItemNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) +void QuickItemNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) { if (name == "state") return; // states are only set by us @@ -341,48 +382,60 @@ void SGItemNodeInstance::setPropertyVariant(const QString &name, const QVariant ObjectNodeInstance::setPropertyVariant(name, value); + quickItem()->update(); + refresh(); + + if (isInPositioner()) + parentInstance()->refreshPositioner(); } -void SGItemNodeInstance::setPropertyBinding(const QString &name, const QString &expression) +void QuickItemNodeInstance::setPropertyBinding(const QString &name, const QString &expression) { if (name == "state") return; // states are only set by us ObjectNodeInstance::setPropertyBinding(name, expression); + + quickItem()->update(); + + refresh(); + + if (isInPositioner()) + parentInstance()->refreshPositioner(); } -QVariant SGItemNodeInstance::property(const QString &name) const +QVariant QuickItemNodeInstance::property(const QString &name) const { return ObjectNodeInstance::property(name); } -void SGItemNodeInstance::resetHorizontal() +void QuickItemNodeInstance::resetHorizontal() { setPropertyVariant("x", m_x); if (m_width > 0.0) { setPropertyVariant("width", m_width); } else { - setPropertyVariant("width", sgItem()->implicitWidth()); + setPropertyVariant("width", quickItem()->implicitWidth()); } } -void SGItemNodeInstance::resetVertical() +void QuickItemNodeInstance::resetVertical() { setPropertyVariant("y", m_y); if (m_height > 0.0) { setPropertyVariant("height", m_height); } else { - setPropertyVariant("height", sgItem()->implicitWidth()); + setPropertyVariant("height", quickItem()->implicitWidth()); } } -static void repositioning(QSGItem *item) +static void repositioning(QQuickItem *item) { if (!item) return; -// QDeclarativeBasePositioner *positioner = qobject_cast<QDeclarativeBasePositioner*>(item); +// QQmlBasePositioner *positioner = qobject_cast<QQmlBasePositioner*>(item); // if (positioner) // positioner->rePositioning(); @@ -390,41 +443,50 @@ static void repositioning(QSGItem *item) repositioning(item->parentItem()); } -void SGItemNodeInstance::refresh() +void QuickItemNodeInstance::refresh() { - repositioning(sgItem()); + repositioning(quickItem()); } -void SGItemNodeInstance::doComponentComplete() +void doComponentCompleteRecursive(QQuickItem *item) { - if (sgItem()) { - if (DesignerSupport::isComponentComplete(sgItem())) + if (item) { + if (DesignerSupport::isComponentComplete(item)) return; - static_cast<QDeclarativeParserStatus*>(sgItem())->componentComplete(); + + foreach (QQuickItem *childItem, item->childItems()) + doComponentCompleteRecursive(childItem); + + static_cast<QQmlParserStatus*>(item)->componentComplete(); } +} + +void QuickItemNodeInstance::doComponentComplete() +{ + doComponentCompleteRecursive(quickItem()); - sgItem()->update(); + quickItem()->update(); } -bool SGItemNodeInstance::isResizable() const +bool QuickItemNodeInstance::isResizable() const { if (isRootNodeInstance()) return false; - return m_isResizable && sgItem() && sgItem()->parentItem(); + return m_isResizable && quickItem() && quickItem()->parentItem(); } -void SGItemNodeInstance::setResizable(bool resizeable) +void QuickItemNodeInstance::setResizable(bool resizeable) { m_isResizable = resizeable; } -int SGItemNodeInstance::penWidth() const +int QuickItemNodeInstance::penWidth() const { - return DesignerSupport::borderWidth(sgItem()); + return DesignerSupport::borderWidth(quickItem()); } -void SGItemNodeInstance::resetProperty(const QString &name) +void QuickItemNodeInstance::resetProperty(const QString &name) { if (name == "height") { m_hasHeight = false; @@ -442,7 +504,7 @@ void SGItemNodeInstance::resetProperty(const QString &name) if (name == "y") m_y = 0.0; - DesignerSupport::resetAnchor(sgItem(), name); + DesignerSupport::resetAnchor(quickItem(), name); if (name == "anchors.fill") { resetHorizontal(); @@ -467,9 +529,14 @@ void SGItemNodeInstance::resetProperty(const QString &name) } ObjectNodeInstance::resetProperty(name); + + quickItem()->update(); + + if (isInPositioner()) + parentInstance()->refreshPositioner(); } -void SGItemNodeInstance::reparent(const ObjectNodeInstance::Pointer &oldParentInstance, const QString &oldParentProperty, const ObjectNodeInstance::Pointer &newParentInstance, const QString &newParentProperty) +void QuickItemNodeInstance::reparent(const ObjectNodeInstance::Pointer &oldParentInstance, const QString &oldParentProperty, const ObjectNodeInstance::Pointer &newParentInstance, const QString &newParentProperty) { if (oldParentInstance && oldParentInstance->isPositioner()) { setInPositioner(false); @@ -492,7 +559,10 @@ void SGItemNodeInstance::reparent(const ObjectNodeInstance::Pointer &oldParentIn } refresh(); - DesignerSupport::updateDirtyNode(sgItem()); + DesignerSupport::updateDirtyNode(quickItem()); + + if (parentInstance() && isInPositioner()) + parentInstance()->refreshPositioner(); } static bool isValidAnchorName(const QString &name) @@ -510,17 +580,17 @@ static bool isValidAnchorName(const QString &name) return anchorNameList.contains(name); } -bool SGItemNodeInstance::hasAnchor(const QString &name) const +bool QuickItemNodeInstance::hasAnchor(const QString &name) const { - return DesignerSupport::hasAnchor(sgItem(), name); + return DesignerSupport::hasAnchor(quickItem(), name); } -QPair<QString, ServerNodeInstance> SGItemNodeInstance::anchor(const QString &name) const +QPair<QString, ServerNodeInstance> QuickItemNodeInstance::anchor(const QString &name) const { - if (!isValidAnchorName(name) || !DesignerSupport::hasAnchor(sgItem(), name)) + if (!isValidAnchorName(name) || !DesignerSupport::hasAnchor(quickItem(), name)) return ObjectNodeInstance::anchor(name); - QPair<QString, QObject*> nameObjectPair = DesignerSupport::anchorLineTarget(sgItem(), name, context()); + QPair<QString, QObject*> nameObjectPair = DesignerSupport::anchorLineTarget(quickItem(), name, context()); QObject *targetObject = nameObjectPair.second; QString targetName = nameObjectPair.first; @@ -532,10 +602,10 @@ QPair<QString, ServerNodeInstance> SGItemNodeInstance::anchor(const QString &nam } } -QList<ServerNodeInstance> SGItemNodeInstance::stateInstances() const +QList<ServerNodeInstance> QuickItemNodeInstance::stateInstances() const { QList<ServerNodeInstance> instanceList; - QList<QObject*> stateList = DesignerSupport::statesForItem(sgItem()); + QList<QObject*> stateList = DesignerSupport::statesForItem(quickItem()); foreach (QObject *state, stateList) { if (state && nodeInstanceServer()->hasInstanceForObject(state)) @@ -545,12 +615,12 @@ QList<ServerNodeInstance> SGItemNodeInstance::stateInstances() const return instanceList; } -bool SGItemNodeInstance::isAnchoredBySibling() const +bool QuickItemNodeInstance::isAnchoredBySibling() const { - if (sgItem()->parentItem()) { - foreach (QSGItem *siblingItem, sgItem()->parentItem()->childItems()) { // search in siblings for a anchor to this item + if (quickItem()->parentItem()) { + foreach (QQuickItem *siblingItem, quickItem()->parentItem()->childItems()) { // search in siblings for a anchor to this item if (siblingItem) { - if (DesignerSupport::isAnchoredTo(siblingItem, sgItem())) + if (DesignerSupport::isAnchoredTo(siblingItem, quickItem())) return true; } } @@ -559,34 +629,34 @@ bool SGItemNodeInstance::isAnchoredBySibling() const return false; } -bool SGItemNodeInstance::isAnchoredByChildren() const +bool QuickItemNodeInstance::isAnchoredByChildren() const { - if (DesignerSupport::areChildrenAnchoredTo(sgItem(), sgItem())) // search in children for a anchor to this item + if (DesignerSupport::areChildrenAnchoredTo(quickItem(), quickItem())) // search in children for a anchor to this item return true; return false; } -QSGItem *SGItemNodeInstance::sgItem() const +QQuickItem *QuickItemNodeInstance::quickItem() const { if (object() == 0) return 0; - Q_ASSERT(qobject_cast<QSGItem*>(object())); - return static_cast<QSGItem*>(object()); + Q_ASSERT(qobject_cast<QQuickItem*>(object())); + return static_cast<QQuickItem*>(object()); } -DesignerSupport *SGItemNodeInstance::designerSupport() const +DesignerSupport *QuickItemNodeInstance::designerSupport() const { return qt5NodeInstanceServer()->designerSupport(); } -Qt5NodeInstanceServer *SGItemNodeInstance::qt5NodeInstanceServer() const +Qt5NodeInstanceServer *QuickItemNodeInstance::qt5NodeInstanceServer() const { return qobject_cast<Qt5NodeInstanceServer*>(nodeInstanceServer()); } -void SGItemNodeInstance::createEffectItem(bool createEffectItem) +void QuickItemNodeInstance::createEffectItem(bool createEffectItem) { s_createEffectItem = createEffectItem; } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/sgitemnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h index 0700f42d8a..b366219230 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/sgitemnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h @@ -27,31 +27,31 @@ ** ****************************************************************************/ -#ifndef SGITEMNODEINSTANCE_H -#define SGITEMNODEINSTANCE_H +#ifndef QuickITEMNODEINSTANCE_H +#define QuickITEMNODEINSTANCE_H #include <QtGlobal> #include "objectnodeinstance.h" -#include <QSGItem> +#include <QQuickItem> #include <designersupport.h> namespace QmlDesigner { namespace Internal { -class SGItemNodeInstance : public ObjectNodeInstance +class QuickItemNodeInstance : public ObjectNodeInstance { public: - typedef QSharedPointer<SGItemNodeInstance> Pointer; - typedef QWeakPointer<SGItemNodeInstance> WeakPointer; + typedef QSharedPointer<QuickItemNodeInstance> Pointer; + typedef QWeakPointer<QuickItemNodeInstance> WeakPointer; - ~SGItemNodeInstance(); + ~QuickItemNodeInstance(); static Pointer create(QObject *objectToBeWrapped); void initialize(const ObjectNodeInstance::Pointer &objectNodeInstance); - bool isSGItem() const; + bool isQuickItem() const; QRectF boundingRect() const; QPointF position() const; @@ -68,12 +68,12 @@ public: QPointF transformOriginPoint() const; double zValue() const; - bool equalSGItem(QSGItem *item) const; + bool equalQuickItem(QQuickItem *item) const; bool hasContent() const; QList<ServerNodeInstance> childItems() const; - QList<ServerNodeInstance> childItemsForChild(QSGItem *childItem) const; + QList<ServerNodeInstance> childItemsForChild(QQuickItem *childItem) const; bool isMovable() const; void setMovable(bool movable); @@ -109,13 +109,15 @@ public: static void createEffectItem(bool createEffectItem); protected: - SGItemNodeInstance(QSGItem*); - QSGItem *sgItem() const; + QuickItemNodeInstance(QQuickItem*); + QQuickItem *quickItem() const; void resetHorizontal(); void resetVertical(); void refresh(); - QRectF boundingRectWithStepChilds(QSGItem *parentItem) const; - void updateDirtyNodeRecursive(QSGItem *parentItem) const; + QRectF boundingRectWithStepChilds(QQuickItem *parentItem) const; + void updateDirtyNodeRecursive(QQuickItem *parentItem) const; + static bool anyItemHasContent(QQuickItem *graphicsItem); + static bool childItemsHaveContent(QQuickItem *graphicsItem); private: //variables bool m_hasHeight; @@ -133,5 +135,5 @@ private: //variables } // namespace Internal } // namespace QmlDesigner -#endif // SGITEMNODEINSTANCE_H +#endif // QuickITEMNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp new file mode 100644 index 0000000000..c249a10121 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp @@ -0,0 +1,639 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "servernodeinstance.h" + +#include "objectnodeinstance.h" +#include "dummynodeinstance.h" +#include "componentnodeinstance.h" +#include "qmltransitionnodeinstance.h" +#include "qmlpropertychangesnodeinstance.h" +#include "behaviornodeinstance.h" +#include "qmlstatenodeinstance.h" +#include "anchorchangesnodeinstance.h" +#include "positionernodeinstance.h" +#include "debugoutputcommand.h" + +#include "quickitemnodeinstance.h" + +#include "nodeinstanceserver.h" +#include "instancecontainer.h" + +#include <QHash> +#include <QSet> +#include <QDebug> +#include <QQuickItem> +#include <private/qqmlengine_p.h> + +#include <QQmlEngine> + +/*! + \class QmlDesigner::NodeInstance + \ingroup CoreInstance + \brief NodeInstance is a common handle for the actual object representation of a ModelNode. + + NodeInstance abstracts away the differences e.g. in terms of position and size + for QWidget, QGraphicsView, QLayout etc objects. Multiple NodeInstance objects can share + the pointer to the same instance object. The actual instance will be deleted when + the last NodeInstance object referencing to it is deleted. This can be disabled by + setDeleteHeldInstance(). + + \see QmlDesigner::NodeInstanceView +*/ + +namespace QmlDesigner { + +/*! +\brief Constructor - creates a invalid NodeInstance + + +\see NodeInstanceView +*/ +ServerNodeInstance::ServerNodeInstance() +{ +} + +/*! +\brief Destructor + +*/ +ServerNodeInstance::~ServerNodeInstance() +{ +} + +/*! +\brief Constructor - creates a valid NodeInstance + +*/ +ServerNodeInstance::ServerNodeInstance(const Internal::ObjectNodeInstance::Pointer &abstractInstance) + : m_nodeInstance(abstractInstance) +{ + +} + + +ServerNodeInstance::ServerNodeInstance(const ServerNodeInstance &other) + : m_nodeInstance(other.m_nodeInstance) +{ +} + +ServerNodeInstance &ServerNodeInstance::operator=(const ServerNodeInstance &other) +{ + m_nodeInstance = other.m_nodeInstance; + return *this; +} + +/*! +\brief Paints the NodeInstance with this painter. +\param painter used QPainter +*/ +void ServerNodeInstance::paint(QPainter *painter) +{ + m_nodeInstance->paint(painter); +} + +QImage ServerNodeInstance::renderImage() const +{ + return m_nodeInstance->renderImage(); +} + +bool ServerNodeInstance::isRootNodeInstance() const +{ + return isValid() && m_nodeInstance->isRootNodeInstance(); +} + +bool ServerNodeInstance::isSubclassOf(QObject *object, const QByteArray &superTypeName) +{ + if (object == 0) + return false; + + const QMetaObject *metaObject = object->metaObject(); + + while (metaObject) { + QQmlType *qmlType = QQmlMetaType::qmlType(metaObject); + if (qmlType && qmlType->qmlTypeName() == superTypeName) // ignore version numbers + return true; + + if (metaObject->className() == superTypeName) + return true; + + metaObject = metaObject->superClass(); + } + + return false; +} + +void ServerNodeInstance::setNodeSource(const QString &source) +{ + m_nodeInstance->setNodeSource(source); +} + +bool ServerNodeInstance::isSubclassOf(const QString &superTypeName) const +{ + return isSubclassOf(internalObject(), superTypeName.toUtf8()); +} + +/*! +\brief Creates a new NodeInstace for this NodeMetaInfo + +\param metaInfo MetaInfo for which a Instance should be created +\param context QQmlContext which should be used +\returns Internal Pointer of a NodeInstance +\see NodeMetaInfo +*/ +Internal::ObjectNodeInstance::Pointer ServerNodeInstance::createInstance(QObject *objectToBeWrapped) +{ + Internal::ObjectNodeInstance::Pointer instance; + + if (objectToBeWrapped == 0) + instance = Internal::DummyNodeInstance::create(); + else if (isSubclassOf(objectToBeWrapped, "QQuickBasePositioner")) + instance = Internal::PositionerNodeInstance::create(objectToBeWrapped); + else if (isSubclassOf(objectToBeWrapped, "QQuickItem")) + instance = Internal::QuickItemNodeInstance::create(objectToBeWrapped); + else if (isSubclassOf(objectToBeWrapped, "QQmlComponent")) + instance = Internal::ComponentNodeInstance::create(objectToBeWrapped); + else if (objectToBeWrapped->inherits("QQmlAnchorChanges")) + instance = Internal::AnchorChangesNodeInstance::create(objectToBeWrapped); + else if (isSubclassOf(objectToBeWrapped, "QQuickPropertyChanges")) + instance = Internal::QmlPropertyChangesNodeInstance::create(objectToBeWrapped); + else if (isSubclassOf(objectToBeWrapped, "QQuickState")) + instance = Internal::QmlStateNodeInstance::create(objectToBeWrapped); + else if (isSubclassOf(objectToBeWrapped, "QQuickTransition")) + instance = Internal::QmlTransitionNodeInstance::create(objectToBeWrapped); + else if (isSubclassOf(objectToBeWrapped, "QQuickBehavior")) + instance = Internal::BehaviorNodeInstance::create(objectToBeWrapped); + else if (isSubclassOf(objectToBeWrapped, "QObject")) + instance = Internal::ObjectNodeInstance::create(objectToBeWrapped); + else + instance = Internal::DummyNodeInstance::create(); + + + return instance; +} + +ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceServer, const InstanceContainer &instanceContainer, ComponentWrap componentWrap) +{ + Q_ASSERT(instanceContainer.instanceId() != -1); + Q_ASSERT(nodeInstanceServer); + + QObject *object = 0; + if (componentWrap == WrapAsComponent) { + object = Internal::ObjectNodeInstance::createComponentWrap(instanceContainer.nodeSource(), nodeInstanceServer->imports(), nodeInstanceServer->context()); + } else if (!instanceContainer.nodeSource().isEmpty()) { + object = Internal::ObjectNodeInstance::createCustomParserObject(instanceContainer.nodeSource(), nodeInstanceServer->imports(), nodeInstanceServer->context()); + if (object == 0) + nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QLatin1String("Custom parser object could not be created.")); + } else if (!instanceContainer.componentPath().isEmpty()) { + object = Internal::ObjectNodeInstance::createComponent(instanceContainer.componentPath(), nodeInstanceServer->context()); + if (object == 0) + nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QString("Component with path %1 could not be created.").arg(instanceContainer.componentPath())); + } else { + object = Internal::ObjectNodeInstance::createPrimitive(instanceContainer.type(), instanceContainer.majorNumber(), instanceContainer.minorNumber(), nodeInstanceServer->context()); + if (object == 0) + nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QLatin1String("Item could not be created.")); + } + + if (object == 0) { + if (instanceContainer.metaType() == InstanceContainer::ItemMetaType) { //If we cannot instanciate the object but we know it has to be an Ttem, we create an Item instead. + object = Internal::ObjectNodeInstance::createPrimitive("QtQuick/Item", 2, 0, nodeInstanceServer->context()); + + if (object == 0) + object = new QQuickItem; + } else { + object = new QObject; + } + } + + + QQmlEnginePrivate::get(nodeInstanceServer->engine())->cache(object->metaObject()); + + ServerNodeInstance instance(createInstance(object)); + + instance.internalInstance()->setNodeInstanceServer(nodeInstanceServer); + + instance.internalInstance()->setInstanceId(instanceContainer.instanceId()); + + instance.internalInstance()->initialize(instance.m_nodeInstance); + + //QObject::connect(instance.internalObject(), SIGNAL(destroyed(QObject*)), nodeInstanceView, SLOT(removeIdFromContext(QObject*))); + + return instance; +} + +void ServerNodeInstance::reparent(const ServerNodeInstance &oldParentInstance, const QString &oldParentProperty, const ServerNodeInstance &newParentInstance, const QString &newParentProperty) +{ + m_nodeInstance->reparent(oldParentInstance.m_nodeInstance, oldParentProperty, newParentInstance.m_nodeInstance, newParentProperty); +} + +/*! +\brief Returns the parent NodeInstance of this NodeInstance. + + If there is not parent than the parent is invalid. + +\returns Parent NodeInstance. +*/ +ServerNodeInstance ServerNodeInstance::parent() const +{ + return m_nodeInstance->parentInstance(); +} + +bool ServerNodeInstance::hasParent() const +{ + return m_nodeInstance->parent(); +} + +bool ServerNodeInstance::isValid() const +{ + return m_nodeInstance && m_nodeInstance->isValid(); +} + + +/*! +\brief Returns if the NodeInstance is a QGraphicsItem. +\returns true if this NodeInstance is a QGraphicsItem +*/ +bool ServerNodeInstance::equalGraphicsItem(QGraphicsItem *item) const +{ + return m_nodeInstance->equalGraphicsItem(item); +} + +/*! +\brief Returns the bounding rect of the NodeInstance. +\returns QRectF of the NodeInstance +*/ +QRectF ServerNodeInstance::boundingRect() const +{ + QRectF boundingRect(m_nodeInstance->boundingRect()); + +// +// if (modelNode().isValid()) { // TODO implement recursiv stuff +// if (qFuzzyIsNull(boundingRect.width())) +// boundingRect.setWidth(nodeState().property("width").value().toDouble()); +// +// if (qFuzzyIsNull(boundingRect.height())) +// boundingRect.setHeight(nodeState().property("height").value().toDouble()); +// } + + return boundingRect; +} + +void ServerNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) +{ + m_nodeInstance->setPropertyVariant(name, value); + +} + +void ServerNodeInstance::setPropertyDynamicVariant(const QString &name, const QString &typeName, const QVariant &value) +{ + m_nodeInstance->createDynamicProperty(name, typeName); + m_nodeInstance->setPropertyVariant(name, value); +} + +void ServerNodeInstance::setPropertyBinding(const QString &name, const QString &expression) +{ + m_nodeInstance->setPropertyBinding(name, expression); +} + +void ServerNodeInstance::setPropertyDynamicBinding(const QString &name, const QString &typeName, const QString &expression) +{ + m_nodeInstance->createDynamicProperty(name, typeName); + m_nodeInstance->setPropertyBinding(name, expression); +} + +void ServerNodeInstance::resetProperty(const QString &name) +{ + m_nodeInstance->resetProperty(name); +} + +void ServerNodeInstance::refreshProperty(const QString &name) +{ + m_nodeInstance->refreshProperty(name); +} + +void ServerNodeInstance::setId(const QString &id) +{ + m_nodeInstance->setId(id); +} + +/*! +\brief Returns the property value of the property of this NodeInstance. +\returns QVariant value +*/ +QVariant ServerNodeInstance::property(const QString &name) const +{ + return m_nodeInstance->property(name); +} + +QStringList ServerNodeInstance::propertyNames() const +{ + return m_nodeInstance->propertyNames(); +} + +bool ServerNodeInstance::hasBindingForProperty(const QString &name, bool *hasChanged) const +{ + return m_nodeInstance->hasBindingForProperty(name, hasChanged); +} + +/*! +\brief Returns the property default value of the property of this NodeInstance. +\returns QVariant default value which is the reset value to +*/ +QVariant ServerNodeInstance::defaultValue(const QString &name) const +{ + return m_nodeInstance->resetValue(name); +} + +/*! +\brief Returns the type of the property of this NodeInstance. +*/ +QString ServerNodeInstance::instanceType(const QString &name) const +{ + return m_nodeInstance->instanceType(name); +} + +void ServerNodeInstance::makeInvalid() +{ + if (m_nodeInstance) + m_nodeInstance->destroy(); + m_nodeInstance.clear(); +} + +bool ServerNodeInstance::hasContent() const +{ + return m_nodeInstance->hasContent(); +} + +bool ServerNodeInstance::isResizable() const +{ + return m_nodeInstance->isResizable(); +} + +bool ServerNodeInstance::isMovable() const +{ + return m_nodeInstance->isMovable(); +} + +bool ServerNodeInstance::isInPositioner() const +{ + return m_nodeInstance->isInPositioner(); +} + +bool ServerNodeInstance::hasAnchor(const QString &name) const +{ + return m_nodeInstance->hasAnchor(name); +} + +int ServerNodeInstance::penWidth() const +{ + return m_nodeInstance->penWidth(); +} + +bool ServerNodeInstance::isAnchoredBySibling() const +{ + return m_nodeInstance->isAnchoredBySibling(); +} + +bool ServerNodeInstance::isAnchoredByChildren() const +{ + return m_nodeInstance->isAnchoredByChildren(); +} + +QPair<QString, ServerNodeInstance> ServerNodeInstance::anchor(const QString &name) const +{ + return m_nodeInstance->anchor(name); +} + +QDebug operator<<(QDebug debug, const ServerNodeInstance &instance) +{ + if (instance.isValid()) { + debug.nospace() << "ServerNodeInstance(" + << instance.instanceId() << ", " + << instance.internalObject() << ", " + << instance.id() << ", " + << instance.parent() << ')'; + } else { + debug.nospace() << "ServerNodeInstance(invalid)"; + } + + return debug.space(); +} + +uint qHash(const ServerNodeInstance &instance) +{ + return ::qHash(instance.instanceId()); +} + +bool operator==(const ServerNodeInstance &first, const ServerNodeInstance &second) +{ + return first.instanceId() == second.instanceId(); +} + +bool ServerNodeInstance::isWrappingThisObject(QObject *object) const +{ + return internalObject() && internalObject() == object; +} + +/*! +\brief Returns the position in parent coordiantes. +\returns QPointF of the position of the instance. +*/ +QPointF ServerNodeInstance::position() const +{ + return m_nodeInstance->position(); +} + +/*! +\brief Returns the size in local coordiantes. +\returns QSizeF of the size of the instance. +*/ +QSizeF ServerNodeInstance::size() const +{ + QSizeF instanceSize = m_nodeInstance->size(); + + return instanceSize; +} + +QTransform ServerNodeInstance::transform() const +{ + return m_nodeInstance->transform(); +} + +/*! +\brief Returns the transform matrix of the instance. +\returns QTransform of the instance. +*/ +QTransform ServerNodeInstance::customTransform() const +{ + return m_nodeInstance->customTransform(); +} + +QTransform ServerNodeInstance::sceneTransform() const +{ + return m_nodeInstance->sceneTransform(); +} + +double ServerNodeInstance::rotation() const +{ + return m_nodeInstance->rotation(); +} + +double ServerNodeInstance::scale() const +{ + return m_nodeInstance->scale(); +} + +QList<QGraphicsTransform *> ServerNodeInstance::transformations() const +{ + return m_nodeInstance->transformations(); +} + +QPointF ServerNodeInstance::transformOriginPoint() const +{ + return m_nodeInstance->transformOriginPoint(); +} + +double ServerNodeInstance::zValue() const +{ + return m_nodeInstance->zValue(); +} + +/*! +\brief Returns the opacity of the instance. +\returns 0.0 mean transparent and 1.0 opaque. +*/ +double ServerNodeInstance::opacity() const +{ + return m_nodeInstance->opacity(); +} + + +void ServerNodeInstance::setDeleteHeldInstance(bool deleteInstance) +{ + m_nodeInstance->setDeleteHeldInstance(deleteInstance); +} + + +void ServerNodeInstance::paintUpdate() +{ + m_nodeInstance->paintUpdate(); +} + +QObject *ServerNodeInstance::internalObject() const +{ + if (m_nodeInstance.isNull()) + return 0; + + return m_nodeInstance->object(); +} + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +QQuickItem *ServerNodeInstance::internalSGItem() const +{ + return qobject_cast<QQuickItem*>(internalObject()); +} +#endif + +void ServerNodeInstance::activateState() +{ + m_nodeInstance->activateState(); +} + +void ServerNodeInstance::deactivateState() +{ + m_nodeInstance->deactivateState(); +} + +bool ServerNodeInstance::updateStateVariant(const ServerNodeInstance &target, const QString &propertyName, const QVariant &value) +{ + return m_nodeInstance->updateStateVariant(target.internalInstance(), propertyName, value); +} + +bool ServerNodeInstance::updateStateBinding(const ServerNodeInstance &target, const QString &propertyName, const QString &expression) +{ + return m_nodeInstance->updateStateBinding(target.internalInstance(), propertyName, expression); +} + +QVariant ServerNodeInstance::resetVariant(const QString &propertyName) const +{ + return m_nodeInstance->resetValue(propertyName); +} + +bool ServerNodeInstance::resetStateProperty(const ServerNodeInstance &target, const QString &propertyName, const QVariant &resetValue) +{ + return m_nodeInstance->resetStateProperty(target.internalInstance(), propertyName, resetValue); +} + +/*! + Makes types used in node instances known to the Qml engine. To be called once at initialization time. +*/ +void ServerNodeInstance::registerQmlTypes() +{ +// qmlRegisterType<QmlDesigner::Internal::QmlPropertyChangesObject>(); +} + +void ServerNodeInstance::doComponentComplete() +{ + m_nodeInstance->doComponentComplete(); +} + +QList<ServerNodeInstance> ServerNodeInstance::childItems() const +{ + return m_nodeInstance->childItems(); +} + +QString ServerNodeInstance::id() const +{ + return m_nodeInstance->id(); +} + +qint32 ServerNodeInstance::instanceId() const +{ + if (isValid()) { + return m_nodeInstance->instanceId(); + } else { + return -1; + } +} + +QObject* ServerNodeInstance::testHandle() const +{ + return internalObject(); +} + +QList<ServerNodeInstance> ServerNodeInstance::stateInstances() const +{ + return m_nodeInstance->stateInstances(); +} + +Internal::ObjectNodeInstance::Pointer ServerNodeInstance::internalInstance() const +{ + return m_nodeInstance; +} + +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h new file mode 100644 index 0000000000..cb5635cb44 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h @@ -0,0 +1,216 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef SERVERNODEINSTANCE_H +#define SERVERNODEINSTANCE_H + +#include <QSharedPointer> +#include <QHash> +#include <QRectF> + +#include <nodeinstanceserverinterface.h> +#include <propertyvaluecontainer.h> + +QT_BEGIN_NAMESPACE +class QPainter; +class QStyleOptionGraphicsItem; +class QQmlContext; +class QGraphicsItem; +class QGraphicsTransform; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +class QQuickItem; +#endif +QT_END_NAMESPACE + +namespace QmlDesigner { + +class NodeInstanceServer; +class Qt4NodeInstanceServer; +class Qt4PreviewNodeInstanceServer; +class Qt5NodeInstanceServer; +class Qt5PreviewNodeInstanceServer; +class InstanceContainer; + +namespace Internal { + class ObjectNodeInstance; + class QmlGraphicsItemNodeInstance; + class QmlPropertyChangesNodeInstance; + class GraphicsObjectNodeInstance; + class QmlStateNodeInstance; + class QuickItemNodeInstance; +} + +class ServerNodeInstance +{ + friend class NodeInstanceServer; + friend class Qt4NodeInstanceServer; + friend class Qt4PreviewNodeInstanceServer; + friend class Qt5NodeInstanceServer; + friend class Qt5PreviewNodeInstanceServer; + friend class QHash<qint32, ServerNodeInstance>; + friend uint qHash(const ServerNodeInstance &instance); + friend bool operator==(const ServerNodeInstance &first, const ServerNodeInstance &second); + friend QDebug operator<<(QDebug debug, const ServerNodeInstance &instance); + friend class NodeMetaInfo; + friend class QmlDesigner::Internal::QmlGraphicsItemNodeInstance; + friend class QmlDesigner::Internal::QuickItemNodeInstance; + friend class QmlDesigner::Internal::GraphicsObjectNodeInstance; + friend class QmlDesigner::Internal::ObjectNodeInstance; + friend class QmlDesigner::Internal::QmlPropertyChangesNodeInstance; + friend class QmlDesigner::Internal::QmlStateNodeInstance; + +public: + enum ComponentWrap { + WrapAsComponent, + DoNotWrapAsComponent + }; + + ServerNodeInstance(); + ~ServerNodeInstance(); + ServerNodeInstance(const ServerNodeInstance &other); + ServerNodeInstance& operator=(const ServerNodeInstance &other); + + void paint(QPainter *painter); + QImage renderImage() const; + + ServerNodeInstance parent() const; + bool hasParent() const; + + bool equalGraphicsItem(QGraphicsItem *item) const; + + QRectF boundingRect() const; + QPointF position() const; + QSizeF size() const; + QTransform transform() const; + QTransform customTransform() const; + QTransform sceneTransform() const; + double rotation() const; + double scale() const; + QList<QGraphicsTransform *> transformations() const; + QPointF transformOriginPoint() const; + double zValue() const; + + double opacity() const; + QVariant property(const QString &name) const; + QVariant defaultValue(const QString &name) const; + QString instanceType(const QString &name) const; + QStringList propertyNames() const; + + + bool hasBindingForProperty(const QString &name, bool *hasChanged = 0) const; + + bool isValid() const; + void makeInvalid(); + bool hasContent() const; + bool isResizable() const; + bool isMovable() const; + bool isInPositioner() const; + + bool isSubclassOf(const QString &superTypeName) const; + bool isRootNodeInstance() const; + + bool isWrappingThisObject(QObject *object) const; + + QVariant resetVariant(const QString &name) const; + + bool hasAnchor(const QString &name) const; + bool isAnchoredBySibling() const; + bool isAnchoredByChildren() const; + QPair<QString, ServerNodeInstance> anchor(const QString &name) const; + + int penWidth() const; + + static void registerQmlTypes(); + + void doComponentComplete(); + + QList<ServerNodeInstance> childItems() const; + + QString id() const; + qint32 instanceId() const; + + QObject* testHandle() const; + QSharedPointer<Internal::ObjectNodeInstance> internalInstance() const; + + QList<ServerNodeInstance> stateInstances() const; + +private: // functions + ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance); + + void setPropertyVariant(const QString &name, const QVariant &value); + void setPropertyDynamicVariant(const QString &name, const QString &typeName, const QVariant &value); + + void setPropertyBinding(const QString &name, const QString &expression); + void setPropertyDynamicBinding(const QString &name, const QString &typeName, const QString &expression); + + void resetProperty(const QString &name); + void refreshProperty(const QString &name); + + void activateState(); + void deactivateState(); + void refreshState(); + + bool updateStateVariant(const ServerNodeInstance &target, const QString &propertyName, const QVariant &value); + bool updateStateBinding(const ServerNodeInstance &target, const QString &propertyName, const QString &expression); + bool resetStateProperty(const ServerNodeInstance &target, const QString &propertyName, const QVariant &resetValue); + + static ServerNodeInstance create(NodeInstanceServer *nodeInstanceServer, const InstanceContainer &instanceContainer, ComponentWrap componentWrap); + + void setDeleteHeldInstance(bool deleteInstance); + void reparent(const ServerNodeInstance &oldParentInstance, const QString &oldParentProperty, const ServerNodeInstance &newParentInstance, const QString &newParentProperty); + + + void setId(const QString &id); + + static QSharedPointer<Internal::ObjectNodeInstance> createInstance(QObject *objectToBeWrapped); + + void paintUpdate(); + + static bool isSubclassOf(QObject *object, const QByteArray &superTypeName); + + void setNodeSource(const QString &source); + + + QObject *internalObject() const; // should be not used outside of the nodeinstances!!!! +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + QQuickItem *internalSGItem() const; +#endif + +private: // variables + QSharedPointer<Internal::ObjectNodeInstance> m_nodeInstance; +}; + +uint qHash(const ServerNodeInstance &instance); +bool operator==(const ServerNodeInstance &first, const ServerNodeInstance &second); +QDebug operator<<(QDebug debug, const ServerNodeInstance &instance); +} + +Q_DECLARE_METATYPE(QmlDesigner::ServerNodeInstance) + +#endif // SERVERNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/main.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/main.cpp index 63844a34c9..a88f612aa4 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/main.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/main.cpp @@ -29,7 +29,7 @@ #include <QDebug> -#include <QApplication> +#include <QGuiApplication> #include <QStringList> #include <qt5nodeinstanceclientproxy.h> @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) { - QApplication application(argc, argv); + QGuiApplication application(argc, argv); QCoreApplication::setOrganizationName("QtProject"); QCoreApplication::setOrganizationDomain("qt-project.org"); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri new file mode 100644 index 0000000000..f8ce91f529 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri @@ -0,0 +1,33 @@ + +QT += core gui qml quick network v8 +contains (QT_CONFIG, webkit) { + QT += webkit +} + +QT += core-private qml-private quick-private gui-private script-private v8-private + +DEFINES += QWEAKPOINTER_ENABLE_ARROW + +include (../instances/instances.pri) +include (instances/instances.pri) +include (../commands/commands.pri) +include (../container/container.pri) +include (../interfaces/interfaces.pri) + +QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH) +!isEmpty(QT_BREAKPAD_ROOT_PATH) { + include($$QT_BREAKPAD_ROOT_PATH/qtbreakpad.pri) +} + +SOURCES += $$PWD/main.cpp +RESOURCES += $$PWD/../qmlpuppet.qrc + +OTHER_FILES += Info.plist.in +macx { + info.input = Info.plist.in + info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist + QMAKE_SUBSTITUTES += info +} else { + target.path = $$QTC_PREFIX/bin + INSTALLS += target +} diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pro b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pro index 6b2b7097ae..48bcfe7d80 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pro +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pro @@ -2,40 +2,11 @@ TARGET = qml2puppet TEMPLATE = app -QT += core gui declarative network - -contains (QT_CONFIG, webkit) { - QT += webkit -} - -QT += core-private declarative-private gui-private script-private v8-private - -DEFINES += QWEAKPOINTER_ENABLE_ARROW - -include(../../../../qtcreator.pri) DESTDIR = $$[QT_INSTALL_BINS] -include(../../../rpath.pri) - -include (instances/instances.pri) -include (../instances/instances.pri) -include (../commands/commands.pri) -include (../container/container.pri) -include (../interfaces/interfaces.pri) -QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH) -!isEmpty(QT_BREAKPAD_ROOT_PATH) { - include($$QT_BREAKPAD_ROOT_PATH/qtbreakpad.pri) +build_all:!build_pass { + CONFIG -= build_all + CONFIG += release } -SOURCES += main.cpp -RESOURCES += ../qmlpuppet.qrc - -OTHER_FILES += Info.plist.in -macx { - info.input = Info.plist.in - info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist - QMAKE_SUBSTITUTES += info -} else { - target.path = $$QTC_PREFIX/bin - INSTALLS += target -} +include(../../../../../share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri) diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/anchorchangesnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/anchorchangesnodeinstance.cpp new file mode 100644 index 0000000000..d1cbe5ba23 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/anchorchangesnodeinstance.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + + + +#include "anchorchangesnodeinstance.h" + +namespace QmlDesigner { + +namespace Internal { + +AnchorChangesNodeInstance::AnchorChangesNodeInstance(QObject *object) : + ObjectNodeInstance(object) +{ +} + +AnchorChangesNodeInstance::Pointer AnchorChangesNodeInstance::create(QObject *object) +{ + Q_ASSERT(object); + + Pointer instance(new AnchorChangesNodeInstance(object)); + + return instance; +} + +void AnchorChangesNodeInstance::setPropertyVariant(const QString &/*name*/, const QVariant &/*value*/) +{ +} + +void AnchorChangesNodeInstance::setPropertyBinding(const QString &/*name*/, const QString &/*expression*/) +{ +} + +QVariant AnchorChangesNodeInstance::property(const QString &/*name*/) const +{ + return QVariant(); +} + +void AnchorChangesNodeInstance::resetProperty(const QString &/*name*/) +{ +} + + +void AnchorChangesNodeInstance::reparent(const ServerNodeInstance &/*oldParentInstance*/, + const QString &/*oldParentProperty*/, + const ServerNodeInstance &/*newParentInstance*/, + const QString &/*newParentProperty*/) +{ +} + +QObject *AnchorChangesNodeInstance::changesObject() const +{ + return object(); +} + +} // namespace Internal + +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/instances/anchorchangesnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/anchorchangesnodeinstance.h index 78fa37d83b..78fa37d83b 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/anchorchangesnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/anchorchangesnodeinstance.h diff --git a/share/qtcreator/qml/qmlpuppet/instances/behaviornodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/behaviornodeinstance.cpp index a0bf629acd..a0bf629acd 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/behaviornodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/behaviornodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/behaviornodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/behaviornodeinstance.h new file mode 100644 index 0000000000..3d8d7f890d --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/behaviornodeinstance.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef BEHAVIORNODEINSTANCE_H +#define BEHAVIORNODEINSTANCE_H + +#include "objectnodeinstance.h" + +namespace QmlDesigner { +namespace Internal { + +class BehaviorNodeInstance : public ObjectNodeInstance +{ +public: + typedef QSharedPointer<BehaviorNodeInstance> Pointer; + typedef QWeakPointer<BehaviorNodeInstance> WeakPointer; + + BehaviorNodeInstance(QObject *object); + + static Pointer create(QObject *objectToBeWrapped); + + void setPropertyVariant(const QString &name, const QVariant &value); + void setPropertyBinding(const QString &name, const QString &expression); + + + QVariant property(const QString &name) const; + void resetProperty(const QString &name); + +private: + bool m_isEnabled; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // BEHAVIORNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/childrenchangeeventfilter.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/childrenchangeeventfilter.cpp new file mode 100644 index 0000000000..e636519c0d --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/childrenchangeeventfilter.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "childrenchangeeventfilter.h" + +#include <QEvent> + +namespace QmlDesigner { +namespace Internal { + +ChildrenChangeEventFilter::ChildrenChangeEventFilter(QObject *parent) + : QObject(parent) +{ +} + + +bool ChildrenChangeEventFilter::eventFilter(QObject * /*object*/, QEvent *event) +{ + switch (event->type()) { + case QEvent::ChildAdded: + case QEvent::ChildRemoved: + { + QChildEvent *childEvent = static_cast<QChildEvent*>(event); + emit childrenChanged(childEvent->child()); break; + } + default: break; + } + + return false; +} +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/meegoplugin/meegoplugin.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/childrenchangeeventfilter.h index 3362da4595..b891604531 100644 --- a/src/plugins/qmldesigner/meegoplugin/meegoplugin.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/childrenchangeeventfilter.h @@ -27,28 +27,30 @@ ** ****************************************************************************/ -#ifndef MEEGOPLUGIN_H -#define MEEGOPLUGIN_H +#ifndef CHILDRENCHANGEEVENTFILTER_H +#define CHILDRENCHANGEEVENTFILTER_H -#include <iwidgetplugin.h> +#include <QObject> namespace QmlDesigner { +namespace Internal { -class MeegoPlugin : public QObject, QmlDesigner::IWidgetPlugin +class ChildrenChangeEventFilter : public QObject { Q_OBJECT -#if QT_VERSION >= 0x050000 - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QmlDesignerPlugin" FILE "meegoplugin.json") -#endif - Q_INTERFACES(QmlDesigner::IWidgetPlugin) - public: - MeegoPlugin(); + ChildrenChangeEventFilter(QObject *parent); + + +signals: + void childrenChanged(QObject *object); + +protected: + bool eventFilter(QObject *object, QEvent *event); - QString metaInfo() const; - QString pluginName() const; }; +} // namespace Internal } // namespace QmlDesigner -#endif // MEEGOPLUGIN_H +#endif // CHILDRENCHANGEEVENTFILTER_H diff --git a/share/qtcreator/qml/qmlpuppet/instances/componentnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/componentnodeinstance.cpp index 7d053ca4f2..7d053ca4f2 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/componentnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/componentnodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/componentnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/componentnodeinstance.h index cf277e50b7..cf277e50b7 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/componentnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/componentnodeinstance.h diff --git a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummycontextobject.cpp index d3183e5636..4b6ab40f48 100644 --- a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummycontextobject.cpp @@ -27,30 +27,26 @@ ** ****************************************************************************/ -#include "customstyleplugin.h" -#include <widgetplugin_helper.h> -#include <QtPlugin> +#include "dummycontextobject.h" namespace QmlDesigner { - -CustomStylePlugin::CustomStylePlugin() +DummyContextObject::DummyContextObject(QObject *parent) : + QObject(parent) { } -QString CustomStylePlugin::pluginName() const +QObject *DummyContextObject::parentDummy() const { - return ("CustomStylePlugin"); + return m_dummyParent.data(); } -QString CustomStylePlugin::metaInfo() const +void DummyContextObject::setParentDummy(QObject *parentDummy) { - return QString(":/customstyleplugin/customstyle.metainfo"); -} - + if (m_dummyParent.data() != parentDummy) { + m_dummyParent = parentDummy; + emit parentDummyChanged(); + } } -#if QT_VERSION < 0x050000 -Q_EXPORT_PLUGIN(QmlDesigner::CustomStylePlugin) -#endif - +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/instances/dummycontextobject.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummycontextobject.h index 6d314069f0..6d314069f0 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/dummycontextobject.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummycontextobject.h diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummynodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummynodeinstance.cpp new file mode 100644 index 0000000000..216e7f0585 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummynodeinstance.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "dummynodeinstance.h" + +namespace QmlDesigner { +namespace Internal { + +DummyNodeInstance::DummyNodeInstance() + : ObjectNodeInstance(new QObject) +{ +} + +DummyNodeInstance::Pointer DummyNodeInstance::create() +{ + return Pointer(new DummyNodeInstance); +} + +void DummyNodeInstance::paint(QPainter * /*painter*/) +{ +} + +QRectF DummyNodeInstance::boundingRect() const +{ + return QRectF(); +} + +QPointF DummyNodeInstance::position() const +{ + return QPointF(); +} + +QSizeF DummyNodeInstance::size() const +{ + return QSizeF(); +} + +QTransform DummyNodeInstance::transform() const +{ + return QTransform(); +} + +double DummyNodeInstance::opacity() const +{ + return 0.0; +} + +void DummyNodeInstance::setPropertyVariant(const QString &/*name*/, const QVariant &/*value*/) +{ +} + +void DummyNodeInstance::setPropertyBinding(const QString &/*name*/, const QString &/*expression*/) +{ + +} + +void DummyNodeInstance::setId(const QString &/*id*/) +{ + +} + +QVariant DummyNodeInstance::property(const QString &/*name*/) const +{ + return QVariant(); +} + +QStringList DummyNodeInstance::properties() +{ + return QStringList(); +} + +QStringList DummyNodeInstance::localProperties() +{ + return QStringList(); +} + +void DummyNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Pointer &/*objectNodeInstance*/) +{ + +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummynodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummynodeinstance.h new file mode 100644 index 0000000000..846cf5630c --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/dummynodeinstance.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef DUMMYNODEINSTANCE_H +#define DUMMYNODEINSTANCE_H + +#include <QWeakPointer> + +#include "objectnodeinstance.h" + +namespace QmlDesigner { +namespace Internal { + +class DummyNodeInstance : public ObjectNodeInstance +{ +public: + typedef QSharedPointer<DummyNodeInstance> Pointer; + typedef QWeakPointer<DummyNodeInstance> WeakPointer; + + static Pointer create(); + + void paint(QPainter *painter); + + QRectF boundingRect() const; + QPointF position() const; + QSizeF size() const; + QTransform transform() const; + double opacity() const; + + void setPropertyVariant(const QString &name, const QVariant &value); + void setPropertyBinding(const QString &name, const QString &expression); + void setId(const QString &id); + QVariant property(const QString &name) const; + QStringList properties(); + QStringList localProperties(); + + void initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance); + +protected: + DummyNodeInstance(); + +}; + +} +} +#endif // DUMMYNODEINSTANCE_H diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/instances.pri b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/instances.pri index 890faf94ae..ff2d2b91b0 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/instances.pri +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/instances.pri @@ -8,6 +8,20 @@ HEADERS += $$PWD/qt4previewnodeinstanceserver.h HEADERS += $$PWD/graphicsobjectnodeinstance.h HEADERS += $$PWD/positionernodeinstance.h HEADERS += $$PWD/qmlgraphicsitemnodeinstance.h +HEADERS += $$PWD/behaviornodeinstance.h +HEADERS += $$PWD/dummycontextobject.h +HEADERS += $$PWD/childrenchangeeventfilter.h +HEADERS += $$PWD/componentnodeinstance.h +HEADERS += $$PWD/dummynodeinstance.h +HEADERS += $$PWD/nodeinstancemetaobject.h +HEADERS += $$PWD/nodeinstanceserver.h +HEADERS += $$PWD/nodeinstancesignalspy.h +HEADERS += $$PWD/objectnodeinstance.h +HEADERS += $$PWD/qmlpropertychangesnodeinstance.h +HEADERS += $$PWD/qmlstatenodeinstance.h +HEADERS += $$PWD/qmltransitionnodeinstance.h +HEADERS += $$PWD/servernodeinstance.h +HEADERS += $$PWD/anchorchangesnodeinstance.h SOURCES += $$PWD/qt4nodeinstanceserver.cpp SOURCES += $$PWD/qt4nodeinstanceclientproxy.cpp @@ -17,3 +31,17 @@ SOURCES += $$PWD/qt4previewnodeinstanceserver.cpp SOURCES += $$PWD/graphicsobjectnodeinstance.cpp SOURCES += $$PWD/qmlgraphicsitemnodeinstance.cpp SOURCES += $$PWD/positionernodeinstance.cpp +SOURCES += $$PWD/behaviornodeinstance.cpp +SOURCES += $$PWD/dummycontextobject.cpp +SOURCES += $$PWD/childrenchangeeventfilter.cpp +SOURCES += $$PWD/componentnodeinstance.cpp +SOURCES += $$PWD/dummynodeinstance.cpp +SOURCES += $$PWD/nodeinstancemetaobject.cpp +SOURCES += $$PWD/nodeinstanceserver.cpp +SOURCES += $$PWD/nodeinstancesignalspy.cpp +SOURCES += $$PWD/objectnodeinstance.cpp +SOURCES += $$PWD/qmlpropertychangesnodeinstance.cpp +SOURCES += $$PWD/qmlstatenodeinstance.cpp +SOURCES += $$PWD/qmltransitionnodeinstance.cpp +SOURCES += $$PWD/servernodeinstance.cpp +SOURCES += $$PWD/anchorchangesnodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstancemetaobject.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancemetaobject.cpp index 2fc86a9628..2fc86a9628 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstancemetaobject.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancemetaobject.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstancemetaobject.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancemetaobject.h index 00d4598f1d..00d4598f1d 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstancemetaobject.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancemetaobject.h diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp index 9244d64bbf..5db7afd771 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp @@ -73,6 +73,7 @@ #include "createscenecommand.h" #include "changenodesourcecommand.h" #include "tokencommand.h" +#include "removesharedmemorycommand.h" #include "dummycontextobject.h" @@ -342,6 +343,10 @@ void NodeInstanceServer::token(const TokenCommand &/*command*/) } +void NodeInstanceServer::removeSharedMemory(const RemoveSharedMemoryCommand &/*command*/) +{ +} + void NodeInstanceServer::setupImports(const QVector<AddImportContainer> &containerVector) { foreach (const AddImportContainer &container, containerVector) { @@ -1022,6 +1027,12 @@ QObject *NodeInstanceServer::dummyContextObject() const return m_dummyContextObject.data(); } +void NodeInstanceServer::sendDebugOutput(DebugOutputCommand::Type type, const QString &message) +{ + DebugOutputCommand command(message, type); + nodeInstanceClient()->debugOutput(command); +} + void NodeInstanceServer::notifyPropertyChange(qint32 instanceid, const QString &propertyName) { if (hasInstanceForId(instanceid)) @@ -1055,7 +1066,7 @@ PixmapChangedCommand NodeInstanceServer::createPixmapChangedCommand(const QList< foreach (const ServerNodeInstance &instance, instanceList) { if (instance.isValid() && instance.hasContent()) - imageVector.append(ImageContainer(instance.instanceId(), instance.renderImage())); + imageVector.append(ImageContainer(instance.instanceId(), instance.renderImage(), instance.instanceId())); } return PixmapChangedCommand(imageVector); diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.h index 4a4fe8da85..64b3fc9bea 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.h @@ -38,6 +38,8 @@ #include <nodeinstanceserverinterface.h> #include "servernodeinstance.h" +#include "debugoutputcommand.h" + QT_BEGIN_NAMESPACE class QFileSystemWatcher; class QDeclarativeView; @@ -90,6 +92,7 @@ public: void completeComponent(const CompleteComponentCommand &command); void changeNodeSource(const ChangeNodeSourceCommand &command); void token(const TokenCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); ServerNodeInstance instanceForId(qint32 id) const; bool hasInstanceForId(qint32 id) const; @@ -124,6 +127,8 @@ public: virtual QDeclarativeView *declarativeView() const = 0; virtual QSGView *sgView() const = 0; + void sendDebugOutput(DebugOutputCommand::Type type, const QString &message); + public slots: void refreshLocalFileProperty(const QString &path); void refreshDummyData(const QString &path); diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstancesignalspy.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.cpp index 0c1db8ba67..0c1db8ba67 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstancesignalspy.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.h new file mode 100644 index 0000000000..ae0b94c108 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef NODEINSTANCESIGNALSPY_H +#define NODEINSTANCESIGNALSPY_H + +#include <QObject> +#include <QHash> +#include <QSharedPointer> + +namespace QmlDesigner { +namespace Internal { + +class ObjectNodeInstance; +typedef QSharedPointer<ObjectNodeInstance> ObjectNodeInstancePointer; +typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer; + +class NodeInstanceSignalSpy : public QObject +{ +public: + explicit NodeInstanceSignalSpy(); + + void setObjectNodeInstance(const ObjectNodeInstancePointer &nodeInstance); + + virtual int qt_metacall(QMetaObject::Call, int, void **); + +protected: + void registerObject(QObject *spiedObject, const QString &prefix = QString()); + +private: + int methodeOffset; + QHash<int, QString> m_indexPropertyHash; + QObjectList m_registeredObjectList; + ObjectNodeInstanceWeakPointer m_objectNodeInstance; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // NODEINSTANCESIGNALSPY_H diff --git a/share/qtcreator/qml/qmlpuppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp index 80b9ef4d87..f66376a961 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp @@ -189,7 +189,7 @@ bool ObjectNodeInstance::isPositioner() const return false; } -bool ObjectNodeInstance::isSGItem() const +bool ObjectNodeInstance::isQuickItem() const { return false; } diff --git a/share/qtcreator/qml/qmlpuppet/instances/objectnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/objectnodeinstance.h index d81269fabb..c96d8042dc 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/objectnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/objectnodeinstance.h @@ -99,7 +99,7 @@ public: virtual bool isGraphicsObject() const; virtual bool isTransition() const; virtual bool isPositioner() const; - virtual bool isSGItem() const; + virtual bool isQuickItem() const; virtual bool equalGraphicsItem(QGraphicsItem *item) const; diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/positionernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/positionernodeinstance.cpp index 193557e9fe..e3679e3fd5 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/positionernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/positionernodeinstance.cpp @@ -65,7 +65,7 @@ void PositionerNodeInstance::setPropertyBinding(const QString &name, const QStri } PositionerNodeInstance::Pointer PositionerNodeInstance::create(QObject *object) -{ +{ QDeclarativeBasePositioner *positioner = qobject_cast<QDeclarativeBasePositioner*>(object); Q_ASSERT(positioner); diff --git a/share/qtcreator/qml/qmlpuppet/instances/qmlpropertychangesnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlpropertychangesnodeinstance.cpp index 2464f8edd3..2464f8edd3 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/qmlpropertychangesnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlpropertychangesnodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/qmlpropertychangesnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlpropertychangesnodeinstance.h index 39eed0c81c..39eed0c81c 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/qmlpropertychangesnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlpropertychangesnodeinstance.h diff --git a/share/qtcreator/qml/qmlpuppet/instances/qmlstatenodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlstatenodeinstance.cpp index 72c3c7a390..72c3c7a390 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/qmlstatenodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlstatenodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/qmlstatenodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlstatenodeinstance.h index 5a23976a14..5a23976a14 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/qmlstatenodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlstatenodeinstance.h diff --git a/share/qtcreator/qml/qmlpuppet/instances/qmltransitionnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmltransitionnodeinstance.cpp index cb225008d3..cb225008d3 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/qmltransitionnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmltransitionnodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/qmltransitionnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmltransitionnodeinstance.h index ed8f2ffd71..ed8f2ffd71 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/qmltransitionnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmltransitionnodeinstance.h diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.cpp index 288f81844b..5080d50dc4 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.cpp @@ -73,8 +73,7 @@ #include "componentcompletedcommand.h" #include "createscenecommand.h" #include "tokencommand.h" - - +#include "removesharedmemorycommand.h" #include "dummycontextobject.h" namespace QmlDesigner { @@ -98,6 +97,12 @@ void Qt4InformationNodeInstanceServer::token(const TokenCommand &command) startRenderTimer(); } +void Qt4InformationNodeInstanceServer::removeSharedMemory(const RemoveSharedMemoryCommand &command) +{ + if (command.typeName() == "Values") + ValuesChangedCommand::removeSharedMemorys(command.keyNumbers()); +} + void Qt4InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands() { static bool inFunction = false; diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.h index fc50aea6b9..6dc7a52524 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.h @@ -46,6 +46,7 @@ public: void createScene(const CreateSceneCommand &command); void completeComponent(const CompleteComponentCommand &command); void token(const TokenCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); protected: void collectItemChangesAndSendChangeCommands(); diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4previewnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4previewnodeinstanceserver.cpp index f3cf682e6c..ae5b32b652 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4previewnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4previewnodeinstanceserver.cpp @@ -32,6 +32,7 @@ #include "nodeinstanceclientinterface.h" #include "statepreviewimagechangedcommand.h" #include "createscenecommand.h" +#include "removesharedmemorycommand.h" #include <QPainter> #include <QDeclarativeView> @@ -69,11 +70,11 @@ void Qt4PreviewNodeInstanceServer::collectItemChangesAndSendChangeCommands() if (!inFunction && nodeInstanceClient()->bytesToWrite() < 10000) { inFunction = true; QVector<ImageContainer> imageContainerVector; - imageContainerVector.append(ImageContainer(0, renderPreviewImage())); + imageContainerVector.append(ImageContainer(0, renderPreviewImage(), -1)); foreach (ServerNodeInstance instance, rootNodeInstance().stateInstances()) { instance.activateState(); - imageContainerVector.append(ImageContainer(instance.instanceId(), renderPreviewImage())); + imageContainerVector.append(ImageContainer(instance.instanceId(), renderPreviewImage(), instance.instanceId())); instance.deactivateState(); } @@ -89,6 +90,12 @@ void Qt4PreviewNodeInstanceServer::changeState(const ChangeStateCommand &/*comma } +void Qt4PreviewNodeInstanceServer::removeSharedMemory(const RemoveSharedMemoryCommand &command) +{ + if (command.typeName() == "Image") + ImageContainer::removeSharedMemorys(command.keyNumbers()); +} + QImage Qt4PreviewNodeInstanceServer::renderPreviewImage() { QSize size = rootNodeInstance().boundingRect().size().toSize(); diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4previewnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4previewnodeinstanceserver.h index ddb99a47eb..77648ea0e4 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4previewnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4previewnodeinstanceserver.h @@ -42,6 +42,7 @@ public: void createScene(const CreateSceneCommand &command); void changeState(const ChangeStateCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); QImage renderPreviewImage(); diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.cpp index 6908b8ad73..2df58261e1 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.cpp @@ -72,6 +72,7 @@ #include "completecomponentcommand.h" #include "componentcompletedcommand.h" #include "createscenecommand.h" +#include "removesharedmemorycommand.h" #include "dummycontextobject.h" @@ -193,4 +194,10 @@ void Qt4RenderNodeInstanceServer::changeState(const ChangeStateCommand &command) QGraphicsItemPrivate::get(item)->notifyBoundingRectChanged = 1; } } + +void Qt4RenderNodeInstanceServer::removeSharedMemory(const RemoveSharedMemoryCommand &command) +{ + if (command.typeName() == "Image") + ImageContainer::removeSharedMemorys(command.keyNumbers()); +} } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.h index a87f8ce8d9..35e6a5f010 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.h @@ -44,6 +44,7 @@ public: void clearScene(const ClearSceneCommand &command); void completeComponent(const CompleteComponentCommand &command); void changeState(const ChangeStateCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); protected: void collectItemChangesAndSendChangeCommands(); diff --git a/share/qtcreator/qml/qmlpuppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/servernodeinstance.cpp index 35e9160849..35e9160849 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/servernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/servernodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/servernodeinstance.h index ff122150f8..ff122150f8 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/servernodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/servernodeinstance.h diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/qmlpuppet.pri b/share/qtcreator/qml/qmlpuppet/qmlpuppet/qmlpuppet.pri index 8f76d142ce..1ae8097090 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/qmlpuppet.pri +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/qmlpuppet.pri @@ -11,8 +11,8 @@ greaterThan(QT_MAJOR_VERSION, 4) { DEFINES += QWEAKPOINTER_ENABLE_ARROW -include (instances/instances.pri) include (../instances/instances.pri) +include (instances/instances.pri) include (../commands/commands.pri) include (../container/container.pri) include (../interfaces/interfaces.pri) diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/AlignmentHorizontalButtons.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/AlignmentHorizontalButtons.qml index 15cc73638e..15cc73638e 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/AlignmentHorizontalButtons.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/AlignmentHorizontalButtons.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/AlignmentVerticalButtons.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/AlignmentVerticalButtons.qml index 01225accb2..01225accb2 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/AlignmentVerticalButtons.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/AlignmentVerticalButtons.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/AnchorBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/AnchorBox.qml index 2507ce4582..2507ce4582 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/AnchorBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/AnchorBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/AnchorButtons.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/AnchorButtons.qml index 17f745f3bc..17f745f3bc 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/AnchorButtons.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/AnchorButtons.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/CheckBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/CheckBox.qml index 81d343b401..81d343b401 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/CheckBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/CheckBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ColorGroupBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorGroupBox.qml index b4d22054af..7e6790b79c 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ColorGroupBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorGroupBox.qml @@ -172,7 +172,7 @@ QExtGroupBox { layout: HorizontalLayout { spacing: 6 - LineEdit { + ColorLineEdit { inputMask: "\\#HHHHHH" visible: gradientEditing == false backendValue: colorGroupBox.backendColor @@ -185,7 +185,12 @@ QExtGroupBox { id: lineEditWidget; QLineEdit { y: 2 - text: color + property color colorG: color + onColorGChanged: { + text = convertColorToString(color); + } + + text: "#000000"; width: lineEditWidget.width height: lineEditWidget.height diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ColorLabel.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorLabel.qml index 7a05c5400d..7a05c5400d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ColorLabel.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorLabel.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorLineEdit.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorLineEdit.qml new file mode 100644 index 0000000000..26ff5761d8 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorLineEdit.qml @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import QtQuick 1.0 +import Bauhaus 1.0 + +QWidget { + id: lineEdit + + function escapeString(string) { + var str = string; + str = str.replace(/\\/g, "\\\\"); + str.replace(/\"/g, "\\\""); + str = str.replace(/\t/g, "\\t"); + str = str.replace(/\r/g, "\\r"); + str = str.replace(/\n/g, '\\n'); + return str; + } + + property variant backendValue + property alias enabled: lineEdit.enabled + property variant baseStateFlag + property alias text: lineEditWidget.text + property alias readOnly: lineEditWidget.readOnly + property alias translation: trCheckbox.visible + property alias inputMask: lineEditWidget.inputMask + + minimumHeight: 24; + + onBaseStateFlagChanged: { + evaluate(); + } + + property variant isEnabled: lineEdit.enabled + onIsEnabledChanged: { + evaluate(); + } + + + property bool isInModel: backendValue.isInModel; + onIsInModelChanged: { + evaluate(); + } + property bool isInSubState: backendValue.isInSubState; + onIsInSubStateChanged: { + evaluate(); + } + + function evaluate() { + if (!enabled) { + lineEditWidget.setStyleSheet("color: "+scheme.disabledColor); + } else { + if (baseStateFlag) { + if (backendValue != null && backendValue.isInModel) + lineEditWidget.setStyleSheet("color: "+scheme.changedBaseColor); + else + lineEditWidget.setStyleSheet("color: "+scheme.defaultColor); + } else { + if (backendValue != null && backendValue.isInSubState) + lineEditWidget.setStyleSheet("color: "+scheme.changedStateColor); + else + lineEditWidget.setStyleSheet("color: "+scheme.defaultColor); + } + } + } + + ColorScheme { id:scheme; } + + QLineEdit { + y: 2 + id: lineEditWidget + styleSheet: "QLineEdit { padding-left: 32; }" + width: lineEdit.width + height: lineEdit.height + toolTip: backendValue.isBound ? backendValue.expression : "" + + property string valueFromBackend: (backendValue === undefined || backendValue.value === undefined) ? "" : backendValue.valueToString; + + onValueFromBackendChanged: { + if (backendValue.value === undefined) + return; + text = backendValue.valueToString; + } + + onEditingFinished: { + if (backendValue.isTranslated) { + backendValue.expression = "qsTr(\"" + escapeString(text) + "\")" + } else { + backendValue.value = text + } + evaluate(); + } + + onFocusChanged: { + if (focus) + backendValue.lock(); + else + backendValue.unlock(); + } + + + } + ExtendedFunctionButton { + backendValue: lineEdit.backendValue + y: 6 + x: 0 + visible: lineEdit.enabled + } + QCheckBox { + id: trCheckbox + y: 2 + styleSheetFile: "checkbox_tr.css"; + toolTip: qsTr("Translate this string") + x: lineEditWidget.width - 22 + height: lineEdit.height - 2; + width: 24 + visible: false + checked: backendValue.isTranslated + onToggled: { + if (trCheckbox.checked) { + backendValue.expression = "qsTr(\"" + escapeString(lineEditWidget.text) + "\")" + } else { + backendValue.value = lineEditWidget.text + } + evaluate(); + } + + onVisibleChanged: { + if (trCheckbox.visible) { + trCheckbox.raise(); + lineEditWidget.styleSheet = "QLineEdit { padding-left: 32; padding-right: 62;}" + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ColorScheme.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorScheme.qml index 48b302c2d2..48b302c2d2 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ColorScheme.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorScheme.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ColorTypeButtons.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorTypeButtons.qml index c3a18fa9d8..c3a18fa9d8 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ColorTypeButtons.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ColorTypeButtons.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ComboBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ComboBox.qml index 65639679f7..65639679f7 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ComboBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/DoubleSpinBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/DoubleSpinBox.qml index b69b2cb849..b69b2cb849 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/DoubleSpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/DoubleSpinBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/DoubleSpinBoxAlternate.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/DoubleSpinBoxAlternate.qml index a28c7ef390..a28c7ef390 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/DoubleSpinBoxAlternate.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/DoubleSpinBoxAlternate.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ExpressionEditor.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ExpressionEditor.qml index 1ede7a51da..1ede7a51da 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ExpressionEditor.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ExpressionEditor.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Extended.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Extended.qml index 6a0cdc2553..6a0cdc2553 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Extended.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Extended.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ExtendedFunctionButton.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ExtendedFunctionButton.qml index 6b1452aced..6b1452aced 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ExtendedFunctionButton.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ExtendedFunctionButton.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ExtendedPane.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ExtendedPane.qml index 9f3889b7ad..9f3889b7ad 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ExtendedPane.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ExtendedPane.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ExtendedSwitches.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ExtendedSwitches.qml index 8171a59e2c..8171a59e2c 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ExtendedSwitches.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ExtendedSwitches.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlagedButton.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/FlagedButton.qml index 76eb4240eb..76eb4240eb 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlagedButton.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/FlagedButton.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/FontComboBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/FontComboBox.qml index f3e64531f6..f3e64531f6 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/FontComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/FontComboBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/FontGroupBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/FontGroupBox.qml index bdf083e106..bdf083e106 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/FontGroupBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/FontGroupBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/FontStyleButtons.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/FontStyleButtons.qml index 422e474c48..422e474c48 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/FontStyleButtons.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/FontStyleButtons.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Geometry.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Geometry.qml index d13a6dad97..d13a6dad97 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Geometry.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Geometry.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/GroupBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/GroupBox.qml index 0379c0a851..0379c0a851 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/GroupBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/GroupBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/GroupBoxOption.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/GroupBoxOption.qml index 97272ec065..97272ec065 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/GroupBoxOption.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/GroupBoxOption.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/HorizontalLayout.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/HorizontalLayout.qml index 99c1f7221a..99c1f7221a 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/HorizontalLayout.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/HorizontalLayout.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/HorizontalWhiteLine.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/HorizontalWhiteLine.qml index 7e3507a134..7e3507a134 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/HorizontalWhiteLine.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/HorizontalWhiteLine.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/IntEditor.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/IntEditor.qml index 4f876aa61b..4f876aa61b 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/IntEditor.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/IntEditor.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Label.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Label.qml index 3852338bec..3852338bec 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Label.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Label.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Layout.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Layout.qml index 22f632e95d..22f632e95d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Layout.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Layout.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/LayoutPane.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/LayoutPane.qml index 873bc9c650..873bc9c650 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/LayoutPane.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/LayoutPane.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/LineEdit.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/LineEdit.qml index 34e40c77b6..34e40c77b6 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/LineEdit.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/LineEdit.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Modifiers.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Modifiers.qml index 7ebfa76101..7ebfa76101 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Modifiers.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Modifiers.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/PlaceHolder.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/PlaceHolder.qml index 5a65d73412..5a65d73412 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/PlaceHolder.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/PlaceHolder.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/PropertyFrame.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/PropertyFrame.qml index b987630111..b987630111 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/PropertyFrame.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/PropertyFrame.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ScrollArea.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ScrollArea.qml index b0b3ec107e..b0b3ec107e 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ScrollArea.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/ScrollArea.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/SliderWidget.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/SliderWidget.qml index d34a871a5d..d34a871a5d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/SliderWidget.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/SliderWidget.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/SpinBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/SpinBox.qml index 8d12106177..8d12106177 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/SpinBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/StandardTextColorGroupBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/StandardTextColorGroupBox.qml index e2bdd87a99..e2bdd87a99 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/StandardTextColorGroupBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/StandardTextColorGroupBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/StandardTextGroupBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/StandardTextGroupBox.qml index 8deaa73b06..8deaa73b06 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/StandardTextGroupBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/StandardTextGroupBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Switches.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Switches.qml index 05260b09c2..05260b09c2 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Switches.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Switches.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextEditor.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/TextEditor.qml index d2010328fb..d2010328fb 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextEditor.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/TextEditor.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextInputGroupBox.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/TextInputGroupBox.qml index e903262012..e903262012 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextInputGroupBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/TextInputGroupBox.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Transformation.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Transformation.qml index 1d2cb2558d..1d2cb2558d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Transformation.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Transformation.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Type.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Type.qml index 5b225927d2..5b225927d2 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Type.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Type.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/UrlEdit.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/UrlEdit.qml new file mode 100644 index 0000000000..66d9901478 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/UrlEdit.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import QtQuick 1.0 +import Bauhaus 1.0 + +QWidget { //This is a special spinBox that does color coding for states + + id: urlEdit + property bool enabled: true + property variant backendValue; + property variant baseStateFlag; + + minimumHeight: 22; + + layout: HorizontalLayout { + spacing: 4 + FileWidget { + enabled: (isBaseState || backendValues.id.value != "") && urlEdit.enabled + fileName: backendValue.value; + onFileNameChanged: { + backendValue.value = fileName; + } + itemNode: anchorBackend.itemNode + showComboBox: false + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/VerticalLayout.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/VerticalLayout.qml index 136e2a5774..136e2a5774 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/VerticalLayout.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/VerticalLayout.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/Visibility.qml b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Visibility.qml index df99e6382f..df99e6382f 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/Visibility.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/Visibility.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorbottom.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorbottom.css index 98ad512dc9..bdb2e7b1ef 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorbottom.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorbottom.css @@ -1,11 +1,11 @@ QPushButton { border-image: url(:/qmldesigner/images/anchor-bottom-normal.png); } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/anchor-bottom-pressed.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/anchor-bottom-pressed.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorbox.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorbox.css index d93895b1c8..389072879c 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorbox.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorbox.css @@ -4,9 +4,9 @@ QPushButton::checked border-radius: 4px; border-image: none; background-color: #909090; -} +} -QPushButton:pressed +QPushButton:pressed { border: 2px solid #000000; } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorfill.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorfill.css index c382641d03..53a80982ef 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorfill.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorfill.css @@ -1,11 +1,11 @@ QPushButton { border-image: url(:/qmldesigner/images/anchor-fill-normal.png); } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/anchor-fill-pressed.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/anchor-fill-pressed.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorhorizontal.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorhorizontal.css index 28be04e0ea..8b985609d2 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorhorizontal.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorhorizontal.css @@ -1,11 +1,11 @@ QPushButton { border-image: url(:/qmldesigner/images/anchor-horizontal-normal.png); } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/anchor-horizontal-pressed.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/anchor-horizontal-pressed.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorleft.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorleft.css index 53c9604c0a..a5eebcc683 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorleft.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorleft.css @@ -1,11 +1,11 @@ QPushButton { border-image: url(:/qmldesigner/images/anchor-left-normal.png); } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/anchor-left-pressed.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/anchor-left-pressed.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorright.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorright.css index ee1690e23c..a30a01b0cb 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorright.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorright.css @@ -1,11 +1,11 @@ QPushButton { - border-image: url(:/qmldesigner/images/anchor-right-normal.png); + border-image: url(:/qmldesigner/images/anchor-right-normal.png); } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/anchor-right-pressed.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/anchor-right-pressed.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorspacer.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorspacer.css index 22cfdf8598..e88ce664f3 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorspacer.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorspacer.css @@ -1,11 +1,11 @@ QPushButton { border-image: url(:/qmldesigner/images/anchor-spacer.png); } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/anchor-spacer.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/anchor-spacer.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchortop.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchortop.css index 2310144c1e..68a9e3e4bc 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchortop.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchortop.css @@ -1,11 +1,11 @@ QPushButton { - border-image: url(:/qmldesigner/images/anchor-top-normal.png); + border-image: url(:/qmldesigner/images/anchor-top-normal.png); } - + QPushButton:pressed { - border-image: url(:/qmldesigner/images/anchor-top-pressed.png); + border-image: url(:/qmldesigner/images/anchor-top-pressed.png); } - + QPushButton:checked { - border-image: url(:/qmldesigner/images/anchor-top-pressed.png); + border-image: url(:/qmldesigner/images/anchor-top-pressed.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorvertical.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorvertical.css index 578030e065..617e091981 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/anchorvertical.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/anchorvertical.css @@ -1,11 +1,11 @@ QPushButton { border-image: url(:/qmldesigner/images/anchor-vertical-normal.png); } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/anchor-vertical-pressed.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/anchor-vertical-pressed.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/applybutton.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/applybutton.css index d7680978b3..dadd1baece 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/applybutton.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/applybutton.css @@ -2,7 +2,7 @@ QPushButton { border-image: url(:/qmldesigner/images/apply.png) 3; border-width: 3; } - + QPushButton:hover { border-image: url(:/qmldesigner/images/applybright.png) 3; } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/aspectlock.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/aspectlock.css index f47f0e50ca..1368648c13 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/aspectlock.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/aspectlock.css @@ -1,11 +1,11 @@ QPushButton { border-image: url(:/qmldesigner/images/aspectlockoff.png); } - + QPushButton:pressed { - border-image: url(:/qmldesigner/images/aspectlockset.png); + border-image: url(:/qmldesigner/images/aspectlockset.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/aspectlockset.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/cancelbutton.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/cancelbutton.css index 2078aa0d34..55e50d74cd 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/cancelbutton.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/cancelbutton.css @@ -1,8 +1,8 @@ QPushButton { border-image: url(:/qmldesigner/images/cancel.png) 3; - border-width: 3; + border-width: 3; } - + QPushButton:hover { border-image: url(:/qmldesigner/images/cancelbright.png) 3; } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/checkbox_tr.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/checkbox_tr.css index 92e3b2c6b1..92e3b2c6b1 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/checkbox_tr.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/checkbox_tr.css diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentbottom-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentbottom-h-icon.png Binary files differindex db20dcdd7c..db20dcdd7c 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentbottom-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentbottom-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentbottom-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentbottom-icon.png Binary files differindex d4319c39a8..d4319c39a8 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentbottom-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentbottom-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentcenterh-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentcenterh-h-icon.png Binary files differindex 004221a6ab..004221a6ab 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentcenterh-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentcenterh-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentcenterh-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentcenterh-icon.png Binary files differindex fa80a4f8e3..fa80a4f8e3 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentcenterh-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentcenterh-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentleft-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentleft-h-icon.png Binary files differindex e40f3ef007..e40f3ef007 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentleft-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentleft-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentleft-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentleft-icon.png Binary files differindex af91e4173e..af91e4173e 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentleft-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentleft-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentmiddle-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentmiddle-h-icon.png Binary files differindex 138c28517d..138c28517d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentmiddle-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentmiddle-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentmiddle-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentmiddle-icon.png Binary files differindex c620e95bb2..c620e95bb2 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentmiddle-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentmiddle-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentright-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentright-h-icon.png Binary files differindex 739f74c9ca..739f74c9ca 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentright-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentright-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentright-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentright-icon.png Binary files differindex 068ab27fcf..068ab27fcf 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmentright-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmentright-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmenttop-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmenttop-h-icon.png Binary files differindex 656d018627..656d018627 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmenttop-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmenttop-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmenttop-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmenttop-icon.png Binary files differindex d6a6865a7d..d6a6865a7d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/alignmenttop-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/alignmenttop-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/apply.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/apply.png Binary files differindex 845b46cbcd..845b46cbcd 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/apply.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/apply.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/behaivour.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/behaivour.png Binary files differindex 7eea89104e..7eea89104e 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/behaivour.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/behaivour.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/blended-image-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/blended-image-icon.png Binary files differindex 7c0911d63d..7c0911d63d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/blended-image-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/blended-image-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/bold-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/bold-h-icon.png Binary files differindex 96f5d4e6ad..96f5d4e6ad 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/bold-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/bold-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/bold-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/bold-icon.png Binary files differindex ba86fb4fc7..ba86fb4fc7 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/bold-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/bold-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/button.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/button.png Binary files differindex cc16dbbec3..cc16dbbec3 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/button.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/button.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/cancel.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/cancel.png Binary files differindex 7b696cc87d..7b696cc87d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/cancel.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/cancel.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/default-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/default-icon.png Binary files differindex a90779f02a..a90779f02a 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/default-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/default-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/downArrow.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/downArrow.png Binary files differindex b92cb987b9..b92cb987b9 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/downArrow.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/downArrow.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/expression.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/expression.png Binary files differindex 3dc2e44b3a..3dc2e44b3a 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/expression.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/expression.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/extended.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/extended.png Binary files differindex 82587ae0ec..82587ae0ec 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/extended.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/extended.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/grid-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/grid-icon.png Binary files differindex 113e14c00a..113e14c00a 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/grid-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/grid-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/icon_color_gradient.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/icon_color_gradient.png Binary files differindex 4360c84965..4360c84965 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/icon_color_gradient.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/icon_color_gradient.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/icon_color_none.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/icon_color_none.png Binary files differindex 8fa7a86dc8..8fa7a86dc8 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/icon_color_none.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/icon_color_none.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/icon_color_solid.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/icon_color_solid.png Binary files differindex 0cf124e72e..0cf124e72e 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/icon_color_solid.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/icon_color_solid.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/image-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/image-icon.png Binary files differindex 4dfcae7d47..4dfcae7d47 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/image-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/image-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/italic-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/italic-h-icon.png Binary files differindex 397ccd18ee..397ccd18ee 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/italic-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/italic-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/italic-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/italic-icon.png Binary files differindex 0c3c7a3b20..0c3c7a3b20 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/italic-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/italic-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/item-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/item-icon.png Binary files differindex 82587ae0ec..82587ae0ec 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/item-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/item-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/layout.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/layout.png Binary files differindex 113e14c00a..113e14c00a 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/layout.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/layout.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/leftArrow.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/leftArrow.png Binary files differindex 45187cf047..45187cf047 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/leftArrow.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/leftArrow.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/list-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/list-icon.png Binary files differindex 9c96743f0e..9c96743f0e 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/list-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/list-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/mouse-area-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/mouse-area-icon.png Binary files differindex 8c23b6c0fc..8c23b6c0fc 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/mouse-area-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/mouse-area-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/placeholder.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/placeholder.png Binary files differindex d2b333fdbd..d2b333fdbd 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/placeholder.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/placeholder.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/rect-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/rect-icon.png Binary files differindex 4555d886fb..4555d886fb 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/rect-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/rect-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/reset-button.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/reset-button.png Binary files differindex bf53422b9e..bf53422b9e 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/reset-button.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/reset-button.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/rightArrow.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/rightArrow.png Binary files differindex 118436bbcc..118436bbcc 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/rightArrow.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/rightArrow.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/standard.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/standard.png Binary files differindex 7c0911d63d..7c0911d63d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/standard.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/standard.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/strikeout-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/strikeout-h-icon.png Binary files differindex 9e40e7dfe4..9e40e7dfe4 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/strikeout-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/strikeout-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/strikeout-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/strikeout-icon.png Binary files differindex 94278fa6b4..94278fa6b4 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/strikeout-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/strikeout-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/submenu.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/submenu.png Binary files differindex a91a6a98a1..a91a6a98a1 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/submenu.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/submenu.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/text-edit-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/text-edit-icon.png Binary files differindex 6a064ab07c..6a064ab07c 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/text-edit-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/text-edit-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/text-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/text-icon.png Binary files differindex 9ce62037ba..9ce62037ba 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/text-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/text-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/underline-h-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/underline-h-icon.png Binary files differindex 02ea8c81a8..02ea8c81a8 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/underline-h-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/underline-h-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/underline-icon.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/underline-icon.png Binary files differindex 5d86d7c0e9..5d86d7c0e9 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/underline-icon.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/underline-icon.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/upArrow.png b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/upArrow.png Binary files differindex e689de743e..e689de743e 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/images/upArrow.png +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/images/upArrow.png diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/layoutWidget.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/layoutWidget.css index ce857900b8..85f3d8efda 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/layoutWidget.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/layoutWidget.css @@ -4,9 +4,9 @@ QPushButton::checked border: 4px solid #4f4f41; border-image: none; background-color: #9a9b9e; - } + } - QPushButton:pressed + QPushButton:pressed { border: 1px solid #5f5f51; background-color: #dadbde; diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/propertyEditor.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/propertyEditor.css index 053d2f9a0e..e621398dd2 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/propertyEditor.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/propertyEditor.css @@ -3,9 +3,9 @@ QFrame, QSpinBox { font-size: 11px; } -QFrame +QFrame { - border-radius: 0px; + border-radius: 0px; } WidgetFrame { @@ -34,7 +34,7 @@ QScrollArea { background-color: #4f4f4f; } -QGroupBox +QGroupBox { background-color: #4f4f4f; border: 1px solid #4F4F4F; @@ -42,7 +42,7 @@ QGroupBox font: bold ; } -QLineEdit +QLineEdit { color: white; font-size: 11px; @@ -82,7 +82,7 @@ QTextEdit - QSpinBox + QSpinBox { font-size: 11px; color: white; @@ -96,12 +96,12 @@ QTextEdit background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2c2c2c, stop: 1 #333333); - + max-height: 16px; min-height: 16px; } - - QDoubleSpinBox + + QDoubleSpinBox { font-size: 11px; color: white; @@ -117,7 +117,7 @@ QTextEdit max-height: 16px; min-height: 16px; } - + QSpinBox::down-button { subcontrol-origin: border; subcontrol-position: bottom right; @@ -136,7 +136,7 @@ QSpinBox::down-button:pressed { border-image: url(:/qmldesigner/images/spindown_pressed.png) 1; } - + QSpinBox::up-button { subcontrol-origin: border; subcontrol-position: top right; /* position at bottom right corner */ @@ -153,8 +153,8 @@ QSpinBox::up-button:hover { QSpinBox::up-button:pressed { border-image: url(:/qmldesigner/images/spinup_pressed.png) 1; } - - + + QDoubleSpinBox::down-button { subcontrol-origin: border; subcontrol-position: bottom right; @@ -171,7 +171,7 @@ QDoubleSpinBox::down-button:hover { QDoubleSpinBox::down-button:pressed { border-image: url(:/qmldesigner/images/spindown_pressed.png) 1; } - + QDoubleSpinBox::up-button { subcontrol-origin: border; subcontrol-position: top right; @@ -188,7 +188,7 @@ QDoubleSpinBox::up-button:hover { QDoubleSpinBox::up-button:pressed { border-image: url(:/qmldesigner/images/spinup_pressed.png) 1; } - + QToolButton { background: none; @@ -235,7 +235,7 @@ QComboBox[editable="true"]:on, QMenuBar::item:on { border-width: 3; } -QComboBox +QComboBox { font-size: 11px; color: white; @@ -270,7 +270,7 @@ QComboBox[editable="false"]::down-arrow { QComboBox[editable="false"]::down-arrow:on { position: relative; - top: 1px; + top: 1px; } QComboBox[editable="true"] { @@ -410,8 +410,8 @@ QMenu { border-radius: 4px; padding: 2px 25px 2px 20px; } - - QMenu::item:disabled { + + QMenu::item:disabled { color: #aaaaaa; } QMenu::separator { @@ -420,7 +420,7 @@ QMenu::separator { margin-left: 5px; margin-right: 5px; } - + QComboBox QAbstractItemView { show-decoration-selected: 1; background-color: #494949; @@ -430,7 +430,7 @@ QMenu::separator { selection-background-color: #d2d2d2; selection-color: #404040; } - + QSlider::groove:horizontal { height: 2px; border-image: url(:/qmldesigner/images/slider_line.png) 0; @@ -440,7 +440,7 @@ QMenu::separator { QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f); width: 16px; - height: 16px; + height: 16px; border: 1px solid #5c5c5c; width: 18px; margin: -4px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */ diff --git a/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/qmldir b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/qmldir new file mode 100644 index 0000000000..25a7d54444 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/qmldir @@ -0,0 +1,48 @@ +AlignmentHorizontalButtons 1.0 AlignmentHorizontalButtons.qml +AlignmentVerticalButtons 1.0 AlignmentVerticalButtons.qml +AnchorBox 1.0 AnchorBox.qml +AnchorButtons 1.0 AnchorButtons.qml +CheckBox 1.0 CheckBox.qml +ColorGroupBox 1.0 ColorGroupBox.qml +ColorLabel 1.0 ColorLabel.qml +ColorLineEdit 1.0 ColorLineEdit.qml +ColorScheme 1.0 ColorScheme.qml +ColorTypeButtons 1.0 ColorTypeButtons.qml +ComboBox 1.0 ComboBox.qml +DoubleSpinBox 1.0 DoubleSpinBox.qml +DoubleSpinBoxAlternate 1.0 DoubleSpinBoxAlternate.qml +ExpressionEditor 1.0 ExpressionEditor.qml +Extended 1.0 Extended.qml +ExtendedFunctionButton 1.0 ExtendedFunctionButton.qml +ExtendedPane 1.0 ExtendedPane.qml +ExtendedSwitches 1.0 ExtendedSwitches.qml +FlagedButton 1.0 FlagedButton.qml +FontComboBox 1.0 FontComboBox.qml +FontGroupBox 1.0 FontGroupBox.qml +FontStyleButtons 1.0 FontStyleButtons.qml +Geometry 1.0 Geometry.qml +GroupBox 1.0 GroupBox.qml +GroupBoxOption 1.0 GroupBoxOption.qml +HorizontalLayout 1.0 HorizontalLayout.qml +HorizontalWhiteLine 1.0 HorizontalWhiteLine.qml +IntEditor 1.0 IntEditor.qml +Label 1.0 Label.qml +Layout 1.0 Layout.qml +LayoutPane 1.0 LayoutPane.qml +LineEdit 1.0 LineEdit.qml +Modifiers 1.0 Modifiers.qml +PlaceHolder 1.0 PlaceHolder.qml +PropertyFrame 1.0 PropertyFrame.qml +ScrollArea 1.0 ScrollArea.qml +SliderWidget 1.0 SliderWidget.qml +SpinBox 1.0 SpinBox.qml +StandardTextColorGroupBox 1.0 StandardTextColorGroupBox.qml +StandardTextGroupBox 1.0 StandardTextGroupBox.qml +Switches 1.0 Switches.qml +TextEditor 1.0 TextEditor.qml +TextInputGroupBox 1.0 TextInputGroupBox.qml +Transformation 1.0 Transformation.qml +Type 1.0 Type.qml +VerticalLayout 1.0 VerticalLayout.qml +Visibility 1.0 Visibility.qml +UrlEdit 1.0 UrlEdit.qml diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/specialCheckBox.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/specialCheckBox.css index bcd93fb2ca..da6ca9ec02 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/specialCheckBox.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/specialCheckBox.css @@ -4,7 +4,7 @@ QCheckBox { border-radius: 2px; color: white; } - + QToolButton { color: white; font: bold; @@ -24,4 +24,3 @@ QCheckBox { } -
\ No newline at end of file diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/styledbuttonleft.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/styledbuttonleft.css index 7e46341a8f..086b0d71d0 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/styledbuttonleft.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/styledbuttonleft.css @@ -1,11 +1,11 @@ QPushButton { border-image: url(:/qmldesigner/images/button-normal-left.png); } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/button-pressed-left.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/button-pressed-left.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/styledbuttonmiddle.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/styledbuttonmiddle.css index 739a17099f..0c6608ad25 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/styledbuttonmiddle.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/styledbuttonmiddle.css @@ -2,11 +2,11 @@ QPushButton { border-image: url(:/qmldesigner/images/button-normal-middle.png); padding: 6px; } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/button-pressed-middle.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/button-pressed-middle.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/styledbuttonright.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/styledbuttonright.css index ea879f2638..a7f748579c 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/styledbuttonright.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/styledbuttonright.css @@ -2,11 +2,11 @@ QPushButton { border-image: url(:/qmldesigner/images/button-normal-right.png); padding: 6px; } - + QPushButton:pressed { border-image: url(:/qmldesigner/images/button-pressed-right.png); } - + QPushButton:checked { border-image: url(:/qmldesigner/images/button-pressed-right.png); } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/switch.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/switch.css index 80bd9f04e5..80bd9f04e5 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/switch.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/switch.css diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/typeLabel.css b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/typeLabel.css index b332ad7b64..b332ad7b64 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/typeLabel.css +++ b/share/qtcreator/qmldesigner/propertyeditor/HelperWidgets/typeLabel.css diff --git a/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/BooleanEditorTemplate.qml b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/BooleanEditorTemplate.qml new file mode 100644 index 0000000000..f3432a9161 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/BooleanEditorTemplate.qml @@ -0,0 +1,14 @@ +QWidget { + layout: HorizontalLayout { + Label { + text: "%1" + toolTip: "%1" + } + CheckBox { + text: backendValues.%2.value + backendValue: backendValues.%2 + baseStateFlag: isBaseState + checkable: true + } + } +}
\ No newline at end of file diff --git a/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/ColorEditorTemplate.qml b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/ColorEditorTemplate.qml new file mode 100644 index 0000000000..e8e4f17d72 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/ColorEditorTemplate.qml @@ -0,0 +1,5 @@ +ColorGroupBox { + caption: "%1" + finished: finishedNotify + backendColor: backendValues.%2 +}
\ No newline at end of file diff --git a/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/IntEditorTemplate.qml b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/IntEditorTemplate.qml new file mode 100644 index 0000000000..c3c35be70c --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/IntEditorTemplate.qml @@ -0,0 +1,6 @@ +IntEditor { + backendValue: backendValues.%2 + caption: "%1" + baseStateFlag: isBaseState + slider: false +}
\ No newline at end of file diff --git a/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/RealEditorTemplate.qml b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/RealEditorTemplate.qml new file mode 100644 index 0000000000..cdae8e7ff8 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/RealEditorTemplate.qml @@ -0,0 +1,5 @@ +DoubleSpinBoxAlternate { + text: "%1" + backendValue: backendValues.%2 + baseStateFlag: isBaseState +}
\ No newline at end of file diff --git a/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/StringEditorTemplate.qml b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/StringEditorTemplate.qml new file mode 100644 index 0000000000..5152da59d6 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/StringEditorTemplate.qml @@ -0,0 +1,12 @@ +QWidget { + layout: HorizontalLayout { + Label { + text: "%1" + toolTip: "%1" + } + LineEdit { + backendValue: backendValues.%2 + baseStateFlag: isBaseState + } + } +}
\ No newline at end of file diff --git a/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/TemplateTypes.qml b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/TemplateTypes.qml new file mode 100644 index 0000000000..78cc7da45d --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/TemplateTypes.qml @@ -0,0 +1,29 @@ + +AutoTypes { + imports: [ "import HelperWidgets 1.0", "import QtQuick 1.0", "import Bauhaus 1.0" ] + + Type { + typeNames: ["int"] + sourceFile: "IntEditorTemplate.qml" + } + Type { + typeNames: ["real", "double", "qreal"] + sourceFile: "RealEditorTemplate.qml" + } + Type { + typeNames: ["string", "QString"] + sourceFile: "StringEditorTemplate.qml" + } + Type { + typeNames: ["QUrl", "url"] + sourceFile: "UrlEditorTemplate.qml" + } + Type { + typeNames: ["bool", "boolean"] + sourceFile: "BooleanEditorTemplate.qml" + } + Type { + typeNames: ["color", "QColor"] + sourceFile: "ColorEditorTemplate.qml" + } +} diff --git a/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/UrlEditorTemplate.qml b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/UrlEditorTemplate.qml new file mode 100644 index 0000000000..39e401b18e --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyeditor/PropertyTemplates/UrlEditorTemplate.qml @@ -0,0 +1,12 @@ +QWidget { + layout: HorizontalLayout { + Label { + text: "%1" + toolTip: "%1" + } + UrlEdit { + backendValue: backendValues.%2 + baseStateFlag: isBaseState + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/BorderImageSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/BorderImageSpecifics.qml index 048b5af7b9..e6eee25041 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/BorderImageSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/BorderImageSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import "../HelperWidgets/" QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlickableGroupBox.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/FlickableGroupBox.qml index 731e99d89a..35e46252ab 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlickableGroupBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/FlickableGroupBox.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 GroupBox { finished: finishedNotify; diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlickableSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/FlickableSpecifics.qml index 2e1aa74a90..3564fdbe8f 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlickableSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/FlickableSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlipableSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/FlipableSpecifics.qml index ca750e2b82..41dc801d5f 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlipableSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/FlipableSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { } diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlowSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/FlowSpecifics.qml index 8eeccb6a9a..36d4d18a86 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/FlowSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/FlowSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/GridSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/GridSpecifics.qml index 9db69b27d5..875cf980fa 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/GridSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/GridSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/GridViewSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/GridViewSpecifics.qml index 3879d9aa32..c77eb60f05 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/GridViewSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/GridViewSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ImageSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/ImageSpecifics.qml index e6ac6ee31d..1ff5ad9d37 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ImageSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/ImageSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ItemPane.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/ItemPane.qml index ae0fbea491..6e8cc56a19 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/ItemPane.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 PropertyFrame { id: frame; diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/ListViewSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/ListViewSpecifics.qml index b64acd61a3..e72c02ad1d 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/ListViewSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/ListViewSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/MouseAreaSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/MouseAreaSpecifics.qml index 806752747a..cf3db6539f 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/MouseAreaSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/MouseAreaSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/PathViewSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/PathViewSpecifics.qml index d55ee0e592..bedd016c5a 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/PathViewSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/PathViewSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/RectangleColorGroupBox.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/RectangleColorGroupBox.qml index 5e8a33d3f8..84d0d1f2f9 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/RectangleColorGroupBox.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/RectangleColorGroupBox.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 GroupBox { id: rectangleColorGroupBox diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/RectangleSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/RectangleSpecifics.qml index b13ba55314..0f4fa40c8a 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/RectangleSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/RectangleSpecifics.qml @@ -29,7 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 - +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/RowSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/RowSpecifics.qml index ea75b9e298..b5e67d78c6 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/RowSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/RowSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextEditSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/TextEditSpecifics.qml index 26ee4e4a81..2bbee533c9 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextEditSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/TextEditSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { id: textSpecifics; diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextInputSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/TextInputSpecifics.qml index bc790149d1..5b88fdfd9f 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextInputSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/TextInputSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { id: textSpecifics; diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/TextSpecifics.qml index 70f8f09ef3..2dfc312cab 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/TextSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/TextSpecifics.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 QWidget { id: textSpecifics; diff --git a/share/qtcreator/qmldesigner/propertyeditor/Qt/emptyPane.qml b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/emptyPane.qml index 88eefe534f..80d3e2d5a9 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/Qt/emptyPane.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtQuick/emptyPane.qml @@ -29,6 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 +import HelperWidgets 1.0 PropertyFrame { layout: QVBoxLayout { diff --git a/share/qtcreator/qmldesigner/propertyeditor/QtWebKit/WebViewSpecifics.qml b/share/qtcreator/qmldesigner/propertyeditor/QtWebKit/WebViewSpecifics.qml index 615e67fc79..e69ca1f4c6 100644 --- a/share/qtcreator/qmldesigner/propertyeditor/QtWebKit/WebViewSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyeditor/QtWebKit/WebViewSpecifics.qml @@ -29,7 +29,7 @@ import QtQuick 1.0 import Bauhaus 1.0 -import "../Qt/" +import HelperWidgets 1.0 QWidget { layout: QVBoxLayout { diff --git a/share/qtcreator/templates/wizards/codesnippet/main.cpp b/share/qtcreator/templates/wizards/codesnippet/main.cpp new file mode 100644 index 0000000000..59d189b301 --- /dev/null +++ b/share/qtcreator/templates/wizards/codesnippet/main.cpp @@ -0,0 +1 @@ +%CODE% diff --git a/share/qtcreator/templates/wizards/codesnippet/project.pro b/share/qtcreator/templates/wizards/codesnippet/project.pro new file mode 100644 index 0000000000..6652132d05 --- /dev/null +++ b/share/qtcreator/templates/wizards/codesnippet/project.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +@if "%TYPE%" == "core" +QT = core +@else +QT = core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +@endif +@if "%CONSOLE%" == "true" +CONFIG += console +@endif +@if "%APP_BUNDLE%" == "false" +CONFIG -= app_bundle +@endif + +SOURCES += main.cpp diff --git a/share/qtcreator/templates/wizards/codesnippet/wizard.xml b/share/qtcreator/templates/wizards/codesnippet/wizard.xml new file mode 100644 index 0000000000..7d52a0e017 --- /dev/null +++ b/share/qtcreator/templates/wizards/codesnippet/wizard.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: http://www.qt-project.org/ +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +**************************************************************************/ + +Custom project wizard configuration example file. Note that by convention, +the project file goes last. +The "class" and "firstpage" attributes specify that it is a Qt 4 wizard and +leave room for the Qt 4 target page. +--> +<wizard version="1" kind="project" + class="qt4project" firstpage="10" + id="Z.Snippet" category="H.QtProjects"> + <description>Creates a qmake-based test project for which a code snippet can be entered.</description> + <displayname>Code Snippet</displayname>; + <displaycategory>Other Projects</displaycategory> + <files> + <file source="main.cpp" openeditor="true"/> + <file source="project.pro" target="%ProjectName%.pro" openproject="true"/> + </files> + <fieldpagetitle>Snippet Parameters</fieldpagetitle> + <fields> + <field name="CODE"> + <fieldcontrol class="QTextEdit" defaulttext="int main(int argc, char *argv[]) { return 0; }"/> + <fielddescription>Code:</fielddescription> + </field> + <field name="TYPE"> + <fielddescription>Type:</fielddescription> + <fieldcontrol class="QComboBox" defaultindex="0"> + <comboentries> + <comboentry value="core"> + <comboentrytext>Headless (QtCore)</comboentrytext> + </comboentry> + <comboentry value="gui"> + <comboentrytext>Gui application (QtCore, QtGui, QtWidgets)</comboentrytext> + </comboentry> + </comboentries> + </fieldcontrol> + </field> + <field name="CONSOLE"> + <fieldcontrol class="QCheckBox" defaultvalue="true"/> + <fielddescription>Console application</fielddescription> + </field> + <field name="APP_BUNDLE"> + <fieldcontrol class="QCheckBox"/> + <fielddescription>Application bundle (Mac)</fielddescription> + </field> + </fields> +</wizard> diff --git a/share/share.qbs b/share/share.qbs index 9a69a21bbf..f2fa15eaa4 100644 --- a/share/share.qbs +++ b/share/share.qbs @@ -5,1334 +5,49 @@ Product { name: "SharedContent" Group { - condition: qbs.targetOS == "macx" - qbs.installDir: "share/qtcreator/scripts" - fileTags: ["install"] - files: "qtcreator/scripts/openTerminal.command" - } - - Group { - qbs.installDir: "share/qtcreator/designer" - fileTags: ["install"] - prefix: "qtcreator/designer/" - files: [ - "templates.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/designer/templates" - fileTags: ["install"] - prefix: "qtcreator/designer/templates/" - files: [ - "Dialog_with_Buttons_Bottom.ui", - "Dialog_with_Buttons_Right.ui", - "Dialog_without_Buttons.ui", - "Main_Window.ui", - "Widget.ui", - ] - } - - Group { - qbs.installDir: "share/qtcreator/dumper" - fileTags: ["install"] - prefix: "qtcreator/dumper/" - files: [ - "LGPL_EXCEPTION.TXT", - "LICENSE.LGPL", - "bridge.py", - "dumper.cpp", - "dumper.h", - "dumper.pro", - "dumper.py", - "dumper_p.h", - "pdumper.py", - "qttypes.py", - ] - } - - Group { - qbs.installDir: "share/qtcreator/dumper/test" - fileTags: ["install"] - prefix: "qtcreator/dumper/test/" - files: [ - "dumpertest.pro", - "main.cpp", - ] - } - - Group { - qbs.installDir: "share/qtcreator/generic-highlighter" - fileTags: ["install"] - prefix: "qtcreator/generic-highlighter/" - files: [ - "alert.xml", - "autoconf.xml", - "bash.xml", - "cmake.xml", - "css.xml", - "doxygen.xml", - "dtd.xml", - "html.xml", - "ini.xml", - "java.xml", - "javadoc.xml", - "perl.xml", - "ruby.xml", - "valgrind-suppression.xml", - "xml.xml", - "yacc.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/glsl" - fileTags: ["install"] - prefix: "qtcreator/glsl/" - files: [ - "glsl_120.frag", - "glsl_120.vert", - "glsl_120_common.glsl", - "glsl_es_100.frag", - "glsl_es_100.vert", - "glsl_es_100_common.glsl", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml-type-descriptions" - fileTags: ["install"] - prefix: "qtcreator/qml-type-descriptions/" - files: [ - "builtins.qmltypes", - "qmlproject.qmltypes", - "qmlruntime.qmltypes", - "qt-labs-folderlistmodel.qmltypes", - "qt-labs-gestures.qmltypes", - "qt-labs-particles.qmltypes", - "qtmobility-connectivity.qmltypes", - "qtmobility-contacts.qmltypes", - "qtmobility-feedback.qmltypes", - "qtmobility-gallery.qmltypes", - "qtmobility-location.qmltypes", - "qtmobility-messaging.qmltypes", - "qtmobility-organizer.qmltypes", - "qtmobility-publishsubscribe.qmltypes", - "qtmobility-sensors.qmltypes", - "qtmobility-serviceframework.qmltypes", - "qtmobility-systeminfo.qmltypes", - "qtmultimediakit.qmltypes", - "qtwebkit.qmltypes", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmldump" - fileTags: ["install"] - prefix: "qtcreator/qml/qmldump/" - files: [ - "LGPL_EXCEPTION.TXT", - "LICENSE.LGPL", - "main.cpp", - "qmldump.pro", - "qmlstreamwriter.cpp", - "qmlstreamwriter.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmljsdebugger" - fileTags: ["install"] - prefix: "qtcreator/qml/qmljsdebugger/" - files: [ - "jsdebuggeragent.cpp", - "qdeclarativeinspectorservice.cpp", - "qdeclarativeviewinspector.cpp", - "qdeclarativeviewinspector_p.h", - "qmljsdebugger-lib.pri", - "qmljsdebugger-src.pri", - "qmljsdebugger.pro", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmljsdebugger/editor" - fileTags: ["install"] - prefix: "qtcreator/qml/qmljsdebugger/editor/" - files: [ - "abstractliveedittool.cpp", - "abstractliveedittool.h", - "boundingrecthighlighter.cpp", - "boundingrecthighlighter.h", - "colorpickertool.cpp", - "colorpickertool.h", - "livelayeritem.cpp", - "livelayeritem.h", - "liverubberbandselectionmanipulator.cpp", - "liverubberbandselectionmanipulator.h", - "liveselectionindicator.cpp", - "liveselectionindicator.h", - "liveselectionrectangle.cpp", - "liveselectionrectangle.h", - "liveselectiontool.cpp", - "liveselectiontool.h", - "livesingleselectionmanipulator.cpp", - "livesingleselectionmanipulator.h", - "subcomponentmasklayeritem.cpp", - "subcomponentmasklayeritem.h", - "zoomtool.cpp", - "zoomtool.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmljsdebugger/include" - fileTags: ["install"] - prefix: "qtcreator/qml/qmljsdebugger/include/" - files: [ - "jsdebuggeragent.h", - "qdeclarativeinspectorservice.h", - "qdeclarativeviewinspector.h", - "qdeclarativeviewobserver.h", - "qmlinspectorconstants.h", - "qmljsdebugger_global.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmljsdebugger/include/qt_private" - fileTags: ["install"] - prefix: "qtcreator/qml/qmljsdebugger/include/qt_private/" - files: [ - "qdeclarativedebughelper_p.h", - "qdeclarativedebugservice_p.h", - "qdeclarativestate_p.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmljsdebugger/protocol" - fileTags: ["install"] - prefix: "qtcreator/qml/qmljsdebugger/protocol/" - files: [ - "inspectorprotocol.h", - "protocol.pri", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlobserver" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlobserver/" - files: [ - "LGPL_EXCEPTION.TXT", - "LICENSE.LGPL", - "deviceorientation.cpp", - "deviceorientation.h", - "deviceorientation_harmattan.cpp", - "deviceorientation_maemo5.cpp", - "deviceorientation_symbian.cpp", - "loggerwidget.cpp", - "loggerwidget.h", - "main.cpp", - "proxysettings.cpp", - "proxysettings.h", - "proxysettings.ui", - "proxysettings_maemo5.ui", - "qdeclarativetester.cpp", - "qdeclarativetester.h", - "qml.icns", - "qml.pri", - "qmlobserver.pro", - "qmlruntime.cpp", - "qmlruntime.h", - "recopts.ui", - "recopts_maemo5.ui", - "texteditautoresizer_maemo5.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlobserver/browser" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlobserver/browser/" - files: [ - "Browser.qml", - "browser.qrc", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlobserver/browser/images" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlobserver/browser/images/" - files: [ - "folder.png", - "titlebar.png", - "titlebar.sci", - "up.png", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlobserver/startup" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlobserver/startup/" - files: [ - "Logo.qml", - "qt-back.png", - "qt-blue.jpg", - "qt-front.png", - "qt-sketch.jpg", - "qt-text.png", - "quick-blur.png", - "quick-regular.png", - "shadow.png", - "startup.qml", - "startup.qrc", - "white-star.png", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/" - files: [ - "qmlpuppet.pro", - "qmlpuppet.qrc", - "qmlpuppet_utilities.pri", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/commands" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/commands/" - files: [ - "changeauxiliarycommand.cpp", - "changeauxiliarycommand.h", - "changebindingscommand.cpp", - "changebindingscommand.h", - "changefileurlcommand.cpp", - "changefileurlcommand.h", - "changeidscommand.cpp", - "changeidscommand.h", - "changenodesourcecommand.cpp", - "changenodesourcecommand.h", - "changestatecommand.cpp", - "changestatecommand.h", - "changevaluescommand.cpp", - "changevaluescommand.h", - "childrenchangedcommand.cpp", - "childrenchangedcommand.h", - "clearscenecommand.cpp", - "clearscenecommand.h", - "commands.pri", - "completecomponentcommand.cpp", - "completecomponentcommand.h", - "componentcompletedcommand.cpp", - "componentcompletedcommand.h", - "createinstancescommand.cpp", - "createinstancescommand.h", - "createscenecommand.cpp", - "createscenecommand.h", - "informationchangedcommand.cpp", - "informationchangedcommand.h", - "pixmapchangedcommand.cpp", - "pixmapchangedcommand.h", - "removeinstancescommand.cpp", - "removeinstancescommand.h", - "removepropertiescommand.cpp", - "removepropertiescommand.h", - "reparentinstancescommand.cpp", - "reparentinstancescommand.h", - "statepreviewimagechangedcommand.cpp", - "statepreviewimagechangedcommand.h", - "synchronizecommand.cpp", - "synchronizecommand.h", - "tokencommand.cpp", - "tokencommand.h", - "valueschangedcommand.cpp", - "valueschangedcommand.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/container" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/container/" - files: [ - "addimportcontainer.cpp", - "addimportcontainer.h", - "container.pri", - "idcontainer.cpp", - "idcontainer.h", - "imagecontainer.cpp", - "imagecontainer.h", - "informationcontainer.cpp", - "informationcontainer.h", - "instancecontainer.cpp", - "instancecontainer.h", - "propertyabstractcontainer.cpp", - "propertyabstractcontainer.h", - "propertybindingcontainer.cpp", - "propertybindingcontainer.h", - "propertyvaluecontainer.cpp", - "propertyvaluecontainer.h", - "reparentcontainer.cpp", - "reparentcontainer.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/html" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/html/" - files: [ - "welcome.html", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/images" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/images/" - files: [ - "template_image.png", - "webkit.png", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/instances" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/instances/" - files: [ - "anchorchangesnodeinstance.cpp", - "anchorchangesnodeinstance.h", - "behaviornodeinstance.cpp", - "behaviornodeinstance.h", - "childrenchangeeventfilter.cpp", - "childrenchangeeventfilter.h", - "componentnodeinstance.cpp", - "componentnodeinstance.h", - "dummycontextobject.cpp", - "dummycontextobject.h", - "dummynodeinstance.cpp", - "dummynodeinstance.h", - "instances.pri", - "nodeinstanceclientproxy.cpp", - "nodeinstanceclientproxy.h", - "nodeinstancemetaobject.cpp", - "nodeinstancemetaobject.h", - "nodeinstanceserver.cpp", - "nodeinstanceserver.h", - "nodeinstancesignalspy.cpp", - "nodeinstancesignalspy.h", - "objectnodeinstance.cpp", - "objectnodeinstance.h", - "qmlpropertychangesnodeinstance.cpp", - "qmlpropertychangesnodeinstance.h", - "qmlstatenodeinstance.cpp", - "qmlstatenodeinstance.h", - "qmltransitionnodeinstance.cpp", - "qmltransitionnodeinstance.h", - "servernodeinstance.cpp", - "servernodeinstance.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/interfaces" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/interfaces/" - files: [ - "commondefines.h", - "interfaces.pri", - "nodeinstanceclientinterface.h", - "nodeinstanceserverinterface.cpp", - "nodeinstanceserverinterface.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/qml2puppet" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/qml2puppet/" - files: [ - "main.cpp", - "qml2puppet.pro", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/qml2puppet/instances" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/qml2puppet/instances/" - files: [ - "instances.pri", - "qt5informationnodeinstanceserver.cpp", - "qt5informationnodeinstanceserver.h", - "qt5nodeinstanceclientproxy.cpp", - "qt5nodeinstanceclientproxy.h", - "qt5nodeinstanceserver.cpp", - "qt5nodeinstanceserver.h", - "qt5previewnodeinstanceserver.cpp", - "qt5previewnodeinstanceserver.h", - "qt5rendernodeinstanceserver.cpp", - "qt5rendernodeinstanceserver.h", - "sgitemnodeinstance.cpp", - "sgitemnodeinstance.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/qmlpuppet" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/qmlpuppet/" - files: [ - "main.cpp", - "qmlpuppet.pri", - "qmlpuppet.pro", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qml/qmlpuppet/qmlpuppet/instances" - fileTags: ["install"] - prefix: "qtcreator/qml/qmlpuppet/qmlpuppet/instances/" - files: [ - "graphicsobjectnodeinstance.cpp", - "graphicsobjectnodeinstance.h", - "instances.pri", - "positionernodeinstance.cpp", - "positionernodeinstance.h", - "qmlgraphicsitemnodeinstance.cpp", - "qmlgraphicsitemnodeinstance.h", - "qt4informationnodeinstanceserver.cpp", - "qt4informationnodeinstanceserver.h", - "qt4nodeinstanceclientproxy.cpp", - "qt4nodeinstanceclientproxy.h", - "qt4nodeinstanceserver.cpp", - "qt4nodeinstanceserver.h", - "qt4previewnodeinstanceserver.cpp", - "qt4previewnodeinstanceserver.h", - "qt4rendernodeinstanceserver.cpp", - "qt4rendernodeinstanceserver.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qmldesigner/propertyeditor/Qt" - fileTags: ["install"] - prefix: "qtcreator/qmldesigner/propertyeditor/Qt/" - files: [ - "AlignmentHorizontalButtons.qml", - "AlignmentVerticalButtons.qml", - "AnchorBox.qml", - "AnchorButtons.qml", - "BorderImageSpecifics.qml", - "CheckBox.qml", - "ColorGroupBox.qml", - "ColorLabel.qml", - "ColorScheme.qml", - "ColorTypeButtons.qml", - "ComboBox.qml", - "DoubleSpinBox.qml", - "DoubleSpinBoxAlternate.qml", - "ExpressionEditor.qml", - "Extended.qml", - "ExtendedFunctionButton.qml", - "ExtendedPane.qml", - "ExtendedSwitches.qml", - "FlagedButton.qml", - "FlickableGroupBox.qml", - "FlickableSpecifics.qml", - "FlipableSpecifics.qml", - "FlowSpecifics.qml", - "FontComboBox.qml", - "FontGroupBox.qml", - "FontStyleButtons.qml", - "Geometry.qml", - "GridSpecifics.qml", - "GridViewSpecifics.qml", - "GroupBox.qml", - "GroupBoxOption.qml", - "HorizontalLayout.qml", - "HorizontalWhiteLine.qml", - "ImageSpecifics.qml", - "IntEditor.qml", - "ItemPane.qml", - "Label.qml", - "Layout.qml", - "LayoutPane.qml", - "LineEdit.qml", - "ListViewSpecifics.qml", - "Modifiers.qml", - "MouseAreaSpecifics.qml", - "PathViewSpecifics.qml", - "PlaceHolder.qml", - "PropertyFrame.qml", - "RectangleColorGroupBox.qml", - "RectangleSpecifics.qml", - "RowSpecifics.qml", - "ScrollArea.qml", - "SliderWidget.qml", - "SpinBox.qml", - "StandardTextColorGroupBox.qml", - "StandardTextGroupBox.qml", - "Switches.qml", - "TextEditSpecifics.qml", - "TextEditor.qml", - "TextInputGroupBox.qml", - "TextInputSpecifics.qml", - "TextSpecifics.qml", - "Transformation.qml", - "Type.qml", - "VerticalLayout.qml", - "Visibility.qml", - "anchorbottom.css", - "anchorbox.css", - "anchorfill.css", - "anchorhorizontal.css", - "anchorleft.css", - "anchorright.css", - "anchorspacer.css", - "anchortop.css", - "anchorvertical.css", - "applybutton.css", - "aspectlock.css", - "cancelbutton.css", - "checkbox_tr.css", - "emptyPane.qml", - "layoutWidget.css", - "propertyEditor.css", - "specialCheckBox.css", - "styledbuttonleft.css", - "styledbuttonmiddle.css", - "styledbuttonright.css", - "switch.css", - "typeLabel.css", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qmldesigner/propertyeditor/Qt/images" - fileTags: ["install"] - prefix: "qtcreator/qmldesigner/propertyeditor/Qt/images/" - files: [ - "alignmentbottom-h-icon.png", - "alignmentbottom-icon.png", - "alignmentcenterh-h-icon.png", - "alignmentcenterh-icon.png", - "alignmentleft-h-icon.png", - "alignmentleft-icon.png", - "alignmentmiddle-h-icon.png", - "alignmentmiddle-icon.png", - "alignmentright-h-icon.png", - "alignmentright-icon.png", - "alignmenttop-h-icon.png", - "alignmenttop-icon.png", - "apply.png", - "behaivour.png", - "blended-image-icon.png", - "bold-h-icon.png", - "bold-icon.png", - "button.png", - "cancel.png", - "default-icon.png", - "downArrow.png", - "expression.png", - "extended.png", - "grid-icon.png", - "icon_color_gradient.png", - "icon_color_none.png", - "icon_color_solid.png", - "image-icon.png", - "italic-h-icon.png", - "italic-icon.png", - "item-icon.png", - "layout.png", - "leftArrow.png", - "list-icon.png", - "mouse-area-icon.png", - "placeholder.png", - "rect-icon.png", - "reset-button.png", - "rightArrow.png", - "standard.png", - "strikeout-h-icon.png", - "strikeout-icon.png", - "submenu.png", - "text-edit-icon.png", - "text-icon.png", - "underline-h-icon.png", - "underline-icon.png", - "upArrow.png", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qmldesigner/propertyeditor/QtWebKit" - fileTags: ["install"] - prefix: "qtcreator/qmldesigner/propertyeditor/QtWebKit/" - files: [ - "WebViewSpecifics.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qmlicons/Qt/16x16" - fileTags: ["install"] - prefix: "qtcreator/qmlicons/Qt/16x16/" - files: [ - "BorderImage.png", - "BusyIndicator.png", - "Button.png", - "ButtonColumn.png", - "ButtonRow.png", - "CheckBox.png", - "ChoiceList.png", - "ColorAnimation.png", - "Component.png", - "CountBubble.png", - "DatePickerDialog.png", - "Flickable.png", - "Flipable.png", - "FocusScope.png", - "GridView.png", - "Image.png", - "InfoBanner.png", - "Item.png", - "ListButton.png", - "ListDelegate.png", - "ListView.png", - "MoreIndicator.png", - "MouseArea.png", - "PageIndicator.png", - "ParallelAnimation.png", - "PathView.png", - "PauseAnimation.png", - "ProgressBar.png", - "PropertyChanges.png", - "RadioButton.png", - "RatingIndicator.png", - "Rectangle.png", - "SequentialAnimation.png", - "Slider.png", - "State.png", - "Switch.png", - "TabBar.png", - "TabButton.png", - "Text.png", - "TextArea.png", - "TextEdit.png", - "TextField.png", - "TextInput.png", - "TimePickerDialog.png", - "ToolBar.png", - "Transition.png", - "Tumbler.png", - "TumblerButton.png", - "TumblerColumn.png", - "TumblerDialog.png", - "Window.png", - "item-icon16.png", - ] - } - - Group { - qbs.installDir: "share/qtcreator/qmlicons/QtWebkit/16x16" - fileTags: ["install"] - prefix: "qtcreator/qmlicons/QtWebkit/16x16/" - files: [ - "WebView.png", - ] - } - - Group { - qbs.installDir: "share/qtcreator/schemes" - fileTags: ["install"] - prefix: "qtcreator/schemes/" - files: [ - "MS_Visual_C++.kms", - "Xcode.kms", - ] - } - - Group { - qbs.installDir: "share/qtcreator/snippets" - fileTags: ["install"] - prefix: "qtcreator/snippets/" - files: [ - "cpp.xml", - "qml.xml", - "text.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/styles" - fileTags: ["install"] - prefix: "qtcreator/styles/" - files: [ - "darkvim.xml", - "default.xml", - "grayscale.xml", - "inkpot.xml", - "intellij.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/html5app" - fileTags: ["install"] - prefix: "qtcreator/templates/html5app/" - files: [ - "app.pro", - "main.cpp", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/html5app/html" + qbs.installDir: "share" fileTags: ["install"] - prefix: "qtcreator/templates/html5app/html/" - files: [ - "index.html", + files: "qtcreator" + recursive: true + excludeFiles: [ + "qtcreator/translations", + "qtcreator/scripts", + "share.pro", + "share.qbs", + "static.pro", ] } Group { - qbs.installDir: "share/qtcreator/templates/html5app/html5applicationviewer" - fileTags: ["install"] - prefix: "qtcreator/templates/html5app/html5applicationviewer/" - files: [ - "html5applicationviewer.cpp", - "html5applicationviewer.h", - "html5applicationviewer.pri", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/html5app/html5applicationviewer/touchnavigation" - fileTags: ["install"] - prefix: "qtcreator/templates/html5app/html5applicationviewer/touchnavigation/" - files: [ - "navigationcontroller.cpp", - "navigationcontroller.h", - "touchnavigation.pri", - "webnavigation.cpp", - "webnavigation.h", - "webtouchevent.cpp", - "webtouchevent.h", - "webtouchnavigation.cpp", - "webtouchnavigation.h", - "webtouchphysics.cpp", - "webtouchphysics.h", - "webtouchphysicsinterface.cpp", - "webtouchphysicsinterface.h", - "webtouchscroller.cpp", - "webtouchscroller.h", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/mobileapp" - fileTags: ["install"] - prefix: "qtcreator/templates/mobileapp/" - files: [ - "app.pro", - "main.cpp", - "mainwindow.cpp", - "mainwindow.h", - "mainwindow.ui", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qt4project" - fileTags: ["install"] - prefix: "qtcreator/templates/qt4project/" - files: [ - "main.cpp", - "mywidget.cpp", - "mywidget.h", - "mywidget_form.cpp", - "mywidget_form.h", - "widget.ui", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qt4project/customwidgetwizard" - fileTags: ["install"] - prefix: "qtcreator/templates/qt4project/customwidgetwizard/" - files: [ - "tpl_collection.cpp", - "tpl_collection.h", - "tpl_plugin.pro", - "tpl_resources.qrc", - "tpl_single.cpp", - "tpl_single.h", - "tpl_widget.cpp", - "tpl_widget.h", - "tpl_widget_include.pri", - "tpl_widget_lib.pro", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qtquick2app" - fileTags: ["install"] - prefix: "qtcreator/templates/qtquick2app/" - files: [ - "app.pro", - "main.cpp", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qtquick2app/qml/app/qtquick20" - fileTags: ["install"] - prefix: "qtcreator/templates/qtquick2app/qml/app/qtquick20/" - files: [ - "main.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qtquick2app/qtquick2applicationviewer" - fileTags: ["install"] - prefix: "qtcreator/templates/qtquick2app/qtquick2applicationviewer/" - files: [ - "qtquick2applicationviewer.cpp", - "qtquick2applicationviewer.h", - "qtquick2applicationviewer.pri", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qtquickapp" - fileTags: ["install"] - prefix: "qtcreator/templates/qtquickapp/" - files: [ - "app.pro", - "main.cpp", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qtquickapp/qml/app/meego10" - fileTags: ["install"] - prefix: "qtcreator/templates/qtquickapp/qml/app/meego10/" - files: [ - "MainPage.qml", - "main.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qtquickapp/qml/app/qtquick10" - fileTags: ["install"] - prefix: "qtcreator/templates/qtquickapp/qml/app/qtquick10/" - files: [ - "main.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/qtquickapp/qmlapplicationviewer" - fileTags: ["install"] - prefix: "qtcreator/templates/qtquickapp/qmlapplicationviewer/" - files: [ - "qmlapplicationviewer.cpp", - "qmlapplicationviewer.h", - "qmlapplicationviewer.pri", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/shared" - fileTags: ["install"] - prefix: "qtcreator/templates/shared/" - files: [ - "app.desktop", - "deployment.pri", - "icon64.png", - "icon80.png", - "manifest.aegis", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/" - files: [ - "README.txt", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/bb-bardescriptor" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/bb-bardescriptor/" - files: [ - "bar-descriptor.xml", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/bb-guiapp" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/bb-guiapp/" - files: [ - "bar-descriptor.xml", - "icon.png", - "main.cpp", - "mainwidget.cpp", - "mainwidget.h", - "mainwidget.ui", - "project.pro", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/bb-qt5-bardescriptor" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/bb-qt5-bardescriptor/" - files: [ - "bar-descriptor.xml", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/bb-qt5-guiapp" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/bb-qt5-guiapp/" - files: [ - "bar-descriptor.xml", - "icon.png", - "main.cpp", - "mainwidget.cpp", - "mainwidget.h", - "mainwidget.ui", - "project.pro", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/bb-qt5-quick2app" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/bb-qt5-quick2app/" - files: [ - "bar-descriptor.xml", - "icon.png", - "main.cpp", - "project.pro", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/bb-qt5-quick2app/qml" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/bb-qt5-quick2app/qml/" - files: [ - "main.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/bb-quickapp" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/bb-quickapp/" - files: [ - "bar-descriptor.xml", - "icon.png", - "main.cpp", - "project.pro", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/bb-quickapp/qml" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/bb-quickapp/qml/" - files: [ - "main.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/helloworld" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/helloworld/" - files: [ - "console.png", - "main.cpp", - "project.pro", - "wizard_sample.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/listmodel" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/listmodel/" - files: [ - "listmodel.cpp", - "listmodel.h", - "wizard_sample.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/plaincapp" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/plaincapp/" - files: [ - "console.png", - "main.c", - "project.pro", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/plaincapp-cmake" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/plaincapp-cmake/" - files: [ - "CMakeLists.txt", - "console.png", - "main.c", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/plaincppapp" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/plaincppapp/" - files: [ - "console.png", - "main.cpp", - "project.pro", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/plaincppapp-cmake" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/plaincppapp-cmake/" - files: [ - "CMakeLists.txt", - "console.png", - "main.cpp", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/qml-extension" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/qml-extension/" - files: [ - "lib.png", - "object.cpp", - "object.h", - "plugin.cpp", - "plugin.h", - "project.pro", - "qmldir", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/qtcreatorplugin" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/qtcreatorplugin/" - files: [ - "MyPlugin.pluginspec.in", - "myplugin.cpp", - "myplugin.h", - "myplugin.pro", - "myplugin_global.h", - "mypluginconstants.h", - "qtcreator_logo_24.png", - "wizard.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/templates/wizards/scriptgeneratedproject" - fileTags: ["install"] - prefix: "qtcreator/templates/wizards/scriptgeneratedproject/" - files: [ - "generate.pl", - "wizard_sample.xml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/welcomescreen" - fileTags: ["install"] - prefix: "qtcreator/welcomescreen/" - files: [ - "develop.qml", - "examples.qml", - "examples_fallback.xml", - "gettingstarted.qml", - "images_areaofinterest.xml", - "qtcreator_tutorials.xml", - "tutorials.qml", - "welcomescreen.qml", - "welcomescreen.qmlproject", - ] - } - - Group { - qbs.installDir: "share/qtcreator/welcomescreen/dummydata" - fileTags: ["install"] - prefix: "qtcreator/welcomescreen/dummydata/" - files: [ - "examplesModel.qml", - "pagesModel.qml", - "projectList.qml", - "sessionList.qml", - "tutorialsModel.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/welcomescreen/widgets" - fileTags: ["install"] - prefix: "qtcreator/welcomescreen/widgets/" - files: [ - "CustomColors.qml", - "CustomFonts.qml", - "CustomTab.qml", - "CustomizedGridView.qml", - "Delegate.qml", - "GettingStartedItem.qml", - "IconAndLink.qml", - "LinkedText.qml", - "LinksBar.qml", - "Logo.qml", - "PageCaption.qml", - "PageLoader.qml", - "ProjectItem.qml", - "RecentProjects.qml", - "SearchBar.qml", - "SessionItem.qml", - "Sessions.qml", - "ToolTip.qml", - "qmldir", - ] - } - - Group { - qbs.installDir: "share/qtcreator/welcomescreen/widgets/dummydata" - fileTags: ["install"] - prefix: "qtcreator/welcomescreen/widgets/dummydata/" - files: [ - "examplesModel.qml", - "mockupTags.qml", - "pagesModel.qml", - "tabsModel.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/welcomescreen/widgets/dummydata/context" - fileTags: ["install"] - prefix: "qtcreator/welcomescreen/widgets/dummydata/context/" - files: [ - "ExampleDelegate.qml", - "ExampleGridView.qml", - ] - } - - Group { - qbs.installDir: "share/qtcreator/welcomescreen/widgets/images" - fileTags: ["install"] - prefix: "qtcreator/welcomescreen/widgets/images/" - files: [ - "arrowBig.png", - "arrow_down.png", - "arrow_up.png", - "bullet.png", - "dropshadow.png", - "gettingStarted01.png", - "gettingStarted02.png", - "gettingStarted03.png", - "gettingStarted04.png", - "info.png", - "more.png", - "qtcreator.png", - "tab.png", - ] - } - - Group { - qbs.installDir: "share/qtcreator/welcomescreen/widgets/images/icons" + condition: qbs.targetOS == "macx" + qbs.installDir: "share/qtcreator/scripts" fileTags: ["install"] - prefix: "qtcreator/welcomescreen/widgets/images/icons/" - files: [ - "adressbook.png", - "buildrun.png", - "clone.png", - "communityIcon.png", - "components.png", - "createIcon.png", - "ddays09.png", - "ddays10.png", - "ddays11.png", - "delete.png", - "developing_with_qt_creator.png", - "feedbackIcon.png", - "ico_community.png", - "labsIcon.png", - "openIcon.png", - "qt_quick_1.png", - "qt_quick_2.png", - "qt_quick_3.png", - "qt_sdk.png", - "qtquick.png", - "qwidget.png", - "rename.png", - "userguideIcon.png", - "videoIcon.png", - ] + files: "qtcreator/scripts/openTerminal.command" } Group { - qbs.installDir: "share/qtcreator/welcomescreen/widgets/images/mockup" - fileTags: ["install"] - prefix: "qtcreator/welcomescreen/widgets/images/mockup/" - files: [ - "designer-examples.png", - "desktop-examples.png", - "draganddrop-examples.png", - "itemview-examples.png", - "layout-examples.png", - "mainwindow-examples.png", - "network-examples.png", - "opengl-examples.png", - "penguin.png", - "qtscript-examples.png", - "thread-examples.png", - ] + qbs.installDir: "share/qtcreator/externaltools" + fileTags: ["install"] + prefix: "../src/share/qtcreator/externaltools/" + files: { + var list = [ + "lrelease.xml", + "lupdate.xml", + "qmlviewer.xml", + "sort.xml", + ] + switch (qbs.targetOS) { + case "windows": + list.push("notepad_win.xml"); + break; + case "mac": + list.push("vi_mac.xml"); + break; + default: + list.push("vi.xml"); + } + return list; + } } } diff --git a/share/update-share-qbs.py b/share/update-share-qbs.py deleted file mode 100755 index 2ff480c143..0000000000 --- a/share/update-share-qbs.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python -# -# Script for automatically updating share.qbs -# Usage: Just call it without arguments. -# - -import os -import posixpath as path -import inspect - -scriptFileName = path.basename(inspect.getfile(inspect.currentframe())) -shareDirPath = path.dirname(inspect.getfile(inspect.currentframe())) -print "updating " + shareDirPath + "/share.qbs" - -os.chdir(shareDirPath) -try: - f = open('share.qbs', 'w') -except: - print "Could not open share.qbs" - quit(1) - -def writeln(line): - f.write(line) - f.write("\n") - -writeln("import qbs.base 1.0") -writeln("") -writeln("Product {") -writeln(" type: [\"installed_content\"]") -writeln(" name: \"SharedContent\"") -writeln("") -writeln(" Group {") -writeln(" condition: qbs.targetOS == \"macx\"") -writeln(" qbs.installDir: \"share/qtcreator/scripts\"") -writeln(" fileTags: [\"install\"]") -writeln(" files: \"qtcreator/scripts/openTerminal.command\"") -writeln(" }") - -filenamedict = {} -blacklist = [ - scriptFileName, - "static.pro", "share.pro", "share.qbs", - "Info.plist.in" -] -blacklistdirs = [ - "qtcreator/translations", - "qtcreator/scripts" -] -for root, dirs, files in os.walk("."): - try: - dirs.remove('.moc') - dirs.remove('.rcc') - dirs.remove('.uic') - dirs.remove('.obj') - except: pass - - root = root.replace('\\', '/') - if root.startswith("./"): - root = path.normpath(root[2:]) - if root in blacklistdirs: - continue - for file in files: - if not (file in blacklist): - if not root in filenamedict: - filenamedict[root] = [file] - else: - filenamedict[root].append(file) - -for directory in sorted(filenamedict.iterkeys()): - prefix = directory - if not prefix.endswith("/"): - prefix += "/" - normalizedDirectory = path.normpath(directory.replace('\\', '/')) - writeln("") - writeln(" Group {") - writeln(" qbs.installDir: \"share/" + normalizedDirectory + "\"") - writeln(" fileTags: [\"install\"]") - writeln(" prefix: \"" + prefix + "\"") - writeln(" files: [") - for fname in sorted(filenamedict[directory]): - writeln(" \"" + fname + "\",") - writeln(" ]") - writeln(" }") - -writeln("}") -writeln("") - diff --git a/src/app/app.pro b/src/app/app.pro index a2a666dd1d..1242209065 100644 --- a/src/app/app.pro +++ b/src/app/app.pro @@ -5,7 +5,8 @@ TEMPLATE = app TARGET = $$IDE_APP_TARGET DESTDIR = $$IDE_APP_PATH -SOURCES += main.cpp +HEADERS += ../tools/qtcreatorcrashhandler/crashhandlersetup.h +SOURCES += main.cpp ../tools/qtcreatorcrashhandler/crashhandlersetup.cpp include(../rpath.pri) @@ -38,3 +39,5 @@ OTHER_FILES += qtcreator.rc \ $$PWD/app_version.h.in QMAKE_SUBSTITUTES += $$PWD/app_version.h.in + +CONFIG += no_batch diff --git a/src/app/main.cpp b/src/app/main.cpp index 557678fafc..a963816ae9 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -28,6 +28,7 @@ ****************************************************************************/ #include "qtsingleapplication.h" +#include "../tools/qtcreatorcrashhandler/crashhandlersetup.h" #include <app/app_version.h> #include <extensionsystem/iplugin.h> @@ -303,6 +304,8 @@ int main(int argc, char **argv) const int threadCount = QThreadPool::globalInstance()->maxThreadCount(); QThreadPool::globalInstance()->setMaxThreadCount(qMax(4, 2 * threadCount)); + setupCrashHandler(); // Display a backtrace once a serious signal is delivered. + #ifdef ENABLE_QT_BREAKPAD QtSystemExceptionHandler systemExceptionHandler; #endif @@ -506,5 +509,7 @@ int main(int argc, char **argv) QTimer::singleShot(100, &pluginManager, SLOT(startTests())); #endif - return app.exec(); + const int r = app.exec(); + cleanupCrashHandler(); + return r; } diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp index 31cacbcc43..13c4568fb7 100644 --- a/src/libs/3rdparty/cplusplus/AST.cpp +++ b/src/libs/3rdparty/cplusplus/AST.cpp @@ -403,12 +403,22 @@ unsigned CallAST::lastToken() const /** \generated */ unsigned CaptureAST::firstToken() const { + if (amper_token) + return amper_token; + if (identifier) + if (unsigned candidate = identifier->firstToken()) + return candidate; return 0; } /** \generated */ unsigned CaptureAST::lastToken() const { + if (identifier) + if (unsigned candidate = identifier->lastToken()) + return candidate; + if (amper_token) + return amper_token + 1; return 1; } @@ -1077,9 +1087,16 @@ unsigned EnumSpecifierAST::firstToken() const { if (enum_token) return enum_token; + if (key_token) + return key_token; if (name) if (unsigned candidate = name->firstToken()) return candidate; + if (colon_token) + return colon_token; + if (type_specifier_list) + if (unsigned candidate = type_specifier_list->firstToken()) + return candidate; if (lbrace_token) return lbrace_token; if (enumerator_list) @@ -1104,9 +1121,16 @@ unsigned EnumSpecifierAST::lastToken() const return candidate; if (lbrace_token) return lbrace_token + 1; + if (type_specifier_list) + if (unsigned candidate = type_specifier_list->lastToken()) + return candidate; + if (colon_token) + return colon_token + 1; if (name) if (unsigned candidate = name->lastToken()) return candidate; + if (key_token) + return key_token + 1; if (enum_token) return enum_token + 1; return 1; @@ -1369,6 +1393,8 @@ unsigned FunctionDeclaratorAST::firstToken() const if (cv_qualifier_list) if (unsigned candidate = cv_qualifier_list->firstToken()) return candidate; + if (ref_qualifier_token) + return ref_qualifier_token; if (exception_specification) if (unsigned candidate = exception_specification->firstToken()) return candidate; @@ -1393,6 +1419,8 @@ unsigned FunctionDeclaratorAST::lastToken() const if (exception_specification) if (unsigned candidate = exception_specification->lastToken()) return candidate; + if (ref_qualifier_token) + return ref_qualifier_token + 1; if (cv_qualifier_list) if (unsigned candidate = cv_qualifier_list->lastToken()) return candidate; @@ -1744,26 +1772,18 @@ unsigned MemInitializerAST::firstToken() const if (name) if (unsigned candidate = name->firstToken()) return candidate; - if (lparen_token) - return lparen_token; - if (expression_list) - if (unsigned candidate = expression_list->firstToken()) + if (expression) + if (unsigned candidate = expression->firstToken()) return candidate; - if (rparen_token) - return rparen_token; return 0; } /** \generated */ unsigned MemInitializerAST::lastToken() const { - if (rparen_token) - return rparen_token + 1; - if (expression_list) - if (unsigned candidate = expression_list->lastToken()) + if (expression) + if (unsigned candidate = expression->lastToken()) return candidate; - if (lparen_token) - return lparen_token + 1; if (name) if (unsigned candidate = name->lastToken()) return candidate; @@ -2043,33 +2063,7 @@ unsigned NewExpressionAST::lastToken() const } /** \generated */ -unsigned NewInitializerAST::firstToken() const -{ - if (lparen_token) - return lparen_token; - if (expression) - if (unsigned candidate = expression->firstToken()) - return candidate; - if (rparen_token) - return rparen_token; - return 0; -} - -/** \generated */ -unsigned NewInitializerAST::lastToken() const -{ - if (rparen_token) - return rparen_token + 1; - if (expression) - if (unsigned candidate = expression->lastToken()) - return candidate; - if (lparen_token) - return lparen_token + 1; - return 1; -} - -/** \generated */ -unsigned NewPlacementAST::firstToken() const +unsigned ExpressionListParenAST::firstToken() const { if (lparen_token) return lparen_token; @@ -2082,7 +2076,7 @@ unsigned NewPlacementAST::firstToken() const } /** \generated */ -unsigned NewPlacementAST::lastToken() const +unsigned ExpressionListParenAST::lastToken() const { if (rparen_token) return rparen_token + 1; @@ -3075,12 +3069,16 @@ unsigned PointerToMemberAST::firstToken() const if (cv_qualifier_list) if (unsigned candidate = cv_qualifier_list->firstToken()) return candidate; + if (ref_qualifier_token) + return ref_qualifier_token; return 0; } /** \generated */ unsigned PointerToMemberAST::lastToken() const { + if (ref_qualifier_token) + return ref_qualifier_token + 1; if (cv_qualifier_list) if (unsigned candidate = cv_qualifier_list->lastToken()) return candidate; @@ -3910,26 +3908,18 @@ unsigned TypeConstructorCallAST::firstToken() const if (type_specifier_list) if (unsigned candidate = type_specifier_list->firstToken()) return candidate; - if (lparen_token) - return lparen_token; - if (expression_list) - if (unsigned candidate = expression_list->firstToken()) + if (expression) + if (unsigned candidate = expression->firstToken()) return candidate; - if (rparen_token) - return rparen_token; return 0; } /** \generated */ unsigned TypeConstructorCallAST::lastToken() const { - if (rparen_token) - return rparen_token + 1; - if (expression_list) - if (unsigned candidate = expression_list->lastToken()) + if (expression) + if (unsigned candidate = expression->lastToken()) return candidate; - if (lparen_token) - return lparen_token + 1; if (type_specifier_list) if (unsigned candidate = type_specifier_list->lastToken()) return candidate; @@ -3998,26 +3988,18 @@ unsigned TypenameCallExpressionAST::firstToken() const if (name) if (unsigned candidate = name->firstToken()) return candidate; - if (lparen_token) - return lparen_token; - if (expression_list) - if (unsigned candidate = expression_list->firstToken()) + if (expression) + if (unsigned candidate = expression->firstToken()) return candidate; - if (rparen_token) - return rparen_token; return 0; } /** \generated */ unsigned TypenameCallExpressionAST::lastToken() const { - if (rparen_token) - return rparen_token + 1; - if (expression_list) - if (unsigned candidate = expression_list->lastToken()) + if (expression) + if (unsigned candidate = expression->lastToken()) return candidate; - if (lparen_token) - return lparen_token + 1; if (name) if (unsigned candidate = name->lastToken()) return candidate; @@ -4362,9 +4344,6 @@ unsigned RangeBasedForStatementAST::firstToken() const if (declarator) if (unsigned candidate = declarator->firstToken()) return candidate; - if (initializer) - if (unsigned candidate = initializer->firstToken()) - return candidate; if (colon_token) return colon_token; if (expression) @@ -4391,9 +4370,6 @@ unsigned RangeBasedForStatementAST::lastToken() const return candidate; if (colon_token) return colon_token + 1; - if (initializer) - if (unsigned candidate = initializer->lastToken()) - return candidate; if (declarator) if (unsigned candidate = declarator->lastToken()) return candidate; @@ -4407,3 +4383,67 @@ unsigned RangeBasedForStatementAST::lastToken() const return 1; } +/** \generated */ +unsigned AlignofExpressionAST::firstToken() const +{ + if (alignof_token) + return alignof_token; + if (lparen_token) + return lparen_token; + if (typeId) + if (unsigned candidate = typeId->firstToken()) + return candidate; + if (rparen_token) + return rparen_token; + return 0; +} + +/** \generated */ +unsigned AlignofExpressionAST::lastToken() const +{ + if (rparen_token) + return rparen_token + 1; + if (typeId) + if (unsigned candidate = typeId->lastToken()) + return candidate; + if (lparen_token) + return lparen_token + 1; + if (alignof_token) + return alignof_token + 1; + return 1; +} + +/** \generated */ +unsigned AliasDeclarationAST::firstToken() const +{ + if (using_token) + return using_token; + if (identifier_token) + return identifier_token; + if (equal_token) + return equal_token; + if (typeId) + if (unsigned candidate = typeId->firstToken()) + return candidate; + if (semicolon_token) + return semicolon_token; + return 0; +} + +/** \generated */ +unsigned AliasDeclarationAST::lastToken() const +{ + if (semicolon_token) + return semicolon_token + 1; + if (typeId) + if (unsigned candidate = typeId->lastToken()) + return candidate; + if (equal_token) + return equal_token + 1; + if (identifier_token) + return identifier_token + 1; + if (using_token) + return using_token + 1; + return 1; +} + diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index 24e031c72e..961bc2e1a7 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -125,6 +125,8 @@ public: virtual AST *clone(MemoryPool *pool) const = 0; virtual AccessDeclarationAST *asAccessDeclaration() { return 0; } + virtual AliasDeclarationAST *asAliasDeclaration() { return 0; } + virtual AlignofExpressionAST *asAlignofExpression() { return 0; } virtual ArrayAccessAST *asArrayAccess() { return 0; } virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; } virtual ArrayInitializerAST *asArrayInitializer() { return 0; } @@ -168,6 +170,7 @@ public: virtual ExceptionDeclarationAST *asExceptionDeclaration() { return 0; } virtual ExceptionSpecificationAST *asExceptionSpecification() { return 0; } virtual ExpressionAST *asExpression() { return 0; } + virtual ExpressionListParenAST *asExpressionListParen() { return 0; } virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return 0; } virtual ExpressionStatementAST *asExpressionStatement() { return 0; } virtual ForStatementAST *asForStatement() { return 0; } @@ -195,8 +198,6 @@ public: virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return 0; } virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return 0; } virtual NewExpressionAST *asNewExpression() { return 0; } - virtual NewInitializerAST *asNewInitializer() { return 0; } - virtual NewPlacementAST *asNewPlacement() { return 0; } virtual NewTypeIdAST *asNewTypeId() { return 0; } virtual NoExceptSpecificationAST *asNoExceptSpecification() { return 0; } virtual NumericLiteralAST *asNumericLiteral() { return 0; } @@ -1457,8 +1458,10 @@ public: ParameterDeclarationClauseAST *parameter_declaration_clause; unsigned rparen_token; SpecifierListAST *cv_qualifier_list; + unsigned ref_qualifier_token; ExceptionSpecificationAST *exception_specification; TrailingReturnTypeAST *trailing_return_type; + // Some FunctionDeclarators can also be interpreted as an initializer, like for 'A b(c);' ExpressionAST *as_cpp_initializer; public: // annotations @@ -1470,6 +1473,7 @@ public: , parameter_declaration_clause(0) , rparen_token(0) , cv_qualifier_list(0) + , ref_qualifier_token(0) , exception_specification(0) , trailing_return_type(0) , as_cpp_initializer(0) @@ -1630,7 +1634,10 @@ class CPLUSPLUS_EXPORT EnumSpecifierAST: public SpecifierAST { public: unsigned enum_token; + unsigned key_token; // struct, class or 0 NameAST *name; + unsigned colon_token; // can be 0 if there is no enum-base + SpecifierListAST *type_specifier_list; // ditto unsigned lbrace_token; EnumeratorListAST *enumerator_list; unsigned stray_comma_token; @@ -1642,7 +1649,10 @@ public: // annotations public: EnumSpecifierAST() : enum_token(0) + , key_token(0) , name(0) + , colon_token(0) + , type_specifier_list(0) , lbrace_token(0) , enumerator_list(0) , stray_comma_token(0) @@ -1918,7 +1928,6 @@ public: SpecifierListAST *type_specifier_list; DeclaratorAST *declarator; // or an expression - ExpressionAST *initializer; unsigned colon_token; ExpressionAST *expression; unsigned rparen_token; @@ -1933,7 +1942,6 @@ public: , lparen_token(0) , type_specifier_list(0) , declarator(0) - , initializer(0) , colon_token(0) , expression(0) , rparen_token(0) @@ -2138,16 +2146,13 @@ class CPLUSPLUS_EXPORT MemInitializerAST: public AST { public: NameAST *name; - unsigned lparen_token; - ExpressionListAST *expression_list; - unsigned rparen_token; + // either a BracedInitializerAST or a ExpressionListParenAST + ExpressionAST *expression; public: MemInitializerAST() : name(0) - , lparen_token(0) - , expression_list(0) - , rparen_token(0) + , expression(0) {} virtual MemInitializerAST *asMemInitializer() { return this; } @@ -2402,7 +2407,37 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; -class CPLUSPLUS_EXPORT NewPlacementAST: public AST +class CPLUSPLUS_EXPORT AliasDeclarationAST: public DeclarationAST +{ +public: + unsigned using_token; + unsigned identifier_token; + unsigned equal_token; + TypeIdAST *typeId; + unsigned semicolon_token; + +public: + AliasDeclarationAST() + : using_token(0) + , identifier_token(0) + , equal_token(0) + , typeId(0) + , semicolon_token(0) + {} + + virtual AliasDeclarationAST *asAliasDeclaration() { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual AliasDeclarationAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); + virtual bool match0(AST *, ASTMatcher *); +}; + +class CPLUSPLUS_EXPORT ExpressionListParenAST: public ExpressionAST { public: unsigned lparen_token; @@ -2410,18 +2445,18 @@ public: unsigned rparen_token; public: - NewPlacementAST() + ExpressionListParenAST() : lparen_token(0) , expression_list(0) , rparen_token(0) {} - virtual NewPlacementAST *asNewPlacement() { return this; } + virtual ExpressionListParenAST *asExpressionListParen() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NewPlacementAST *clone(MemoryPool *pool) const; + virtual ExpressionListParenAST *clone(MemoryPool *pool) const; protected: virtual void accept0(ASTVisitor *visitor); @@ -2459,7 +2494,7 @@ class CPLUSPLUS_EXPORT NewExpressionAST: public ExpressionAST public: unsigned scope_token; unsigned new_token; - NewPlacementAST *new_placement; + ExpressionListParenAST *new_placement; unsigned lparen_token; ExpressionAST *type_id; @@ -2467,7 +2502,7 @@ public: NewTypeIdAST *new_type_id; - NewInitializerAST *new_initializer; + ExpressionAST *new_initializer; // either ExpressionListParenAST or BracedInitializerAST public: NewExpressionAST() @@ -2493,32 +2528,6 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; -class CPLUSPLUS_EXPORT NewInitializerAST: public AST -{ -public: - unsigned lparen_token; - ExpressionAST *expression; - unsigned rparen_token; - -public: - NewInitializerAST() - : lparen_token(0) - , expression(0) - , rparen_token(0) - {} - - virtual NewInitializerAST *asNewInitializer() { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual NewInitializerAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); - virtual bool match0(AST *, ASTMatcher *); -}; - class CPLUSPLUS_EXPORT NewTypeIdAST: public AST { public: @@ -2768,17 +2777,13 @@ class CPLUSPLUS_EXPORT TypenameCallExpressionAST: public ExpressionAST public: unsigned typename_token; NameAST *name; - unsigned lparen_token; - ExpressionListAST *expression_list; - unsigned rparen_token; + ExpressionAST *expression; // either ExpressionListParenAST or BracedInitializerAST public: TypenameCallExpressionAST() : typename_token(0) , name(0) - , lparen_token(0) - , expression_list(0) - , rparen_token(0) + , expression(0) {} virtual TypenameCallExpressionAST *asTypenameCallExpression() { return this; } @@ -2797,16 +2802,12 @@ class CPLUSPLUS_EXPORT TypeConstructorCallAST: public ExpressionAST { public: SpecifierListAST *type_specifier_list; - unsigned lparen_token; - ExpressionListAST *expression_list; - unsigned rparen_token; + ExpressionAST *expression; // either ExpressionListParenAST or BracedInitializerAST public: TypeConstructorCallAST() : type_specifier_list(0) - , lparen_token(0) - , expression_list(0) - , rparen_token(0) + , expression(0) {} virtual TypeConstructorCallAST *asTypeConstructorCall() { return this; } @@ -2828,6 +2829,7 @@ public: NestedNameSpecifierListAST *nested_name_specifier_list; unsigned star_token; SpecifierListAST *cv_qualifier_list; + unsigned ref_qualifier_token; public: PointerToMemberAST() @@ -2835,6 +2837,7 @@ public: , nested_name_specifier_list(0) , star_token(0) , cv_qualifier_list(0) + , ref_qualifier_token(0) {} virtual PointerToMemberAST *asPointerToMember() { return this; } @@ -3025,6 +3028,34 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; +class CPLUSPLUS_EXPORT AlignofExpressionAST: public ExpressionAST +{ +public: + unsigned alignof_token; + unsigned lparen_token; + TypeIdAST *typeId; + unsigned rparen_token; + +public: + AlignofExpressionAST() + : alignof_token(0) + , lparen_token(0) + , typeId(0) + , rparen_token(0) + {} + + virtual AlignofExpressionAST *asAlignofExpression() { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual AlignofExpressionAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); + virtual bool match0(AST *, ASTMatcher *); +}; + class CPLUSPLUS_EXPORT PointerLiteralAST: public ExpressionAST { public: @@ -4364,7 +4395,13 @@ protected: class CaptureAST: public AST { public: + unsigned amper_token; + NameAST *identifier; + +public: CaptureAST() + : amper_token(0) + , identifier(0) {} virtual CaptureAST *asCapture() { return this; } diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp index 6a3b7a5dda..79e8b7818d 100644 --- a/src/libs/3rdparty/cplusplus/ASTClone.cpp +++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp @@ -487,6 +487,7 @@ FunctionDeclaratorAST *FunctionDeclaratorAST::clone(MemoryPool *pool) const for (SpecifierListAST *iter = cv_qualifier_list, **ast_iter = &ast->cv_qualifier_list; iter; iter = iter->next, ast_iter = &(*ast_iter)->next) *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0); + ast->ref_qualifier_token = ref_qualifier_token; if (exception_specification) ast->exception_specification = exception_specification->clone(pool); if (trailing_return_type) @@ -557,8 +558,13 @@ EnumSpecifierAST *EnumSpecifierAST::clone(MemoryPool *pool) const { EnumSpecifierAST *ast = new (pool) EnumSpecifierAST; ast->enum_token = enum_token; + ast->key_token = key_token; if (name) ast->name = name->clone(pool); + ast->colon_token = colon_token; + for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list; + iter; iter = iter->next, ast_iter = &(*ast_iter)->next) + *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0); ast->lbrace_token = lbrace_token; for (EnumeratorListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list; iter; iter = iter->next, ast_iter = &(*ast_iter)->next) @@ -680,8 +686,6 @@ RangeBasedForStatementAST *RangeBasedForStatementAST::clone(MemoryPool *pool) co *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0); if (declarator) ast->declarator = declarator->clone(pool); - if (initializer) - ast->initializer = initializer->clone(pool); ast->colon_token = colon_token; if (expression) ast->expression = expression->clone(pool); @@ -772,11 +776,8 @@ MemInitializerAST *MemInitializerAST::clone(MemoryPool *pool) const MemInitializerAST *ast = new (pool) MemInitializerAST; if (name) ast->name = name->clone(pool); - ast->lparen_token = lparen_token; - for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list; - iter; iter = iter->next, ast_iter = &(*ast_iter)->next) - *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0); - ast->rparen_token = rparen_token; + if (expression) + ast->expression = expression->clone(pool); return ast; } @@ -878,9 +879,21 @@ NamespaceAliasDefinitionAST *NamespaceAliasDefinitionAST::clone(MemoryPool *pool return ast; } -NewPlacementAST *NewPlacementAST::clone(MemoryPool *pool) const +AliasDeclarationAST *AliasDeclarationAST::clone(MemoryPool *pool) const { - NewPlacementAST *ast = new (pool) NewPlacementAST; + AliasDeclarationAST *ast = new (pool) AliasDeclarationAST; + ast->using_token = using_token; + ast->identifier_token = identifier_token; + ast->equal_token = equal_token; + if (typeId) + ast->typeId = typeId->clone(pool); + ast->semicolon_token = semicolon_token; + return ast; +} + +ExpressionListParenAST *ExpressionListParenAST::clone(MemoryPool *pool) const +{ + ExpressionListParenAST *ast = new (pool) ExpressionListParenAST; ast->lparen_token = lparen_token; for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list; iter; iter = iter->next, ast_iter = &(*ast_iter)->next) @@ -917,16 +930,6 @@ NewExpressionAST *NewExpressionAST::clone(MemoryPool *pool) const return ast; } -NewInitializerAST *NewInitializerAST::clone(MemoryPool *pool) const -{ - NewInitializerAST *ast = new (pool) NewInitializerAST; - ast->lparen_token = lparen_token; - if (expression) - ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - NewTypeIdAST *NewTypeIdAST::clone(MemoryPool *pool) const { NewTypeIdAST *ast = new (pool) NewTypeIdAST; @@ -1038,11 +1041,8 @@ TypenameCallExpressionAST *TypenameCallExpressionAST::clone(MemoryPool *pool) co ast->typename_token = typename_token; if (name) ast->name = name->clone(pool); - ast->lparen_token = lparen_token; - for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list; - iter; iter = iter->next, ast_iter = &(*ast_iter)->next) - *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0); - ast->rparen_token = rparen_token; + if (expression) + ast->expression = expression->clone(pool); return ast; } @@ -1052,11 +1052,8 @@ TypeConstructorCallAST *TypeConstructorCallAST::clone(MemoryPool *pool) const for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list; iter; iter = iter->next, ast_iter = &(*ast_iter)->next) *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0); - ast->lparen_token = lparen_token; - for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list; - iter; iter = iter->next, ast_iter = &(*ast_iter)->next) - *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0); - ast->rparen_token = rparen_token; + if (expression) + ast->expression = expression->clone(pool); return ast; } @@ -1071,6 +1068,7 @@ PointerToMemberAST *PointerToMemberAST::clone(MemoryPool *pool) const for (SpecifierListAST *iter = cv_qualifier_list, **ast_iter = &ast->cv_qualifier_list; iter; iter = iter->next, ast_iter = &(*ast_iter)->next) *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0); + ast->ref_qualifier_token = ref_qualifier_token; return ast; } @@ -1138,6 +1136,17 @@ SizeofExpressionAST *SizeofExpressionAST::clone(MemoryPool *pool) const return ast; } +AlignofExpressionAST *AlignofExpressionAST::clone(MemoryPool *pool) const +{ + AlignofExpressionAST *ast = new (pool) AlignofExpressionAST; + ast->alignof_token = alignof_token; + ast->lparen_token = lparen_token; + if (typeId) + ast->typeId = typeId->clone(pool); + ast->rparen_token = rparen_token; + return ast; +} + PointerLiteralAST *PointerLiteralAST::clone(MemoryPool *pool) const { PointerLiteralAST *ast = new (pool) PointerLiteralAST; @@ -1694,6 +1703,9 @@ LambdaCaptureAST *LambdaCaptureAST::clone(MemoryPool *pool) const CaptureAST *CaptureAST::clone(MemoryPool *pool) const { CaptureAST *ast = new (pool) CaptureAST; + ast->amper_token = amper_token; + if (identifier) + ast->identifier = identifier->clone(pool); return ast; } diff --git a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp index 81e74316b6..de743a2f7f 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp @@ -592,33 +592,33 @@ bool NamespaceAliasDefinitionAST::match0(AST *pattern, ASTMatcher *matcher) return false; } -bool NewPlacementAST::match0(AST *pattern, ASTMatcher *matcher) +bool AliasDeclarationAST::match0(AST *pattern, ASTMatcher *matcher) { - if (NewPlacementAST *_other = pattern->asNewPlacement()) + if (AliasDeclarationAST *_other = pattern->asAliasDeclaration()) return matcher->match(this, _other); return false; } -bool NewArrayDeclaratorAST::match0(AST *pattern, ASTMatcher *matcher) +bool ExpressionListParenAST::match0(AST *pattern, ASTMatcher *matcher) { - if (NewArrayDeclaratorAST *_other = pattern->asNewArrayDeclarator()) + if (ExpressionListParenAST *_other = pattern->asExpressionListParen()) return matcher->match(this, _other); return false; } -bool NewExpressionAST::match0(AST *pattern, ASTMatcher *matcher) +bool NewArrayDeclaratorAST::match0(AST *pattern, ASTMatcher *matcher) { - if (NewExpressionAST *_other = pattern->asNewExpression()) + if (NewArrayDeclaratorAST *_other = pattern->asNewArrayDeclarator()) return matcher->match(this, _other); return false; } -bool NewInitializerAST::match0(AST *pattern, ASTMatcher *matcher) +bool NewExpressionAST::match0(AST *pattern, ASTMatcher *matcher) { - if (NewInitializerAST *_other = pattern->asNewInitializer()) + if (NewExpressionAST *_other = pattern->asNewExpression()) return matcher->match(this, _other); return false; @@ -776,6 +776,14 @@ bool SizeofExpressionAST::match0(AST *pattern, ASTMatcher *matcher) return false; } +bool AlignofExpressionAST::match0(AST *pattern, ASTMatcher *matcher) +{ + if (AlignofExpressionAST *_other = pattern->asAlignofExpression()) + return matcher->match(this, _other); + + return false; +} + bool PointerLiteralAST::match0(AST *pattern, ASTMatcher *matcher) { if (PointerLiteralAST *_other = pattern->asPointerLiteral()) diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp index a773c07b3e..091a5dfd84 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp @@ -809,6 +809,8 @@ bool ASTMatcher::match(FunctionDeclaratorAST *node, FunctionDeclaratorAST *patte else if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this)) return false; + pattern->ref_qualifier_token = node->ref_qualifier_token; + if (! pattern->exception_specification) pattern->exception_specification = node->exception_specification; else if (! AST::match(node->exception_specification, pattern->exception_specification, this)) @@ -933,11 +935,20 @@ bool ASTMatcher::match(EnumSpecifierAST *node, EnumSpecifierAST *pattern) pattern->enum_token = node->enum_token; + pattern->key_token = node->key_token; + if (! pattern->name) pattern->name = node->name; else if (! AST::match(node->name, pattern->name, this)) return false; + pattern->colon_token = node->colon_token; + + if (! pattern->type_specifier_list) + pattern->type_specifier_list = node->type_specifier_list; + else if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this)) + return false; + pattern->lbrace_token = node->lbrace_token; if (! pattern->enumerator_list) @@ -1152,11 +1163,6 @@ bool ASTMatcher::match(RangeBasedForStatementAST *node, RangeBasedForStatementAS else if (! AST::match(node->declarator, pattern->declarator, this)) return false; - if (! pattern->initializer) - pattern->initializer = node->initializer; - else if (! AST::match(node->initializer, pattern->initializer, this)) - return false; - pattern->colon_token = node->colon_token; if (! pattern->expression) @@ -1319,15 +1325,11 @@ bool ASTMatcher::match(MemInitializerAST *node, MemInitializerAST *pattern) else if (! AST::match(node->name, pattern->name, this)) return false; - pattern->lparen_token = node->lparen_token; - - if (! pattern->expression_list) - pattern->expression_list = node->expression_list; - else if (! AST::match(node->expression_list, pattern->expression_list, this)) + if (! pattern->expression) + pattern->expression = node->expression; + else if (! AST::match(node->expression, pattern->expression, this)) return false; - pattern->rparen_token = node->rparen_token; - return true; } @@ -1492,7 +1494,28 @@ bool ASTMatcher::match(NamespaceAliasDefinitionAST *node, NamespaceAliasDefiniti return true; } -bool ASTMatcher::match(NewPlacementAST *node, NewPlacementAST *pattern) +bool ASTMatcher::match(AliasDeclarationAST *node, AliasDeclarationAST *pattern) +{ + (void) node; + (void) pattern; + + pattern->using_token = node->using_token; + + pattern->identifier_token = node->identifier_token; + + pattern->equal_token = node->equal_token; + + if (! pattern->typeId) + pattern->typeId = node->typeId; + else if (! AST::match(node->typeId, pattern->typeId, this)) + return false; + + pattern->semicolon_token = node->semicolon_token; + + return true; +} + +bool ASTMatcher::match(ExpressionListParenAST *node, ExpressionListParenAST *pattern) { (void) node; (void) pattern; @@ -1562,23 +1585,6 @@ bool ASTMatcher::match(NewExpressionAST *node, NewExpressionAST *pattern) return true; } -bool ASTMatcher::match(NewInitializerAST *node, NewInitializerAST *pattern) -{ - (void) node; - (void) pattern; - - pattern->lparen_token = node->lparen_token; - - if (! pattern->expression) - pattern->expression = node->expression; - else if (! AST::match(node->expression, pattern->expression, this)) - return false; - - pattern->rparen_token = node->rparen_token; - - return true; -} - bool ASTMatcher::match(NewTypeIdAST *node, NewTypeIdAST *pattern) { (void) node; @@ -1768,15 +1774,11 @@ bool ASTMatcher::match(TypenameCallExpressionAST *node, TypenameCallExpressionAS else if (! AST::match(node->name, pattern->name, this)) return false; - pattern->lparen_token = node->lparen_token; - - if (! pattern->expression_list) - pattern->expression_list = node->expression_list; - else if (! AST::match(node->expression_list, pattern->expression_list, this)) + if (! pattern->expression) + pattern->expression = node->expression; + else if (! AST::match(node->expression, pattern->expression, this)) return false; - pattern->rparen_token = node->rparen_token; - return true; } @@ -1790,15 +1792,11 @@ bool ASTMatcher::match(TypeConstructorCallAST *node, TypeConstructorCallAST *pat else if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this)) return false; - pattern->lparen_token = node->lparen_token; - - if (! pattern->expression_list) - pattern->expression_list = node->expression_list; - else if (! AST::match(node->expression_list, pattern->expression_list, this)) + if (! pattern->expression) + pattern->expression = node->expression; + else if (! AST::match(node->expression, pattern->expression, this)) return false; - pattern->rparen_token = node->rparen_token; - return true; } @@ -1821,6 +1819,8 @@ bool ASTMatcher::match(PointerToMemberAST *node, PointerToMemberAST *pattern) else if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this)) return false; + pattern->ref_qualifier_token = node->ref_qualifier_token; + return true; } @@ -1925,6 +1925,25 @@ bool ASTMatcher::match(SizeofExpressionAST *node, SizeofExpressionAST *pattern) return true; } +bool ASTMatcher::match(AlignofExpressionAST *node, AlignofExpressionAST *pattern) +{ + (void) node; + (void) pattern; + + pattern->alignof_token = node->alignof_token; + + pattern->lparen_token = node->lparen_token; + + if (! pattern->typeId) + pattern->typeId = node->typeId; + else if (! AST::match(node->typeId, pattern->typeId, this)) + return false; + + pattern->rparen_token = node->rparen_token; + + return true; +} + bool ASTMatcher::match(PointerLiteralAST *node, PointerLiteralAST *pattern) { (void) node; @@ -2879,6 +2898,13 @@ bool ASTMatcher::match(CaptureAST *node, CaptureAST *pattern) (void) node; (void) pattern; + pattern->amper_token = node->amper_token; + + if (! pattern->identifier) + pattern->identifier = node->identifier; + else if (! AST::match(node->identifier, pattern->identifier, this)) + return false; + return true; } diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.h b/src/libs/3rdparty/cplusplus/ASTMatcher.h index 202a577741..29842253cd 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.h +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.h @@ -32,6 +32,8 @@ public: virtual ~ASTMatcher(); virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern); + virtual bool match(AliasDeclarationAST *node, AliasDeclarationAST *pattern); + virtual bool match(AlignofExpressionAST *node, AlignofExpressionAST *pattern); virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern); virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern); virtual bool match(ArrayInitializerAST *node, ArrayInitializerAST *pattern); @@ -71,6 +73,7 @@ public: virtual bool match(EnumSpecifierAST *node, EnumSpecifierAST *pattern); virtual bool match(EnumeratorAST *node, EnumeratorAST *pattern); virtual bool match(ExceptionDeclarationAST *node, ExceptionDeclarationAST *pattern); + virtual bool match(ExpressionListParenAST *node, ExpressionListParenAST *pattern); virtual bool match(ExpressionOrDeclarationStatementAST *node, ExpressionOrDeclarationStatementAST *pattern); virtual bool match(ExpressionStatementAST *node, ExpressionStatementAST *pattern); virtual bool match(ForStatementAST *node, ForStatementAST *pattern); @@ -97,8 +100,6 @@ public: virtual bool match(NestedNameSpecifierAST *node, NestedNameSpecifierAST *pattern); virtual bool match(NewArrayDeclaratorAST *node, NewArrayDeclaratorAST *pattern); virtual bool match(NewExpressionAST *node, NewExpressionAST *pattern); - virtual bool match(NewInitializerAST *node, NewInitializerAST *pattern); - virtual bool match(NewPlacementAST *node, NewPlacementAST *pattern); virtual bool match(NewTypeIdAST *node, NewTypeIdAST *pattern); virtual bool match(NoExceptSpecificationAST *node, NoExceptSpecificationAST *pattern); virtual bool match(NumericLiteralAST *node, NumericLiteralAST *pattern); diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h index 41ad4964b2..fcf1f56d04 100644 --- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h +++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h @@ -374,10 +374,11 @@ public: return __ast; } - EnumSpecifierAST *EnumSpecifier(NameAST *name = 0, EnumeratorListAST *enumerator_list = 0) + EnumSpecifierAST *EnumSpecifier(NameAST *name = 0, SpecifierListAST *type_specifier_list = 0, EnumeratorListAST *enumerator_list = 0) { EnumSpecifierAST *__ast = new (&pool) EnumSpecifierAST; __ast->name = name; + __ast->type_specifier_list = type_specifier_list; __ast->enumerator_list = enumerator_list; return __ast; } @@ -447,12 +448,11 @@ public: return __ast; } - RangeBasedForStatementAST *RangeBasedForStatement(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0, ExpressionAST *initializer = 0, ExpressionAST *expression = 0, StatementAST *statement = 0) + RangeBasedForStatementAST *RangeBasedForStatement(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0, ExpressionAST *expression = 0, StatementAST *statement = 0) { RangeBasedForStatementAST *__ast = new (&pool) RangeBasedForStatementAST; __ast->type_specifier_list = type_specifier_list; __ast->declarator = declarator; - __ast->initializer = initializer; __ast->expression = expression; __ast->statement = statement; return __ast; @@ -505,11 +505,11 @@ public: return __ast; } - MemInitializerAST *MemInitializer(NameAST *name = 0, ExpressionListAST *expression_list = 0) + MemInitializerAST *MemInitializer(NameAST *name = 0, ExpressionAST *expression = 0) { MemInitializerAST *__ast = new (&pool) MemInitializerAST; __ast->name = name; - __ast->expression_list = expression_list; + __ast->expression = expression; return __ast; } @@ -578,9 +578,16 @@ public: return __ast; } - NewPlacementAST *NewPlacement(ExpressionListAST *expression_list = 0) + AliasDeclarationAST *AliasDeclaration(TypeIdAST *typeId = 0) { - NewPlacementAST *__ast = new (&pool) NewPlacementAST; + AliasDeclarationAST *__ast = new (&pool) AliasDeclarationAST; + __ast->typeId = typeId; + return __ast; + } + + ExpressionListParenAST *ExpressionListParen(ExpressionListAST *expression_list = 0) + { + ExpressionListParenAST *__ast = new (&pool) ExpressionListParenAST; __ast->expression_list = expression_list; return __ast; } @@ -592,7 +599,7 @@ public: return __ast; } - NewExpressionAST *NewExpression(NewPlacementAST *new_placement = 0, ExpressionAST *type_id = 0, NewTypeIdAST *new_type_id = 0, NewInitializerAST *new_initializer = 0) + NewExpressionAST *NewExpression(ExpressionListParenAST *new_placement = 0, ExpressionAST *type_id = 0, NewTypeIdAST *new_type_id = 0, ExpressionAST *new_initializer = 0) { NewExpressionAST *__ast = new (&pool) NewExpressionAST; __ast->new_placement = new_placement; @@ -602,13 +609,6 @@ public: return __ast; } - NewInitializerAST *NewInitializer(ExpressionAST *expression = 0) - { - NewInitializerAST *__ast = new (&pool) NewInitializerAST; - __ast->expression = expression; - return __ast; - } - NewTypeIdAST *NewTypeId(SpecifierListAST *type_specifier_list = 0, PtrOperatorListAST *ptr_operator_list = 0, NewArrayDeclaratorListAST *new_array_declarator_list = 0) { NewTypeIdAST *__ast = new (&pool) NewTypeIdAST; @@ -678,19 +678,19 @@ public: return __ast; } - TypenameCallExpressionAST *TypenameCallExpression(NameAST *name = 0, ExpressionListAST *expression_list = 0) + TypenameCallExpressionAST *TypenameCallExpression(NameAST *name = 0, ExpressionAST *expression = 0) { TypenameCallExpressionAST *__ast = new (&pool) TypenameCallExpressionAST; __ast->name = name; - __ast->expression_list = expression_list; + __ast->expression = expression; return __ast; } - TypeConstructorCallAST *TypeConstructorCall(SpecifierListAST *type_specifier_list = 0, ExpressionListAST *expression_list = 0) + TypeConstructorCallAST *TypeConstructorCall(SpecifierListAST *type_specifier_list = 0, ExpressionAST *expression = 0) { TypeConstructorCallAST *__ast = new (&pool) TypeConstructorCallAST; __ast->type_specifier_list = type_specifier_list; - __ast->expression_list = expression_list; + __ast->expression = expression; return __ast; } @@ -747,6 +747,13 @@ public: return __ast; } + AlignofExpressionAST *AlignofExpression(TypeIdAST *typeId = 0) + { + AlignofExpressionAST *__ast = new (&pool) AlignofExpressionAST; + __ast->typeId = typeId; + return __ast; + } + PointerLiteralAST *PointerLiteral() { PointerLiteralAST *__ast = new (&pool) PointerLiteralAST; @@ -1100,9 +1107,10 @@ public: return __ast; } - CaptureAST *Capture() + CaptureAST *Capture(NameAST *identifier = 0) { CaptureAST *__ast = new (&pool) CaptureAST; + __ast->identifier = identifier; return __ast; } diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp index f30523ee53..24c5a2372f 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp +++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp @@ -410,6 +410,7 @@ void EnumSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { accept(name, visitor); + accept(type_specifier_list, visitor); accept(enumerator_list, visitor); } visitor->endVisit(this); @@ -493,7 +494,6 @@ void RangeBasedForStatementAST::accept0(ASTVisitor *visitor) if (visitor->visit(this)) { accept(type_specifier_list, visitor); accept(declarator, visitor); - accept(initializer, visitor); accept(expression, visitor); accept(statement, visitor); } @@ -557,7 +557,7 @@ void MemInitializerAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { accept(name, visitor); - accept(expression_list, visitor); + accept(expression, visitor); } visitor->endVisit(this); } @@ -636,7 +636,15 @@ void NamespaceAliasDefinitionAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } -void NewPlacementAST::accept0(ASTVisitor *visitor) +void AliasDeclarationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + accept(typeId, visitor); + } + visitor->endVisit(this); +} + +void ExpressionListParenAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { accept(expression_list, visitor); @@ -663,14 +671,6 @@ void NewExpressionAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } -void NewInitializerAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - accept(expression, visitor); - } - visitor->endVisit(this); -} - void NewTypeIdAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { @@ -753,7 +753,7 @@ void TypenameCallExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { accept(name, visitor); - accept(expression_list, visitor); + accept(expression, visitor); } visitor->endVisit(this); } @@ -762,7 +762,7 @@ void TypeConstructorCallAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { accept(type_specifier_list, visitor); - accept(expression_list, visitor); + accept(expression, visitor); } visitor->endVisit(this); } @@ -828,6 +828,14 @@ void SizeofExpressionAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void AlignofExpressionAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + accept(typeId, visitor); + } + visitor->endVisit(this); +} + void PointerLiteralAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { @@ -1229,6 +1237,7 @@ void LambdaCaptureAST::accept0(ASTVisitor *visitor) void CaptureAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { + accept(identifier, visitor); } visitor->endVisit(this); } diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.h b/src/libs/3rdparty/cplusplus/ASTVisitor.h index eab93a20bb..a7d3f728f6 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisitor.h +++ b/src/libs/3rdparty/cplusplus/ASTVisitor.h @@ -74,6 +74,8 @@ public: virtual void postVisit(AST *) {} virtual bool visit(AccessDeclarationAST *) { return true; } + virtual bool visit(AliasDeclarationAST *) { return true; } + virtual bool visit(AlignofExpressionAST *) { return true; } virtual bool visit(ArrayAccessAST *) { return true; } virtual bool visit(ArrayDeclaratorAST *) { return true; } virtual bool visit(ArrayInitializerAST *) { return true; } @@ -113,6 +115,7 @@ public: virtual bool visit(EnumSpecifierAST *) { return true; } virtual bool visit(EnumeratorAST *) { return true; } virtual bool visit(ExceptionDeclarationAST *) { return true; } + virtual bool visit(ExpressionListParenAST *) { return true; } virtual bool visit(ExpressionOrDeclarationStatementAST *) { return true; } virtual bool visit(ExpressionStatementAST *) { return true; } virtual bool visit(ForStatementAST *) { return true; } @@ -139,8 +142,6 @@ public: virtual bool visit(NestedNameSpecifierAST *) { return true; } virtual bool visit(NewArrayDeclaratorAST *) { return true; } virtual bool visit(NewExpressionAST *) { return true; } - virtual bool visit(NewInitializerAST *) { return true; } - virtual bool visit(NewPlacementAST *) { return true; } virtual bool visit(NewTypeIdAST *) { return true; } virtual bool visit(NoExceptSpecificationAST *) { return true; } virtual bool visit(NumericLiteralAST *) { return true; } @@ -218,6 +219,8 @@ public: virtual bool visit(WhileStatementAST *) { return true; } virtual void endVisit(AccessDeclarationAST *) {} + virtual void endVisit(AliasDeclarationAST *) {} + virtual void endVisit(AlignofExpressionAST *) {} virtual void endVisit(ArrayAccessAST *) {} virtual void endVisit(ArrayDeclaratorAST *) {} virtual void endVisit(ArrayInitializerAST *) {} @@ -257,6 +260,7 @@ public: virtual void endVisit(EnumSpecifierAST *) {} virtual void endVisit(EnumeratorAST *) {} virtual void endVisit(ExceptionDeclarationAST *) {} + virtual void endVisit(ExpressionListParenAST *) {} virtual void endVisit(ExpressionOrDeclarationStatementAST *) {} virtual void endVisit(ExpressionStatementAST *) {} virtual void endVisit(ForStatementAST *) {} @@ -283,8 +287,6 @@ public: virtual void endVisit(NestedNameSpecifierAST *) {} virtual void endVisit(NewArrayDeclaratorAST *) {} virtual void endVisit(NewExpressionAST *) {} - virtual void endVisit(NewInitializerAST *) {} - virtual void endVisit(NewPlacementAST *) {} virtual void endVisit(NewTypeIdAST *) {} virtual void endVisit(NoExceptSpecificationAST *) {} virtual void endVisit(NumericLiteralAST *) {} diff --git a/src/libs/3rdparty/cplusplus/ASTfwd.h b/src/libs/3rdparty/cplusplus/ASTfwd.h index f429fe7101..722a5b0d38 100644 --- a/src/libs/3rdparty/cplusplus/ASTfwd.h +++ b/src/libs/3rdparty/cplusplus/ASTfwd.h @@ -32,6 +32,8 @@ class ASTVisitor; class ASTMatcher; class AccessDeclarationAST; +class AliasDeclarationAST; +class AlignofExpressionAST; class ArrayAccessAST; class ArrayDeclaratorAST; class ArrayInitializerAST; @@ -75,6 +77,7 @@ class EnumeratorAST; class ExceptionDeclarationAST; class ExceptionSpecificationAST; class ExpressionAST; +class ExpressionListParenAST; class ExpressionOrDeclarationStatementAST; class ExpressionStatementAST; class ForStatementAST; @@ -102,8 +105,6 @@ class NestedExpressionAST; class NestedNameSpecifierAST; class NewArrayDeclaratorAST; class NewExpressionAST; -class NewInitializerAST; -class NewPlacementAST; class NewTypeIdAST; class NoExceptSpecificationAST; class NumericLiteralAST; diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 380b0ccaef..ef71f2900e 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -517,9 +517,7 @@ void Bind::memInitializer(MemInitializerAST *ast, Function *fun) /*const Name *name =*/ this->name(ast->name); Scope *previousScope = switchScope(fun); - for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - /*ExpressionTy value =*/ this->expression(it->value); - } + this->expression(ast->expression); (void) switchScope(previousScope); } @@ -539,14 +537,18 @@ const Name *Bind::nestedNameSpecifier(NestedNameSpecifierAST *ast) return class_or_namespace_name; } -bool Bind::visit(NewPlacementAST *ast) +bool Bind::visit(ExpressionListParenAST *ast) { - (void) ast; - assert(!"unreachable"); + // unsigned lparen_token = ast->lparen_token; + for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { + /*ExpressionTy value =*/ this->expression(it->value); + } + // unsigned rparen_token = ast->rparen_token; + return false; } -void Bind::newPlacement(NewPlacementAST *ast) +void Bind::newPlacement(ExpressionListParenAST *ast) { if (! ast) return; @@ -578,23 +580,6 @@ FullySpecifiedType Bind::newArrayDeclarator(NewArrayDeclaratorAST *ast, const Fu return type; } -bool Bind::visit(NewInitializerAST *ast) -{ - (void) ast; - assert(!"unreachable"); - return false; -} - -void Bind::newInitializer(NewInitializerAST *ast) -{ - if (! ast) - return; - - // unsigned lparen_token = ast->lparen_token; - ExpressionTy expression = this->expression(ast->expression); - // unsigned rparen_token = ast->rparen_token; -} - bool Bind::visit(NewTypeIdAST *ast) { (void) ast; @@ -1084,6 +1069,7 @@ void Bind::capture(CaptureAST *ast) if (! ast) return; + name(ast->identifier); } bool Bind::visit(LambdaDeclaratorAST *ast) @@ -1330,7 +1316,6 @@ bool Bind::visit(RangeBasedForStatementAST *ast) block->addMember(decl); } - /*ExpressionTy initializer =*/ this->expression(ast->initializer); /*ExpressionTy expression =*/ this->expression(ast->expression); this->statement(ast->statement); (void) switchScope(previousScope); @@ -1636,7 +1621,7 @@ bool Bind::visit(NewExpressionAST *ast) ExpressionTy type_id = this->expression(ast->type_id); // unsigned rparen_token = ast->rparen_token; this->newTypeId(ast->new_type_id); - this->newInitializer(ast->new_initializer); + this->expression(ast->new_initializer); return false; } @@ -1653,11 +1638,7 @@ bool Bind::visit(TypenameCallExpressionAST *ast) { // unsigned typename_token = ast->typename_token; /*const Name *name =*/ this->name(ast->name); - // unsigned lparen_token = ast->lparen_token; - for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - ExpressionTy value = this->expression(it->value); - } - // unsigned rparen_token = ast->rparen_token; + this->expression(ast->expression); return false; } @@ -1667,11 +1648,7 @@ bool Bind::visit(TypeConstructorCallAST *ast) for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) { type = this->specifier(it->value, type); } - // unsigned lparen_token = ast->lparen_token; - for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - ExpressionTy value = this->expression(it->value); - } - // unsigned rparen_token = ast->rparen_token; + this->expression(ast->expression); return false; } @@ -1804,7 +1781,7 @@ bool Bind::visit(BracedInitializerAST *ast) { // unsigned lbrace_token = ast->lbrace_token; for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - ExpressionTy value = this->expression(it->value); + /*ExpressionTy value =*/ this->expression(it->value); } // unsigned comma_token = ast->comma_token; // unsigned rbrace_token = ast->rbrace_token; @@ -1901,7 +1878,10 @@ bool Bind::visit(SimpleDeclarationAST *ast) if (Function *funTy = decl->type()->asFunctionType()) { funTy->setMethodKey(methodKey); - if (funTy->isVirtual() && it->value->equal_token) + bool pureVirtualInit = it->value->equal_token + && it->value->initializer + && it->value->initializer->asNumericLiteral(); + if (funTy->isVirtual() && pureVirtualInit) funTy->setPureVirtual(true); } } @@ -2985,6 +2965,8 @@ bool Bind::visit(EnumSpecifierAST *ast) Enum *e = control()->newEnum(sourceLocation, enumName); e->setStartOffset(tokenAt(sourceLocation).end()); // at the end of the enum or identifier token. e->setEndOffset(tokenAt(ast->lastToken() - 1).end()); + if (ast->key_token) + e->setScoped(true); ast->symbol = e; _scope->addMember(e); diff --git a/src/libs/3rdparty/cplusplus/Bind.h b/src/libs/3rdparty/cplusplus/Bind.h index de0cf12557..93022b9af7 100644 --- a/src/libs/3rdparty/cplusplus/Bind.h +++ b/src/libs/3rdparty/cplusplus/Bind.h @@ -85,9 +85,8 @@ protected: FullySpecifiedType exceptionSpecification(ExceptionSpecificationAST *ast, const FullySpecifiedType &init); void memInitializer(MemInitializerAST *ast, Function *fun); const Name *nestedNameSpecifier(NestedNameSpecifierAST *ast); - void newPlacement(NewPlacementAST *ast); + void newPlacement(ExpressionListParenAST *ast); FullySpecifiedType newArrayDeclarator(NewArrayDeclaratorAST *ast, const FullySpecifiedType &init); - void newInitializer(NewInitializerAST *ast); FullySpecifiedType newTypeId(NewTypeIdAST *ast); OperatorNameId::Kind cppOperator(OperatorAST *ast); void parameterDeclarationClause(ParameterDeclarationClauseAST *ast, unsigned lparen_token, Function *fun); @@ -122,9 +121,7 @@ protected: virtual bool visit(DynamicExceptionSpecificationAST *ast); virtual bool visit(MemInitializerAST *ast); virtual bool visit(NestedNameSpecifierAST *ast); - virtual bool visit(NewPlacementAST *ast); virtual bool visit(NewArrayDeclaratorAST *ast); - virtual bool visit(NewInitializerAST *ast); virtual bool visit(NewTypeIdAST *ast); virtual bool visit(OperatorAST *ast); virtual bool visit(ParameterDeclarationClauseAST *ast); @@ -199,6 +196,7 @@ protected: virtual bool visit(ObjCSelectorExpressionAST *ast); virtual bool visit(LambdaExpressionAST *ast); virtual bool visit(BracedInitializerAST *ast); + virtual bool visit(ExpressionListParenAST *ast); // DeclarationAST virtual bool visit(SimpleDeclarationAST *ast); diff --git a/src/libs/3rdparty/cplusplus/Keywords.cpp b/src/libs/3rdparty/cplusplus/Keywords.cpp index cac51a4fd6..1da78381ac 100644 --- a/src/libs/3rdparty/cplusplus/Keywords.cpp +++ b/src/libs/3rdparty/cplusplus/Keywords.cpp @@ -573,6 +573,26 @@ static inline int classify7(const char *s, bool q, bool x) { } } } + else if (x && s[0] == 'a') { + if (s[1] == 'l') { + if (s[2] == 'i') { + if (s[3] == 'g') { + if (s[4] == 'n') { + if (s[5] == 'a') { + if (s[6] == 's') { + return T_ALIGNAS; + } + } + else if (s[5] == 'o') { + if (s[6] == 'f') { + return T_ALIGNOF; + } + } + } + } + } + } + } else if (s[0] == 'd') { if (s[1] == 'e') { if (s[2] == 'f') { diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index e1800229e7..c7d00c9817 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -28,7 +28,7 @@ #include "QtContextKeywords.h" #include <string> #include <cstdio> // for putchar - +#include <QDebug> #ifdef _MSC_VER # define va_copy(dst, src) ((dst) = (src)) #elif defined(__INTEL_COMPILER) && !defined(va_copy) @@ -107,7 +107,7 @@ inline int precedence(int tokenKind, bool templateArguments) { // ### this will/might need some tuning for C++0x // (see: [temp.names]p3) - if (templateArguments && tokenKind == T_GREATER) + if (templateArguments && (tokenKind == T_GREATER || tokenKind == T_GREATER_GREATER)) return -1; if (lookAtAssignmentOperator(tokenKind)) @@ -212,6 +212,11 @@ bool Parser::switchTemplateArguments(bool templateArguments) return previousTemplateArguments; } +bool Parser::maybeSplitGreaterGreaterToken(int n) +{ + return _translationUnit->maybeSplitGreaterGreaterToken(_tokenIndex + n - 1); +} + bool Parser::blockErrors(bool block) { return _translationUnit->blockErrors(block); } @@ -367,6 +372,18 @@ bool Parser::skip(int l, int r) return false; } +int Parser::find(int token, int stopAt) +{ + for (int i = 1; ; ++i) { + const int tk = LA(i); + if (!tk || tk == stopAt) + return 0; + if (tk == token) + return i; + } + return 0; +} + void Parser::match(int kind, unsigned *token) { if (LA() == kind) @@ -421,9 +438,9 @@ bool Parser::parseTemplateId(NameAST *&node, unsigned template_token) ast->template_token = template_token; ast->identifier_token = consumeToken(); ast->less_token = consumeToken(); - if (LA() == T_GREATER || parseTemplateArgumentList( + if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER || parseTemplateArgumentList( ast->template_argument_list)) { - if (LA() == T_GREATER) { + if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER) { ast->greater_token = consumeToken(); node = ast; return true; @@ -811,6 +828,9 @@ bool Parser::parseUsing(DeclarationAST *&node) if (LA(2) == T_NAMESPACE) return parseUsingDirective(node); + if (_cxx0xEnabled && LA(2) == T_IDENTIFIER && parseAliasDeclaration(node)) + return true; + UsingAST *ast = new (_pool) UsingAST; ast->using_token = consumeToken(); @@ -840,6 +860,37 @@ bool Parser::parseUsingDirective(DeclarationAST *&node) return false; } +// alias-declaration = 'using' identifier attribute-specifier-seq(opt) '=' type-id ';' +bool Parser::parseAliasDeclaration(DeclarationAST *&node) +{ + DEBUG_THIS_RULE(); + if (LA() != T_USING || LA(2) != T_IDENTIFIER) + return false; + + if (!find(T_EQUAL, T_SEMICOLON)) + return false; + + AliasDeclarationAST *alias = new (_pool) AliasDeclarationAST; + alias->using_token = consumeToken(); + alias->identifier_token = consumeToken(); + + // ### attributes! + while (LA() != T_EQUAL) + consumeToken(); + + alias->equal_token = consumeToken(); + + ExpressionAST *expr = 0; + parseTypeId(expr); + if (expr) + alias->typeId = expr->asTypeId(); + + match(T_SEMICOLON, &alias->semicolon_token); + + node = alias; + return true; +} + bool Parser::parseConversionFunctionId(NameAST *&node) { DEBUG_THIS_RULE(); @@ -1057,7 +1108,7 @@ bool Parser::parseTemplateDeclaration(DeclarationAST *&node) if (LA() == T_LESS) { ast->less_token = consumeToken(); - if (LA() == T_GREATER || parseTemplateParameterList(ast->template_parameter_list)) + if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER || parseTemplateParameterList(ast->template_parameter_list)) match(T_GREATER, &ast->greater_token); } @@ -1176,6 +1227,21 @@ bool Parser::parseCvQualifiers(SpecifierListAST *&node) return start != cursor(); } +bool Parser::parseRefQualifier(unsigned &ref_qualifier) +{ + DEBUG_THIS_RULE(); + + if (!_cxx0xEnabled) + return false; + + if (LA() == T_AMPER || LA() == T_AMPER_AMPER) { + ref_qualifier = consumeToken(); + return true; + } + + return false; +} + /** * \brief Handles override and final from C++ 2011, they are pseudo keywords and has special meaning only in function declaration */ @@ -1257,7 +1323,7 @@ bool Parser::parseTemplateArgument(ExpressionAST *&node) if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT) index = 2; - if (LA(index) == T_COMMA || LA(index) == T_GREATER) + if (LA(index) == T_COMMA || maybeSplitGreaterGreaterToken(index) || LA(index) == T_GREATER) return true; } @@ -1425,11 +1491,12 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif bool blocked = blockErrors(true); if (parseInitializer(initializer, &node->equal_token)) { - NestedExpressionAST *expr = 0; + // maybe the initializer also parses as a FunctionDeclarator? + ExpressionListParenAST *expr = 0; if (initializer) - expr = initializer->asNestedExpression(); + expr = initializer->asExpressionListParen(); if (expr) { - if (expr->expression && expr->rparen_token && (LA() == T_COMMA || LA() == T_SEMICOLON)) { + if (expr->expression_list && expr->rparen_token && (LA() == T_COMMA || LA() == T_SEMICOLON)) { rewind(lparen_token); // check for ambiguous declarators. @@ -1474,8 +1541,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif ast->rparen_token = consumeToken(); // ### parse attributes parseCvQualifiers(ast->cv_qualifier_list); - parseOverrideFinalQualifiers(ast->cv_qualifier_list); - // ### parse ref-qualifiers + parseRefQualifier(ast->ref_qualifier_token); parseExceptionSpecification(ast->exception_specification); if (_cxx0xEnabled && ! node->ptr_operator_list && LA() == T_ARROW) { @@ -1494,6 +1560,8 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif parseTrailingReturnType(ast->trailing_return_type); } + parseOverrideFinalQualifiers(ast->cv_qualifier_list); + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_LBRACKET) { @@ -1579,6 +1647,7 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *dec ast->rparen_token = consumeToken(); } parseCvQualifiers(ast->cv_qualifier_list); + parseRefQualifier(ast->ref_qualifier_token); parseExceptionSpecification(ast->exception_specification); *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; @@ -1621,16 +1690,19 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_ENUM) { - unsigned enum_token = consumeToken(); - if (_cxx0xEnabled && LA() == T_CLASS) - consumeToken(); + EnumSpecifierAST *ast = new (_pool) EnumSpecifierAST; - NameAST *name = 0; - parseName(name); + ast->enum_token = consumeToken(); + if (_cxx0xEnabled && (LA() == T_CLASS || LA() == T_STRUCT)) + ast->key_token = consumeToken(); + + parseName(ast->name); + + if (_cxx0xEnabled && LA() == T_COLON) { + ast->colon_token = consumeToken(); + parseTypeSpecifier(ast->type_specifier_list); + } if (LA() == T_LBRACE) { - EnumSpecifierAST *ast = new (_pool) EnumSpecifierAST; - ast->enum_token = enum_token; - ast->name = name; ast->lbrace_token = consumeToken(); unsigned comma_token = 0; EnumeratorListAST **enumerator_ptr = &ast->enumerator_list; @@ -1654,9 +1726,12 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node) match(T_COMMA, &comma_token); } match(T_RBRACE, &ast->rbrace_token); - node = new (_pool) SpecifierListAST(ast); - return true; + } else if (!_cxx0xEnabled) { + return false; } + + node = new (_pool) SpecifierListAST(ast); + return true; } return false; } @@ -1727,7 +1802,7 @@ bool Parser::parseTemplateTypeParameter(DeclarationAST *&node) if (LA() == T_LESS) ast->less_token = consumeToken(); parseTemplateParameterList(ast->template_parameter_list); - if (LA() == T_GREATER) + if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER) ast->greater_token = consumeToken(); if (LA() == T_CLASS) ast->class_token = consumeToken(); @@ -1747,7 +1822,7 @@ bool Parser::parseTemplateTypeParameter(DeclarationAST *&node) return false; } -bool Parser::lookAtTypeParameter() const +bool Parser::lookAtTypeParameter() { if (LA() == T_CLASS || LA() == T_TYPENAME) { if (LA(2) == T_IDENTIFIER) { @@ -1758,7 +1833,7 @@ bool Parser::lookAtTypeParameter() const return true; default: - return false; + return maybeSplitGreaterGreaterToken(3); } } else if (LA(2) == T_COLON_COLON) { // found something like template <typename ::foo::bar>... @@ -1872,7 +1947,10 @@ bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node) parseDeclaratorOrAbstractDeclarator(ast->declarator, decl_specifier_seq); if (LA() == T_EQUAL) { ast->equal_token = consumeToken(); - parseLogicalOrExpression(ast->expression); + if (!_cxx0xEnabled) + parseLogicalOrExpression(ast->expression); + else + parseInitializerClause0x(ast->expression); } node = ast; @@ -2446,7 +2524,9 @@ bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node) } else if (_cxx0xEnabled && LA() == T_NOEXCEPT) { NoExceptSpecificationAST *ast = new (_pool) NoExceptSpecificationAST; ast->noexcept_token = consumeToken(); - if (LA() == T_LPAREN && parseConstantExpression(ast->expression)) { + if (LA() == T_LPAREN) { + ast->lparen_token = consumeToken(); + parseConstantExpression(ast->expression); match(T_RPAREN, &ast->rparen_token); } node = ast; @@ -2493,6 +2573,10 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp consumeToken(); } + const bool isFunctionDeclarator = node + && node->postfix_declarator_list + && node->postfix_declarator_list->lastValue() + && node->postfix_declarator_list->lastValue()->asFunctionDeclarator(); if (declaringClass && LA() == T_COLON && (! node || ! node->postfix_declarator_list)) { unsigned colon_token = consumeToken(); @@ -2506,7 +2590,20 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp return true; } rewind(colon_token); - } else if (node->core_declarator && (LA() == T_EQUAL || (! declaringClass && LA() == T_LPAREN))) { + } else if (isFunctionDeclarator && declaringClass && node->core_declarator && LA() == T_EQUAL && LA(3) == T_SEMICOLON) { // = 0, = delete, = default + if (!_cxx0xEnabled || LA(2) == T_NUMERIC_LITERAL) { + parseInitializer(node->initializer, &node->equal_token); + } else { + node->equal_token = consumeToken(); + + IdExpressionAST *id_expr = new (_pool) IdExpressionAST; + node->initializer = id_expr; + + SimpleNameAST *simple_name = new (_pool) SimpleNameAST; + id_expr->name = simple_name; + simple_name->identifier_token = consumeToken(); + } + } else if (node->core_declarator && (LA() == T_EQUAL || (_cxx0xEnabled && !isFunctionDeclarator && LA() == T_LBRACE) || (! declaringClass && LA() == T_LPAREN))) { parseInitializer(node->initializer, &node->equal_token); } return true; @@ -2555,7 +2652,7 @@ bool Parser::parseInitializer0x(ExpressionAST *&node, unsigned *equals_token) } else if (LA() == T_LPAREN) { - return parsePrimaryExpression(node); + return parseExpressionListParen(node); } return false; @@ -2581,8 +2678,7 @@ bool Parser::parseInitializerClause0x(ExpressionAST *&node) if (LA() == T_LBRACE) return parseBracedInitList0x(node); - parseAssignmentExpression(node); - return true; + return parseAssignmentExpression(node); } bool Parser::parseInitializerList0x(ExpressionListAST *&node) @@ -2650,7 +2746,9 @@ bool Parser::parseMemInitializerList(MemInitializerListAST *&node) else if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && LA(2) == T_LBRACE) break; - else if (LA() == T_COMMA || (LA() == T_IDENTIFIER && (LA(2) == T_LPAREN || LA(2) == T_COLON_COLON))) { + else if (LA() == T_COMMA + || (LA() == T_IDENTIFIER + && (LA(2) == T_LPAREN || LA(2) == T_COLON_COLON || (_cxx0xEnabled && LA(2) == T_LBRACE)))) { if (LA() != T_COMMA) error(cursor(), "expected `,'"); else @@ -2687,9 +2785,18 @@ bool Parser::parseMemInitializer(MemInitializerListAST *&node) MemInitializerAST *ast = new (_pool) MemInitializerAST; ast->name = name; - match(T_LPAREN, &ast->lparen_token); - parseExpressionList(ast->expression_list); - match(T_RPAREN, &ast->rparen_token); + + if (LA() == T_LPAREN) { + parseExpressionListParen(ast->expression); + } else if (_cxx0xEnabled && LA() == T_LBRACE) { + parseBracedInitList0x(ast->expression); + } else { + if (!_cxx0xEnabled) + error(cursor(), "expected '('"); + else + error(cursor(), "expected '(' or '{'"); + return false; + } node = new (_pool) MemInitializerListAST; node->value = ast; @@ -2731,12 +2838,9 @@ bool Parser::parseExpressionList(ExpressionListAST *&node) { DEBUG_THIS_RULE(); -#ifdef CPLUSPLUS_WITH_CXXOX_INITIALIZER_LIST if (_cxx0xEnabled) return parseInitializerList0x(node); -#endif - // ### remove me ExpressionListAST **expression_list_ptr = &node; ExpressionAST *expression = 0; if (parseAssignmentExpression(expression)) { @@ -2846,7 +2950,7 @@ bool Parser::parseUnqualifiedName(NameAST *&node, bool acceptTemplateId) if (acceptTemplateId && LA(2) == T_LESS) { bool blocked = blockErrors(true); if (parseTemplateId(node) - && (! _templateArguments || (LA() == T_COMMA || LA() == T_GREATER || + && (! _templateArguments || (LA() == T_COMMA || maybeSplitGreaterGreaterToken() || LA() == T_GREATER || LA() == T_LPAREN || LA() == T_RPAREN || LA() == T_STAR || LA() == T_AMPER || // ptr-operators LA() == T_COLON_COLON))) { @@ -3088,7 +3192,10 @@ bool Parser::parseReturnStatement(StatementAST *&node) if (LA() == T_RETURN) { ReturnStatementAST *ast = new (_pool) ReturnStatementAST; ast->return_token = consumeToken(); - parseExpression(ast->expression); + if (_cxx0xEnabled && LA() == T_LBRACE) + parseBracedInitList0x(ast->expression); + else + parseExpression(ast->expression); match(T_SEMICOLON, &ast->semicolon_token); node = ast; return true; @@ -3377,7 +3484,11 @@ bool Parser::parseForStatement(StatementAST *&node) ast->colon_token = consumeToken(); blockErrors(blocked); - parseExpression(ast->expression); + if (LA() == T_LBRACE) { + parseBracedInitList0x(ast->expression); + } else { + parseExpression(ast->expression); + } match(T_RPAREN, &ast->rparen_token); parseStatement(ast->statement); @@ -3755,7 +3866,6 @@ bool Parser::parseBuiltinTypeSpecifier(SpecifierListAST *&node) if (parseExpression(ast->expression)) match(T_RPAREN, &ast->rparen_token); node = new (_pool) SpecifierListAST(ast); - skipUntilDeclaration(); return true; } else if (lookAtBuiltinTypeSpecifier()) { SimpleSpecifierAST *ast = new (_pool) SimpleSpecifierAST; @@ -3818,7 +3928,9 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de } } else if (! has_type_specifier && LA() == T_ENUM) { unsigned startOfTypeSpecifier = cursor(); - if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) || LA() == T_LBRACE) { + if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) + || LA() == T_LBRACE + || (_cxx0xEnabled && LA() == T_COLON)) { rewind(startOfTypeSpecifier); if (! parseEnumSpecifier(*decl_specifier_seq_ptr)) { error(startOfTypeSpecifier, @@ -4599,13 +4711,16 @@ bool Parser::parseTypenameCallExpression(ExpressionAST *&node) if (LA() == T_TYPENAME) { unsigned typename_token = consumeToken(); NameAST *name = 0; - if (parseName(name) && LA() == T_LPAREN) { + if (parseName(name) + && (LA() == T_LPAREN || (_cxx0xEnabled && LA() == T_LBRACE))) { TypenameCallExpressionAST *ast = new (_pool) TypenameCallExpressionAST; ast->typename_token = typename_token; ast->name = name; - ast->lparen_token = consumeToken(); - parseExpressionList(ast->expression_list); - match(T_RPAREN, &ast->rparen_token); + if (LA() == T_LPAREN) { + parseExpressionListParen(ast->expression); + } else { // T_LBRACE + parseBracedInitList0x(ast->expression); + } node = ast; return true; } @@ -4658,21 +4773,19 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node) bool blocked = blockErrors(true); if (lookAtBuiltinTypeSpecifier() && parseSimpleTypeSpecifier(type_specifier) && - LA() == T_LPAREN) { - unsigned lparen_token = consumeToken(); - ExpressionListAST *expression_list = 0; - parseExpressionList(expression_list); - if (LA() == T_RPAREN) { - unsigned rparen_token = consumeToken(); - TypeConstructorCallAST *ast = new (_pool) TypeConstructorCallAST; - ast->type_specifier_list = type_specifier; - ast->lparen_token = lparen_token; - ast->expression_list = expression_list; - ast->rparen_token = rparen_token; - node = ast; - blockErrors(blocked); - return true; + (LA() == T_LPAREN || (_cxx0xEnabled && LA() == T_LBRACE))) { + ExpressionAST *expr = 0; + if (LA() == T_LPAREN) { + parseExpressionListParen(expr); + } else { // T_LBRACE + parseBracedInitList0x(expr); } + TypeConstructorCallAST *ast = new (_pool) TypeConstructorCallAST; + ast->type_specifier_list = type_specifier; + ast->expression = expr; + node = ast; + blockErrors(blocked); + return true; } rewind(start); @@ -4722,6 +4835,14 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) match(T_RBRACKET, &ast->rbracket_token); ast->base_expression = node; node = ast; + } else if (_cxx0xEnabled && LA() == T_LBRACE && node->asIdExpression()) { + // this is slightly inconsistent: simple-type-specifier '(' expression-list ')' + // gets parsed as a CallAST while simple-type-specifier brace-init-list + // is a TypenameCallExpressionAST + TypenameCallExpressionAST *ast = new (_pool) TypenameCallExpressionAST; + ast->name = node->asIdExpression()->name; + parseBracedInitList0x(ast->expression); + node = ast; } else if (LA() == T_PLUS_PLUS || LA() == T_MINUS_MINUS) { PostIncrDecrAST *ast = new (_pool) PostIncrDecrAST; ast->incr_decr_token = consumeToken(); @@ -4808,6 +4929,24 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node) return true; } + case T_ALIGNOF: { + if (!_cxx0xEnabled) + break; + + AlignofExpressionAST *ast = new (_pool) AlignofExpressionAST; + ast->alignof_token = consumeToken(); + + match(T_LPAREN, &ast->lparen_token); + ExpressionAST *temp = 0; + parseTypeId(temp); + if (temp) + ast->typeId = temp->asTypeId(); + match(T_RPAREN, &ast->rparen_token); + + node = ast; + return true; + } + default: break; } // switch @@ -4823,15 +4962,15 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node) } // new-placement ::= T_LPAREN expression-list T_RPAREN -bool Parser::parseNewPlacement(NewPlacementAST *&node) +bool Parser::parseExpressionListParen(ExpressionAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_LPAREN) { unsigned lparen_token = consumeToken(); ExpressionListAST *expression_list = 0; - if (parseExpressionList(expression_list) && expression_list && LA() == T_RPAREN) { + if (parseExpressionList(expression_list) && LA() == T_RPAREN) { unsigned rparen_token = consumeToken(); - NewPlacementAST *ast = new (_pool) NewPlacementAST; + ExpressionListParenAST *ast = new (_pool) ExpressionListParenAST; ast->lparen_token = lparen_token; ast->expression_list = expression_list; ast->rparen_token = rparen_token; @@ -4843,6 +4982,7 @@ bool Parser::parseNewPlacement(NewPlacementAST *&node) return false; } + // new-expression ::= T_COLON_COLON? T_NEW new-placement.opt // new-type-id new-initializer.opt // new-expression ::= T_COLON_COLON? T_NEW new-placement.opt @@ -4859,14 +4999,14 @@ bool Parser::parseNewExpression(ExpressionAST *&node) ast->new_token = consumeToken(); - NewPlacementAST *new_placement = 0; + ExpressionAST *parenExpressionList = 0; - if (parseNewPlacement(new_placement)) { + if (parseExpressionListParen(parenExpressionList)) { unsigned after_new_placement = cursor(); NewTypeIdAST *new_type_id = 0; if (parseNewTypeId(new_type_id)) { - ast->new_placement = new_placement; + ast->new_placement = parenExpressionList->asExpressionListParen(); ast->new_type_id = new_type_id; parseNewInitializer(ast->new_initializer); // recognized new-placement.opt new-type-id new-initializer.opt @@ -4879,7 +5019,7 @@ bool Parser::parseNewExpression(ExpressionAST *&node) unsigned lparen_token = consumeToken(); ExpressionAST *type_id = 0; if (parseTypeId(type_id) && LA() == T_RPAREN) { - ast->new_placement = new_placement; + ast->new_placement = parenExpressionList->asExpressionListParen(); ast->lparen_token = lparen_token; ast->type_id = type_id; ast->rparen_token = consumeToken(); @@ -4950,20 +5090,13 @@ bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node) return true; } -bool Parser::parseNewInitializer(NewInitializerAST *&node) +bool Parser::parseNewInitializer(ExpressionAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_LPAREN) { - unsigned lparen_token = consumeToken(); - ExpressionAST *expression = 0; - if (LA() == T_RPAREN || parseExpression(expression)) { - NewInitializerAST *ast = new (_pool) NewInitializerAST; - ast->lparen_token = lparen_token; - ast->expression = expression; - match(T_RPAREN, &ast->rparen_token); - node = ast; - return true; - } + return parseExpressionListParen(node); + } else if (_cxx0xEnabled && LA() == T_LBRACE) { + return parseBracedInitList0x(node); } return false; } @@ -5188,8 +5321,13 @@ void Parser::parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minP if (operPrecedence <= Prec::Conditional && isCPlusPlus) { // in C++ you can put a throw in the right-most expression of a conditional expression, // or an assignment, so some special handling: - if (!parseAssignmentExpression(rhs)) - return; + if (_cxx0xEnabled) { + if (!parseInitializerClause0x(rhs)) + return; + } else { + if (!parseAssignmentExpression(rhs)) + return; + } } else { // for C & all other expressions: if (!parseCastExpression(rhs)) @@ -6156,41 +6294,56 @@ bool Parser::parseLambdaCapture(LambdaCaptureAST *&node) return true; } -bool Parser::parseCapture(CaptureAST *&) +bool Parser::parseCapture(CaptureAST *&node) { DEBUG_THIS_RULE(); - if (LA() == T_IDENTIFIER) { - consumeToken(); - return true; - } else if (LA() == T_AMPER && LA(2) == T_IDENTIFIER) { - consumeToken(); + if (LA() == T_THIS) { consumeToken(); return true; + } - } else if (LA() == T_THIS) { + if (LA() == T_AMPER) consumeToken(); + + if (LA() == T_IDENTIFIER) { + SimpleNameAST *ast = new (_pool) SimpleNameAST; + ast->identifier_token = consumeToken(); + + node = new (_pool) CaptureAST; + node->identifier = ast; return true; } return false; } -bool Parser::parseCaptureList(CaptureListAST *&) +bool Parser::parseCaptureList(CaptureListAST *&node) { DEBUG_THIS_RULE(); CaptureAST *capture = 0; if (parseCapture(capture)) { + node = new (_pool) CaptureListAST; + node->value = capture; + + CaptureListAST **l = &node->next; while (LA() == T_COMMA) { consumeToken(); // consume `,' - + CaptureAST *capture = 0; parseCapture(capture); + if (capture) { + *l = new (_pool) CaptureListAST; + (*l)->value = capture; + l = &(*l)->next; + } } + + return true; } - return true; + return false; } bool Parser::parseLambdaDeclarator(LambdaDeclaratorAST *&node) diff --git a/src/libs/3rdparty/cplusplus/Parser.h b/src/libs/3rdparty/cplusplus/Parser.h index 406e8f2d69..f5971e4040 100644 --- a/src/libs/3rdparty/cplusplus/Parser.h +++ b/src/libs/3rdparty/cplusplus/Parser.h @@ -82,6 +82,7 @@ public: bool parseConstantExpression(ExpressionAST *&node); bool parseCtorInitializer(CtorInitializerAST *&node); bool parseCvQualifiers(SpecifierListAST *&node); + bool parseRefQualifier(unsigned &ref_qualifier); bool parseOverrideFinalQualifiers(SpecifierListAST *&node); bool parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list); bool parseDeclaration(DeclarationAST *&node); @@ -131,8 +132,8 @@ public: bool parseNamespaceAliasDefinition(DeclarationAST *&node); bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node); bool parseNewExpression(ExpressionAST *&node); - bool parseNewPlacement(NewPlacementAST *&node); - bool parseNewInitializer(NewInitializerAST *&node); + bool parseExpressionListParen(ExpressionAST *&node); + bool parseNewInitializer(ExpressionAST *&node); bool parseNewTypeId(NewTypeIdAST *&node); bool parseOperator(OperatorAST *&node); bool parseConversionFunctionId(NameAST *&node); @@ -189,6 +190,7 @@ public: bool parseUnqualifiedName(NameAST *&node, bool acceptTemplateId = true); bool parseUsing(DeclarationAST *&node); bool parseUsingDirective(DeclarationAST *&node); + bool parseAliasDeclaration(DeclarationAST *&node); bool parseWhileStatement(StatementAST *&node); void parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minPrecedence); @@ -254,8 +256,9 @@ public: void skipUntilDeclaration(); bool skipUntilStatement(); bool skip(int l, int r); + int find(int token, int stopAt); - bool lookAtTypeParameter() const; + bool lookAtTypeParameter(); bool lookAtCVQualifier() const; bool lookAtFunctionSpecifier() const; bool lookAtStorageClassSpecifier() const; @@ -273,6 +276,7 @@ public: int peekAtQtContextKeyword() const; bool switchTemplateArguments(bool templateArguments); + bool maybeSplitGreaterGreaterToken(int n = 1); bool blockErrors(bool block); void warning(unsigned index, const char *format, ...); diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp index 2ac8075f1c..1a16c5ed7f 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.cpp +++ b/src/libs/3rdparty/cplusplus/Symbols.cpp @@ -231,12 +231,6 @@ bool Function::isEqualTo(const Type *other) const return false; else if (isVolatile() != o->isVolatile()) return false; -#ifdef ICHECK_BUILD - else if (isInvokable() != o->isInvokable()) - return false; - else if (isSignal() != o->isSignal()) - return false; -#endif const Name *l = unqualifiedName(); const Name *r = o->unqualifiedName(); @@ -256,37 +250,6 @@ bool Function::isEqualTo(const Type *other) const return false; } -#ifdef ICHECK_BUILD -bool Function::isEqualTo(const Function* fct, bool ignoreName/* = false*/) const -{ - if (!ignoreName) - return isEqualTo((Type*)fct); - - if (! fct) - return false; - else if (isConst() != fct->isConst()) - return false; - else if (isVolatile() != fct->isVolatile()) - return false; - else if (isInvokable() != fct->isInvokable()) - return false; - else if (isSignal() != fct->isSignal()) - return false; - - if (_arguments->symbolCount() != fct->_arguments->symbolCount()) - return false; - else if (! _returnType.isEqualTo(fct->_returnType)) - return false; - for (unsigned i = 0; i < _arguments->symbolCount(); ++i) { - Symbol *l = _arguments->symbolAt(i); - Symbol *r = fct->_arguments->symbolAt(i); - if (! l->type().isEqualTo(r->type())) - return false; - } - return true; -} -#endif - void Function::accept0(TypeVisitor *visitor) { visitor->visit(this); } @@ -458,10 +421,12 @@ void Block::visitSymbol0(SymbolVisitor *visitor) Enum::Enum(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name) : Scope(translationUnit, sourceLocation, name) + , _isScoped(false) { } Enum::Enum(Clone *clone, Subst *subst, Enum *original) : Scope(clone, subst, original) + , _isScoped(original->isScoped()) { } Enum::~Enum() @@ -484,6 +449,16 @@ bool Enum::isEqualTo(const Type *other) const return l->isEqualTo(r); } +bool Enum::isScoped() const +{ + return _isScoped; +} + +void Enum::setScoped(bool scoped) +{ + _isScoped = scoped; +} + void Enum::accept0(TypeVisitor *visitor) { visitor->visit(this); } diff --git a/src/libs/3rdparty/cplusplus/Symbols.h b/src/libs/3rdparty/cplusplus/Symbols.h index e7fae94892..b6a711b8f8 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.h +++ b/src/libs/3rdparty/cplusplus/Symbols.h @@ -279,10 +279,16 @@ public: virtual Enum *asEnumType() { return this; } + bool isScoped() const; + void setScoped(bool scoped); + protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + +private: + bool _isScoped; }; class CPLUSPLUS_EXPORT Function: public Scope, public Type @@ -341,10 +347,6 @@ public: bool isPureVirtual() const; void setPureVirtual(bool isPureVirtual); -#ifdef ICHECK_BUILD - bool isEqualTo(const Function* fct, bool ignoreName = false) const; -#endif - // Symbol's interface virtual FullySpecifiedType type() const; diff --git a/src/libs/3rdparty/cplusplus/Token.cpp b/src/libs/3rdparty/cplusplus/Token.cpp index dcc18601c2..ed3319aeab 100644 --- a/src/libs/3rdparty/cplusplus/Token.cpp +++ b/src/libs/3rdparty/cplusplus/Token.cpp @@ -46,7 +46,7 @@ static const char *token_names[] = { ("|="), ("||"), ("+"), ("+="), ("++"), ("#"), ("##"), ("?"), ("}"), ("]"), (")"), (";"), ("*"), ("*="), ("~"), ("~="), - ("asm"), ("auto"), ("bool"), ("break"), ("case"), ("catch"), + ("alignas"), ("alignof"), ("asm"), ("auto"), ("bool"), ("break"), ("case"), ("catch"), ("char"), ("char16_t"), ("char32_t"), ("class"), ("const"), ("const_cast"), ("constexpr"), ("continue"), ("decltype"), ("default"), diff --git a/src/libs/3rdparty/cplusplus/Token.h b/src/libs/3rdparty/cplusplus/Token.h index a89e552256..3d253151bd 100644 --- a/src/libs/3rdparty/cplusplus/Token.h +++ b/src/libs/3rdparty/cplusplus/Token.h @@ -115,7 +115,9 @@ enum Kind { T_LAST_OPERATOR = T_TILDE_EQUAL, T_FIRST_KEYWORD, - T_ASM = T_FIRST_KEYWORD, + T_ALIGNAS = T_FIRST_KEYWORD, + T_ALIGNOF, + T_ASM, T_AUTO, T_BOOL, T_BREAK, diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp index a26a23eabc..7afef149ef 100644 --- a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp +++ b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp @@ -552,6 +552,34 @@ unsigned TranslationUnit::findPreviousLineOffset(unsigned tokenIndex) const return lineOffset; } +bool TranslationUnit::maybeSplitGreaterGreaterToken(unsigned tokenIndex) +{ + Token &tok = _tokens->at(tokenIndex); + if (tok.kind() != T_GREATER_GREATER) + return false; + + tok.f.kind = T_GREATER; + tok.f.length = 1; + + Token newGreater; + newGreater.f.kind = T_GREATER; + newGreater.f.expanded = tok.f.expanded; + newGreater.f.generated = tok.f.generated; + newGreater.f.length = 1; + newGreater.offset = tok.offset + 1; + + _tokens->insert(_tokens->begin() + tokenIndex + 1, newGreater); + + std::map<unsigned, std::pair<unsigned, unsigned> >::const_iterator it = + _expandedLineColumn.find(tok.offset); + if (it != _expandedLineColumn.end()) { + const std::pair<unsigned, unsigned> newPosition(it->second.first, it->second.second + 1); + _expandedLineColumn.insert(std::make_pair(newGreater.offset, newPosition)); + } + + return true; +} + void TranslationUnit::showErrorLine(unsigned index, unsigned column, FILE *out) { unsigned lineOffset = _lineOffsets[findLineNumber(_tokens->at(index).offset)]; diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.h b/src/libs/3rdparty/cplusplus/TranslationUnit.h index 95832f4328..f6ac1959db 100644 --- a/src/libs/3rdparty/cplusplus/TranslationUnit.h +++ b/src/libs/3rdparty/cplusplus/TranslationUnit.h @@ -134,6 +134,8 @@ public: unsigned findPreviousLineOffset(unsigned tokenIndex) const; + bool maybeSplitGreaterGreaterToken(unsigned tokenIndex); + public: struct PPLine { unsigned offset; diff --git a/src/libs/QtcLibrary.qbs b/src/libs/QtcLibrary.qbs index 1145ddd40e..3e97e4a59d 100644 --- a/src/libs/QtcLibrary.qbs +++ b/src/libs/QtcLibrary.qbs @@ -1,12 +1,19 @@ import qbs.base 1.0 +import "../../qbs/defaults.js" as Defaults DynamicLibrary { Depends { name: "cpp" } - cpp.defines: project.additionalCppDefines + Depends { + condition: Defaults.testsEnabled(qbs) + name: "Qt.test" + } + + cpp.defines: Defaults.defines(qbs) cpp.linkerFlags: { if (qbs.buildVariant == "release" && (qbs.toolchain == "gcc" || qbs.toolchain == "mingw")) return ["-Wl,-s"] } + cpp.includePaths: [ "." ] destination: { if (qbs.targetOS == "windows") @@ -14,4 +21,9 @@ DynamicLibrary { else return "lib/qtcreator" } + + ProductModule { + Depends { name: "cpp" } + cpp.includePaths: [ "." ] + } } diff --git a/src/libs/aggregation/aggregation.qbs b/src/libs/aggregation/aggregation.qbs index 1c81766995..a5e8e84d39 100644 --- a/src/libs/aggregation/aggregation.qbs +++ b/src/libs/aggregation/aggregation.qbs @@ -4,18 +4,13 @@ import "../QtcLibrary.qbs" as QtcLibrary QtcLibrary { name: "Aggregation" - cpp.includePaths: [ - ".", - ".." - ] cpp.defines: base.concat("AGGREGATION_LIBRARY") - Depends { name: "cpp" } Depends { name: "Qt.core" } files: [ - "aggregation_global.h", + "aggregate.cpp", "aggregate.h", - "aggregate.cpp" + "aggregation_global.h", ] } diff --git a/src/libs/cplusplus/AlreadyConsideredClassContainer.h b/src/libs/cplusplus/AlreadyConsideredClassContainer.h new file mode 100644 index 0000000000..4ada3866c4 --- /dev/null +++ b/src/libs/cplusplus/AlreadyConsideredClassContainer.h @@ -0,0 +1,45 @@ +#ifndef CPLUSPLUS_ALREADYCONSIDEREDCLASSCONTAINER_H +#define CPLUSPLUS_ALREADYCONSIDEREDCLASSCONTAINER_H + +#include <QSet> + +namespace CPlusPlus { + +template<typename T> +class AlreadyConsideredClassContainer +{ +public: + AlreadyConsideredClassContainer() : _class(0) {} + void insert(const T *item) + { + if (_container.isEmpty()) + _class = item; + _container.insert(item); + } + bool contains(const T *item) + { + if (_container.contains(item)) + return true; + + foreach (const T *existingItem, _container) { + if (existingItem->isEqualTo(item)) + return true; + } + + return false; + } + + void clear(const T *item) + { + if (_class != item || _container.size() == 1) + _container.clear(); + } + +private: + QSet<const T *> _container; + const T * _class; +}; + +} // namespace CPlusPlus + +#endif // CPLUSPLUS_ALREADYCONSIDEREDCLASSCONTAINER_H diff --git a/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp b/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp index 4c8c752fab..eb27a6bf55 100644 --- a/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp +++ b/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp @@ -304,25 +304,25 @@ private: virtual void visit(const DestructorNameId *name) { Overview oo; - qWarning() << "ignored name:" << oo(name); + qWarning() << "ignored name:" << oo.prettyName(name); } virtual void visit(const OperatorNameId *name) { Overview oo; - qWarning() << "ignored name:" << oo(name); + qWarning() << "ignored name:" << oo.prettyName(name); } virtual void visit(const ConversionNameId *name) { Overview oo; - qWarning() << "ignored name:" << oo(name); + qWarning() << "ignored name:" << oo.prettyName(name); } virtual void visit(const SelectorNameId *name) { Overview oo; - qWarning() << "ignored name:" << oo(name); + qWarning() << "ignored name:" << oo.prettyName(name); } private: diff --git a/src/libs/cplusplus/Dumpers.cpp b/src/libs/cplusplus/Dumpers.cpp index c91a5bdbba..2a20ea72f4 100644 --- a/src/libs/cplusplus/Dumpers.cpp +++ b/src/libs/cplusplus/Dumpers.cpp @@ -55,13 +55,13 @@ static QString indent(QString s, int level = 2) QString CPlusPlus::toString(const Name *name, QString id) { Overview oo; - return QString("%0: %1").arg(id, name ? oo(name) : QLatin1String("(null)")); + return QString("%0: %1").arg(id, name ? oo.prettyName(name) : QLatin1String("(null)")); } QString CPlusPlus::toString(FullySpecifiedType ty, QString id) { Overview oo; - return QString("%0: %1 (a %2)").arg(id, oo(ty), ty.type() ? typeid(*ty.type()).name() : "(null)"); + return QString("%0: %1 (a %2)").arg(id, oo.prettyType(ty), ty.type() ? typeid(*ty.type()).name() : "(null)"); } QString CPlusPlus::toString(const Symbol *s, QString id) @@ -72,7 +72,7 @@ QString CPlusPlus::toString(const Symbol *s, QString id) return QString("%0: %1 (%2) at %3:%4:%5\n%6").arg( id, QString::fromLatin1(typeid(*s).name()), - QString::fromUtf8(s->identifier()->chars()), + s->identifier() ? QString::fromUtf8(s->identifier()->chars()) : "no id", QString::fromLatin1(s->fileName()), QString::number(s->line()), QString::number(s->column()), diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 8dc0637279..e83d7d220f 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -535,11 +535,7 @@ void FindUsages::memInitializer(MemInitializerAST *ast) (void) switchScope(previousScope); } } - // unsigned lparen_token = ast->lparen_token; - for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - this->expression(it->value); - } - // unsigned rparen_token = ast->rparen_token; + this->expression(ast->expression); } bool FindUsages::visit(NestedNameSpecifierAST *ast) @@ -558,14 +554,17 @@ void FindUsages::nestedNameSpecifier(NestedNameSpecifierAST *ast) // unsigned scope_token = ast->scope_token; } -bool FindUsages::visit(NewPlacementAST *ast) +bool FindUsages::visit(ExpressionListParenAST *ast) { - (void) ast; - Q_ASSERT(!"unreachable"); + // unsigned lparen_token = ast->lparen_token; + for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { + this->expression(it->value); + } + // unsigned rparen_token = ast->rparen_token; return false; } -void FindUsages::newPlacement(NewPlacementAST *ast) +void FindUsages::newPlacement(ExpressionListParenAST *ast) { if (! ast) return; @@ -594,23 +593,6 @@ void FindUsages::newArrayDeclarator(NewArrayDeclaratorAST *ast) // unsigned rbracket_token = ast->rbracket_token; } -bool FindUsages::visit(NewInitializerAST *ast) -{ - (void) ast; - Q_ASSERT(!"unreachable"); - return false; -} - -void FindUsages::newInitializer(NewInitializerAST *ast) -{ - if (! ast) - return; - - // unsigned lparen_token = ast->lparen_token; - this->expression(ast->expression); - // unsigned rparen_token = ast->rparen_token; -} - bool FindUsages::visit(NewTypeIdAST *ast) { (void) ast; @@ -887,6 +869,7 @@ void FindUsages::capture(CaptureAST *ast) if (! ast) return; + this->name(ast->identifier); } bool FindUsages::visit(LambdaDeclaratorAST *ast) @@ -1025,7 +1008,6 @@ bool FindUsages::visit(RangeBasedForStatementAST *ast) this->specifier(it->value); } this->declarator(ast->declarator); - this->expression(ast->initializer); // unsigned comma_token = ast->comma_token; this->expression(ast->expression); // unsigned rparen_token = ast->rparen_token; @@ -1296,7 +1278,7 @@ bool FindUsages::visit(NewExpressionAST *ast) this->expression(ast->type_id); // unsigned rparen_token = ast->rparen_token; this->newTypeId(ast->new_type_id); - this->newInitializer(ast->new_initializer); + this->expression(ast->new_initializer); return false; } @@ -1313,11 +1295,7 @@ bool FindUsages::visit(TypenameCallExpressionAST *ast) { // unsigned typename_token = ast->typename_token; /*const Name *name =*/ this->name(ast->name); - // unsigned lparen_token = ast->lparen_token; - for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - this->expression(it->value); - } - // unsigned rparen_token = ast->rparen_token; + this->expression(ast->expression); return false; } @@ -1326,11 +1304,7 @@ bool FindUsages::visit(TypeConstructorCallAST *ast) for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) { this->specifier(it->value); } - // unsigned lparen_token = ast->lparen_token; - for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - this->expression(it->value); - } - // unsigned rparen_token = ast->rparen_token; + this->expression(ast->expression); return false; } diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h index 5d4bdeb379..c4a25ff4de 100644 --- a/src/libs/cplusplus/FindUsages.h +++ b/src/libs/cplusplus/FindUsages.h @@ -103,9 +103,8 @@ protected: void exceptionSpecification(ExceptionSpecificationAST *ast); void memInitializer(MemInitializerAST *ast); void nestedNameSpecifier(NestedNameSpecifierAST *ast); - void newPlacement(NewPlacementAST *ast); + void newPlacement(ExpressionListParenAST *ast); void newArrayDeclarator(NewArrayDeclaratorAST *ast); - void newInitializer(NewInitializerAST *ast); void newTypeId(NewTypeIdAST *ast); void cppOperator(OperatorAST *ast); void parameterDeclarationClause(ParameterDeclarationClauseAST *ast); @@ -136,9 +135,7 @@ protected: virtual bool visit(DynamicExceptionSpecificationAST *ast); virtual bool visit(MemInitializerAST *ast); virtual bool visit(NestedNameSpecifierAST *ast); - virtual bool visit(NewPlacementAST *ast); virtual bool visit(NewArrayDeclaratorAST *ast); - virtual bool visit(NewInitializerAST *ast); virtual bool visit(NewTypeIdAST *ast); virtual bool visit(OperatorAST *ast); virtual bool visit(ParameterDeclarationClauseAST *ast); @@ -213,6 +210,7 @@ protected: virtual bool visit(ObjCSelectorExpressionAST *ast); virtual bool visit(LambdaExpressionAST *ast); virtual bool visit(BracedInitializerAST *ast); + virtual bool visit(ExpressionListParenAST *ast); // DeclarationAST virtual bool visit(SimpleDeclarationAST *ast); diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 4f56c5180a..dbc513b1ad 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -83,6 +83,9 @@ static void path_helper(Symbol *symbol, QList<const Name *> *names) } else if (symbol->isFunction()) { if (const QualifiedNameId *q = symbol->name()->asQualifiedNameId()) addNames(q->base(), names); + } else if (Enum *e = symbol->asEnum()) { + if (e->isScoped()) + addNames(symbol->name(), names); } } } @@ -349,17 +352,10 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const if (! candidates.isEmpty()) return candidates; // it's a template parameter. - } else if (Class *klass = scope->asClass()) { - - if (ClassOrNamespace *binding = bindings()->lookupType(klass)) { - candidates = binding->find(name); - - if (! candidates.isEmpty()) - return candidates; - } - - } else if (Namespace *ns = scope->asNamespace()) { - if (ClassOrNamespace *binding = bindings()->lookupType(ns)) + } else if (scope->asNamespace() + || scope->asClass() + || (scope->asEnum() && scope->asEnum()->isScoped())) { + if (ClassOrNamespace *binding = bindings()->lookupType(scope)) candidates = binding->find(name); if (! candidates.isEmpty()) @@ -419,7 +415,7 @@ QList<ClassOrNamespace *> ClassOrNamespace::usings() const return _usings; } -QList<Enum *> ClassOrNamespace::enums() const +QList<Enum *> ClassOrNamespace::unscopedEnums() const { const_cast<ClassOrNamespace *>(this)->flush(); return _enums; @@ -547,7 +543,7 @@ void ClassOrNamespace::lookup_helper(const Name *name, ClassOrNamespace *binding } } - foreach (Enum *e, binding->enums()) + foreach (Enum *e, binding->unscopedEnums()) _factory->lookupInScope(name, e, result, templateId, binding); foreach (ClassOrNamespace *u, binding->usings()) @@ -751,9 +747,10 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac #endif // DEBUG_LOOKUP instantiation->_templateId = templId; instantiation->_instantiationOrigin = origin; + instantiation->_classOrNamespaces = reference->_classOrNamespaces; // The instantiation should have all symbols, enums, and usings from the reference. - instantiation->_enums.append(reference->enums()); + instantiation->_enums.append(reference->unscopedEnums()); instantiation->_usings.append(reference->usings()); // It gets a bit complicated if the reference is actually a class template because we @@ -779,7 +776,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac Symbol *clone = cloner.symbol(s, &subst); instantiation->_symbols.append(clone); #ifdef DEBUG_LOOKUP - Overview oo;oo.setShowFunctionSignatures(true);oo.setShowReturnTypes(true);oo.setShowTemplateParameters(true); + Overview oo;oo.showFunctionSignatures = true;oo.showReturnTypes = true; oo.showTemplateParameters = true; qDebug()<<"cloned"<<oo(clone->type()); #endif // DEBUG_LOOKUP } @@ -856,20 +853,11 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac if (allBases.isEmpty() || allBases.size() == knownUsings.size()) return reference; - QList<const Name *> fullyQualifiedNameForReferenceClass = - LookupContext::fullyQualifiedName(referenceClass); // Find the missing bases for regular (non-template) types. // Ex.: class A : public B<Some>::Type {}; foreach (const Name *baseName, allBases) { ClassOrNamespace *binding = this; if (const QualifiedNameId *qBaseName = baseName->asQualifiedNameId()) { - QList<const Name *> fullyQualifiedNameForBaseClass; - addNames(baseName, &fullyQualifiedNameForBaseClass); - if (compareFullyQualifiedName(fullyQualifiedNameForReferenceClass, - fullyQualifiedNameForBaseClass)) { - continue; - } - if (const Name *qualification = qBaseName->base()) binding = lookupType(qualification); else if (binding->parent() != 0) @@ -881,9 +869,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac continue; baseName = qBaseName->name(); } - else if (compareName(name, baseName)) { - continue; - } if (binding) { ClassOrNamespace * baseBinding = binding->lookupType(baseName); @@ -917,7 +902,7 @@ void ClassOrNamespace::addTodo(Symbol *symbol) _todo.append(symbol); } -void ClassOrNamespace::addEnum(Enum *e) +void ClassOrNamespace::addUnscopedEnum(Enum *e) { _enums.append(e); } @@ -1126,7 +1111,12 @@ bool CreateBindings::visit(ForwardClassDeclaration *klass) bool CreateBindings::visit(Enum *e) { - _currentClassOrNamespace->addEnum(e); + if (e->isScoped()) { + ClassOrNamespace *previous = enterClassOrNamespaceBinding(e); + _currentClassOrNamespace = previous; + } else { + _currentClassOrNamespace->addUnscopedEnum(e); + } return false; } @@ -1142,7 +1132,7 @@ bool CreateBindings::visit(Declaration *decl) _currentClassOrNamespace->addNestedType(decl->name(), e); } else if (false) { Overview oo; - qDebug() << "found entity not found for" << oo(namedTy->name()); + qDebug() << "found entity not found for" << oo.prettyName(namedTy->name()); } } else if (Class *klass = ty->asClassType()) { if (const Identifier *nameId = decl->name()->asNameId()) { @@ -1167,7 +1157,7 @@ bool CreateBindings::visit(BaseClass *b) _currentClassOrNamespace->addUsing(base); } else if (false) { Overview oo; - qDebug() << "no entity for:" << oo(b->name()); + qDebug() << "no entity for:" << oo.prettyName(b->name()); } return false; } @@ -1193,7 +1183,7 @@ bool CreateBindings::visit(UsingNamespaceDirective *u) _currentClassOrNamespace->addUsing(e); } else if (false) { Overview oo; - qDebug() << "no entity for namespace:" << oo(u->name()); + qDebug() << "no entity for namespace:" << oo.prettyName(u->name()); } return false; } @@ -1209,7 +1199,7 @@ bool CreateBindings::visit(NamespaceAlias *a) } else if (false) { Overview oo; - qDebug() << "no entity for namespace:" << oo(a->namespaceName()); + qDebug() << "no entity for namespace:" << oo.prettyName(a->namespaceName()); } return false; @@ -1237,7 +1227,7 @@ bool CreateBindings::visit(ObjCBaseClass *b) _currentClassOrNamespace->addUsing(base); } else if (false) { Overview oo; - qDebug() << "no entity for:" << oo(b->name()); + qDebug() << "no entity for:" << oo.prettyName(b->name()); } return false; } @@ -1269,7 +1259,7 @@ bool CreateBindings::visit(ObjCBaseProtocol *b) _currentClassOrNamespace->addUsing(base); } else if (false) { Overview oo; - qDebug() << "no entity for:" << oo(b->name()); + qDebug() << "no entity for:" << oo.prettyName(b->name()); } return false; } diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index e72c8fd3f9..b7c84d4e25 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -32,6 +32,7 @@ #include "CppDocument.h" #include "LookupItem.h" +#include "AlreadyConsideredClassContainer.h" #include <FullySpecifiedType.h> #include <Type.h> #include <SymbolVisitor.h> @@ -44,41 +45,6 @@ namespace CPlusPlus { class CreateBindings; -class Class; -template<typename T> -class AlreadyConsideredClassContainer -{ -public: - AlreadyConsideredClassContainer() : _class(0) {} - void insert(const T *item) - { - if (_container.isEmpty()) - _class = item; - _container.insert(item); - } - bool contains(const T *item) - { - if (_container.contains(item)) - return true; - - foreach (const T *existingItem, _container) { - if (existingItem->isEqualTo(item)) - return true; - } - - return false; - } - - void clear(const T *item) - { - if (_class != item || _container.size() == 1) - _container.clear(); - } - -private: - QSet<const T *> _container; - const T * _class; -}; class CPLUSPLUS_EXPORT ClassOrNamespace { @@ -90,7 +56,7 @@ public: ClassOrNamespace *parent() const; QList<ClassOrNamespace *> usings() const; - QList<Enum *> enums() const; + QList<Enum *> unscopedEnums() const; QList<Symbol *> symbols() const; ClassOrNamespace *globalNamespace() const; @@ -110,7 +76,7 @@ private: void addTodo(Symbol *symbol); void addSymbol(Symbol *symbol); - void addEnum(Enum *e); + void addUnscopedEnum(Enum *e); void addUsing(ClassOrNamespace *u); void addNestedType(const Name *alias, ClassOrNamespace *e); diff --git a/src/libs/cplusplus/Overview.cpp b/src/libs/cplusplus/Overview.cpp index 0a7d2628dc..748033d859 100644 --- a/src/libs/cplusplus/Overview.cpp +++ b/src/libs/cplusplus/Overview.cpp @@ -38,99 +38,16 @@ using namespace CPlusPlus; Overview::Overview() - : _markedArgument(0), - _markedArgumentBegin(0), - _markedArgumentEnd(0), - _showArgumentNames(false), - _showReturnTypes(false), - _showFunctionSignatures(true), - _showDefaultArguments(true), - _showTemplateParameters(false) + : markedArgument(0), + markedArgumentBegin(0), + markedArgumentEnd(0), + showArgumentNames(false), + showReturnTypes(false), + showFunctionSignatures(true), + showDefaultArguments(true), + showTemplateParameters(false) { } -Overview::~Overview() -{ } - -bool Overview::showArgumentNames() const -{ - return _showArgumentNames; -} - -void Overview::setShowArgumentNames(bool showArgumentNames) -{ - _showArgumentNames = showArgumentNames; -} - -void Overview::setShowReturnTypes(bool showReturnTypes) -{ - _showReturnTypes = showReturnTypes; -} - -bool Overview::showReturnTypes() const -{ - return _showReturnTypes; -} - -unsigned Overview::markedArgument() const -{ - return _markedArgument; -} - -void Overview::setMarkedArgument(unsigned position) -{ - _markedArgument = position; -} - -int Overview::markedArgumentBegin() const -{ - return _markedArgumentBegin; -} - -void Overview::setMarkedArgumentBegin(int begin) -{ - _markedArgumentBegin = begin; -} - -int Overview::markedArgumentEnd() const -{ - return _markedArgumentEnd; -} - -void Overview::setMarkedArgumentEnd(int end) -{ - _markedArgumentEnd = end; -} - -bool Overview::showFunctionSignatures() const -{ - return _showFunctionSignatures; -} - -void Overview::setShowFunctionSignatures(bool showFunctionSignatures) -{ - _showFunctionSignatures = showFunctionSignatures; -} - -bool Overview::showDefaultArguments() const -{ - return _showDefaultArguments; -} - -void Overview::setShowDefaultArguments(bool showDefaultArguments) -{ - _showDefaultArguments = showDefaultArguments; -} - -bool Overview::showTemplateParameters() const -{ - return _showTemplateParameters; -} - -void Overview::setShowTemplateParameters(bool showTemplateParameters) -{ - _showTemplateParameters = showTemplateParameters; -} - QString Overview::prettyName(const Name *name) const { NamePrettyPrinter pp(this); diff --git a/src/libs/cplusplus/Overview.h b/src/libs/cplusplus/Overview.h index 8a7635cdd8..344c976f99 100644 --- a/src/libs/cplusplus/Overview.h +++ b/src/libs/cplusplus/Overview.h @@ -44,32 +44,6 @@ class CPLUSPLUS_EXPORT Overview public: Overview(); - ~Overview(); - - bool showArgumentNames() const; - void setShowArgumentNames(bool showArgumentNames); - - bool showReturnTypes() const; - void setShowReturnTypes(bool showReturnTypes); - - bool showFunctionSignatures() const; - void setShowFunctionSignatures(bool showFunctionSignatures); - - bool showDefaultArguments() const; - void setShowDefaultArguments(bool showDefaultArguments); - - bool showTemplateParameters() const; - void setShowTemplateParameters(bool showTemplateParameters); - - // argument index that you want to mark - unsigned markedArgument() const; - void setMarkedArgument(unsigned position); - - int markedArgumentBegin() const; - void setMarkedArgumentBegin(int begin); - - int markedArgumentEnd() const; - void setMarkedArgumentEnd(int end); QString operator()(const Name *name) const { return prettyName(name); } @@ -85,15 +59,15 @@ public: QString prettyType(const FullySpecifiedType &type, const Name *name = 0) const; QString prettyType(const FullySpecifiedType &type, const QString &name) const; -private: - unsigned _markedArgument; - int _markedArgumentBegin; - int _markedArgumentEnd; - bool _showArgumentNames: 1; - bool _showReturnTypes: 1; - bool _showFunctionSignatures: 1; - bool _showDefaultArguments: 1; - bool _showTemplateParameters: 1; +public: + unsigned markedArgument; + int markedArgumentBegin; + int markedArgumentEnd; + bool showArgumentNames: 1; + bool showReturnTypes: 1; + bool showFunctionSignatures: 1; + bool showDefaultArguments: 1; + bool showTemplateParameters: 1; }; } // namespace CPlusPlus diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 65908254da..65ba9cb2a3 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -774,8 +774,8 @@ QList<LookupItem> ResolveExpression::getMembers(ClassOrNamespace *binding, const FullySpecifiedType instantiatedTy = rewriteType(decl->type(), &env, _context.control().data()); Overview oo; - oo.setShowReturnTypes(true); - oo.setShowFunctionSignatures(true); + oo.showReturnTypes = true; + oo.showFunctionSignatures = true; qDebug() << "original:" << oo(decl->type(), decl->name()) << "inst:" << oo(instantiatedTy, decl->name()); diff --git a/src/libs/cplusplus/TypePrettyPrinter.cpp b/src/libs/cplusplus/TypePrettyPrinter.cpp index 7031c7c777..035a6f6be6 100644 --- a/src/libs/cplusplus/TypePrettyPrinter.cpp +++ b/src/libs/cplusplus/TypePrettyPrinter.cpp @@ -143,7 +143,7 @@ void TypePrettyPrinter::visit(Namespace *type) void TypePrettyPrinter::visit(Template *type) { if (Symbol *d = type->declaration()) { - if (overview()->showTemplateParameters() && ! _name.isEmpty()) { + if (overview()->showTemplateParameters && ! _name.isEmpty()) { _name += QLatin1Char('<'); for (unsigned index = 0; index < type->templateParameterCount(); ++index) { if (index) @@ -309,13 +309,13 @@ void TypePrettyPrinter::visit(Function *type) } _text.append(QLatin1Char(')')); _needsParens = false; - } else if (! _name.isEmpty() && _overview->showFunctionSignatures()) { + } else if (! _name.isEmpty() && _overview->showFunctionSignatures) { appendSpace(); _text.append(_name); _name.clear(); } - if (_overview->showReturnTypes()) { + if (_overview->showReturnTypes) { const QString returnType = _overview->prettyType(type->returnType()); if (!returnType.isEmpty()) { if (!endsWithPtrOrRef(returnType)) @@ -324,11 +324,11 @@ void TypePrettyPrinter::visit(Function *type) } } - if (_overview->showFunctionSignatures()) { + if (_overview->showFunctionSignatures) { Overview argumentText; - argumentText.setShowReturnTypes(true); - argumentText.setShowArgumentNames(false); - argumentText.setShowFunctionSignatures(true); + argumentText.showReturnTypes = true; + argumentText.showArgumentNames = false; + argumentText.showFunctionSignatures = true; _text += QLatin1Char('('); @@ -337,25 +337,25 @@ void TypePrettyPrinter::visit(Function *type) _text += QLatin1String(", "); if (Argument *arg = type->argumentAt(index)->asArgument()) { - if (index + 1 == _overview->markedArgument()) - const_cast<Overview*>(_overview)->setMarkedArgumentBegin(_text.length()); + if (index + 1 == _overview->markedArgument) + const_cast<Overview*>(_overview)->markedArgumentBegin = _text.length(); const Name *name = 0; - if (_overview->showArgumentNames()) + if (_overview->showArgumentNames) name = arg->name(); - _text += argumentText(arg->type(), name); + _text += argumentText.prettyType(arg->type(), name); - if (_overview->showDefaultArguments()) { + if (_overview->showDefaultArguments) { if (const StringLiteral *initializer = arg->initializer()) { _text += QLatin1String(" ="); _text += QString::fromUtf8(initializer->chars(), initializer->size()); } } - if (index + 1 == _overview->markedArgument()) - const_cast<Overview*>(_overview)->setMarkedArgumentEnd(_text.length()); + if (index + 1 == _overview->markedArgument) + const_cast<Overview*>(_overview)->markedArgumentEnd = _text.length(); } } diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri index 2a8d5d544c..f5d1b0a511 100644 --- a/src/libs/cplusplus/cplusplus-lib.pri +++ b/src/libs/cplusplus/cplusplus-lib.pri @@ -36,6 +36,7 @@ HEADERS += \ $$PWD/TypePrettyPrinter.h \ $$PWD/ResolveExpression.h \ $$PWD/LookupItem.h \ + $$PWD/AlreadyConsideredClassContainer.h \ $$PWD/LookupContext.h \ $$PWD/ASTParent.h \ $$PWD/ASTPath.h \ diff --git a/src/libs/cplusplus/cplusplus.qbs b/src/libs/cplusplus/cplusplus.qbs index 6038fc6a2c..08213f11d6 100644 --- a/src/libs/cplusplus/cplusplus.qbs +++ b/src/libs/cplusplus/cplusplus.qbs @@ -4,12 +4,7 @@ import "../QtcLibrary.qbs" as QtcLibrary QtcLibrary { name: "CPlusPlus" - cpp.includePaths: [ - ".", - "..", - "../3rdparty/cplusplus", - "../../plugins" - ] + cpp.includePaths: base.concat("../3rdparty/cplusplus") cpp.defines: base.concat([ "NDEBUG", "CPLUSPLUS_BUILD_LIB" @@ -22,13 +17,21 @@ QtcLibrary { Group { prefix: "../3rdparty/cplusplus/" files: [ + "AST.cpp", + "AST.h", + "ASTClone.cpp", + "ASTMatch0.cpp", + "ASTMatcher.cpp", + "ASTMatcher.h", "ASTPatternBuilder.cpp", - "CPlusPlus.h", - "LiteralTable.cpp", - "ObjectiveCTypeQualifiers.h", - "Templates.cpp", - "Templates.h", + "ASTPatternBuilder.h", + "ASTVisit.cpp", "ASTVisitor.cpp", + "ASTVisitor.h", + "ASTfwd.h", + "Bind.cpp", + "Bind.h", + "CPlusPlus.h", "Control.cpp", "Control.h", "CoreTypes.cpp", @@ -37,8 +40,12 @@ QtcLibrary { "DiagnosticClient.h", "FullySpecifiedType.cpp", "FullySpecifiedType.h", + "Keywords.cpp", + "Lexer.cpp", "Lexer.h", + "LiteralTable.cpp", "LiteralTable.h", + "Literals.cpp", "Literals.h", "MemoryPool.cpp", "MemoryPool.h", @@ -50,48 +57,36 @@ QtcLibrary { "Names.h", "ObjectiveCAtKeywords.cpp", "ObjectiveCTypeQualifiers.cpp", + "ObjectiveCTypeQualifiers.h", + "Parser.cpp", + "Parser.h", + "QtContextKeywords.cpp", + "QtContextKeywords.h", "Scope.cpp", "Scope.h", + "Symbol.cpp", + "Symbol.h", "SymbolVisitor.cpp", "SymbolVisitor.h", + "Symbols.cpp", "Symbols.h", + "Templates.cpp", + "Templates.h", + "Token.cpp", + "Token.h", + "TranslationUnit.cpp", + "TranslationUnit.h", "Type.cpp", "Type.h", "TypeMatcher.cpp", "TypeMatcher.h", "TypeVisitor.cpp", "TypeVisitor.h", - "AST.cpp", - "AST.h", - "ASTClone.cpp", - "ASTMatch0.cpp", - "ASTMatcher.cpp", - "ASTMatcher.h", - "ASTPatternBuilder.h", - "ASTVisit.cpp", - "ASTVisitor.h", - "ASTfwd.h", - "Bind.cpp", - "Bind.h", - "Keywords.cpp", - "Lexer.cpp", - "Literals.cpp", - "Parser.cpp", - "Parser.h", - "QtContextKeywords.cpp", - "QtContextKeywords.h", - "Symbol.cpp", - "Symbol.h", - "Symbols.cpp", - "Token.cpp", - "Token.h", - "TranslationUnit.cpp", - "TranslationUnit.h" ] } files: [ - "cplusplus.qrc", + "AlreadyConsideredClassContainer.h", "ASTParent.cpp", "ASTParent.h", "ASTPath.cpp", @@ -128,6 +123,8 @@ QtcLibrary { "Overview.h", "OverviewModel.cpp", "OverviewModel.h", + "PPToken.cpp", + "PPToken.h", "PreprocessorClient.cpp", "PreprocessorClient.h", "PreprocessorEnvironment.cpp", @@ -144,13 +141,12 @@ QtcLibrary { "TypeOfExpression.h", "TypePrettyPrinter.cpp", "TypePrettyPrinter.h", + "cplusplus.qrc", "findcdbbreakpoint.cpp", "findcdbbreakpoint.h", "pp-cctype.h", "pp-engine.cpp", "pp-engine.h", - "PPToken.cpp", - "PPToken.h", "pp-scanner.cpp", "pp-scanner.h", "pp.h", @@ -169,7 +165,7 @@ QtcLibrary { "images/slot_prot.png", "images/var.png", "images/var_priv.png", - "images/var_prot.png" + "images/var_prot.png", ] ProductModule { @@ -181,4 +177,3 @@ QtcLibrary { ] } } - diff --git a/src/libs/extensionsystem/extensionsystem.qbs b/src/libs/extensionsystem/extensionsystem.qbs index bbdd8b74b3..f7a90814cb 100644 --- a/src/libs/extensionsystem/extensionsystem.qbs +++ b/src/libs/extensionsystem/extensionsystem.qbs @@ -4,10 +4,6 @@ import "../QtcLibrary.qbs" as QtcLibrary QtcLibrary { name: "ExtensionSystem" - cpp.includePaths: [ - ".", - ".." - ] cpp.defines: base.concat([ "EXTENSIONSYSTEM_LIBRARY", "IDE_TEST_DIR=\".\"" @@ -18,10 +14,6 @@ QtcLibrary { Depends { name: "Aggregation" } files: [ - "plugindetailsview.ui", - "pluginerrorview.ui", - "pluginview.qrc", - "pluginview.ui", "extensionsystem_global.h", "invoker.cpp", "invoker.h", @@ -34,19 +26,23 @@ QtcLibrary { "plugincollection.h", "plugindetailsview.cpp", "plugindetailsview.h", + "plugindetailsview.ui", "pluginerroroverview.cpp", "pluginerroroverview.h", "pluginerroroverview.ui", "pluginerrorview.cpp", "pluginerrorview.h", + "pluginerrorview.ui", "pluginmanager.cpp", "pluginmanager.h", "pluginmanager_p.h", + "pluginspec.cpp", "pluginspec.h", "pluginspec_p.h", "pluginview.cpp", "pluginview.h", - "pluginspec.cpp", + "pluginview.qrc", + "pluginview.ui", "images/error.png", "images/notloaded.png", "images/ok.png", diff --git a/src/libs/extensionsystem/invoker.cpp b/src/libs/extensionsystem/invoker.cpp index 689527a328..ac79d9aafd 100644 --- a/src/libs/extensionsystem/invoker.cpp +++ b/src/libs/extensionsystem/invoker.cpp @@ -37,6 +37,7 @@ InvokerBase::InvokerBase() useRet = false; nag = true; success = true; + connectionType = Qt::AutoConnection; target = 0; } @@ -53,6 +54,11 @@ bool InvokerBase::wasSuccessful() const return success; } +void InvokerBase::setConnectionType(Qt::ConnectionType c) +{ + connectionType = c; +} + void InvokerBase::invoke(QObject *t, const char *slot) { target = t; @@ -72,11 +78,11 @@ void InvokerBase::invoke(QObject *t, const char *slot) return; QMetaMethod method = target->metaObject()->method(idx); if (useRet) - success = method.invoke(target, ret, + success = method.invoke(target, connectionType, ret, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]); else - success = method.invoke(target, + success = method.invoke(target, connectionType, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]); } diff --git a/src/libs/extensionsystem/invoker.h b/src/libs/extensionsystem/invoker.h index 6ccfc73148..3f4b1ceca6 100644 --- a/src/libs/extensionsystem/invoker.h +++ b/src/libs/extensionsystem/invoker.h @@ -46,6 +46,7 @@ public: ~InvokerBase(); bool wasSuccessful() const; + void setConnectionType(Qt::ConnectionType connectionType); template <class T> void addArgument(const T &t) { @@ -73,6 +74,7 @@ private: int lastArg; bool success; bool useRet; + Qt::ConnectionType connectionType; mutable bool nag; }; diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp index e4aaf4d761..b718f31965 100644 --- a/src/libs/extensionsystem/optionsparser.cpp +++ b/src/libs/extensionsystem/optionsparser.cpp @@ -72,8 +72,10 @@ bool OptionsParser::parse() continue; if (checkForProfilingOption()) continue; +#ifdef WITH_TESTS if (checkForTestOption()) continue; +#endif if (checkForAppOption()) continue; if (checkForPluginOption()) diff --git a/src/libs/extensionsystem/pluginerroroverview.cpp b/src/libs/extensionsystem/pluginerroroverview.cpp index f5ee645915..cf014b67e1 100644 --- a/src/libs/extensionsystem/pluginerroroverview.cpp +++ b/src/libs/extensionsystem/pluginerroroverview.cpp @@ -35,43 +35,12 @@ Q_DECLARE_METATYPE(ExtensionSystem::PluginSpec*) namespace ExtensionSystem { -namespace Internal { - -class PluginErrorOverviewPrivate : public QObject -{ - Q_OBJECT -public: - PluginErrorOverviewPrivate(QDialog *dialog); - ~PluginErrorOverviewPrivate(); - -private slots: - void showDetails(QListWidgetItem *item); - -private: - Ui::PluginErrorOverview *m_ui; -}; - -} // Internal -} // ExtensionSystem - -using namespace ExtensionSystem; -using namespace ExtensionSystem::Internal; PluginErrorOverview::PluginErrorOverview(QWidget *parent) : QDialog(parent), - d(new PluginErrorOverviewPrivate(this)) -{ -} - -PluginErrorOverview::~PluginErrorOverview() + m_ui(new Internal::Ui::PluginErrorOverview) { - delete d; -} - -PluginErrorOverviewPrivate::PluginErrorOverviewPrivate(QDialog *dialog) - : m_ui(new Ui::PluginErrorOverview) -{ - m_ui->setupUi(dialog); + m_ui->setupUi(this); m_ui->buttonBox->addButton(tr("Continue"), QDialogButtonBox::AcceptRole); foreach (PluginSpec *spec, PluginManager::plugins()) { @@ -90,12 +59,12 @@ PluginErrorOverviewPrivate::PluginErrorOverviewPrivate(QDialog *dialog) m_ui->pluginList->setCurrentRow(0); } -PluginErrorOverviewPrivate::~PluginErrorOverviewPrivate() +PluginErrorOverview::~PluginErrorOverview() { delete m_ui; } -void PluginErrorOverviewPrivate::showDetails(QListWidgetItem *item) +void PluginErrorOverview::showDetails(QListWidgetItem *item) { if (item) { PluginSpec *spec = item->data(Qt::UserRole).value<PluginSpec *>(); @@ -105,4 +74,4 @@ void PluginErrorOverviewPrivate::showDetails(QListWidgetItem *item) } } -#include "pluginerroroverview.moc" +} // namespace ExtensionSystem diff --git a/src/libs/extensionsystem/pluginerroroverview.h b/src/libs/extensionsystem/pluginerroroverview.h index 8ec826aace..08394ee523 100644 --- a/src/libs/extensionsystem/pluginerroroverview.h +++ b/src/libs/extensionsystem/pluginerroroverview.h @@ -34,13 +34,15 @@ #include <QDialog> -namespace ExtensionSystem { +QT_BEGIN_NAMESPACE +class QListWidgetItem; +QT_END_NAMESPACE -class PluginManager; +namespace ExtensionSystem { namespace Internal { -class PluginErrorOverviewPrivate; -} +namespace Ui { class PluginErrorOverview; } +} // namespace Internal class EXTENSIONSYSTEM_EXPORT PluginErrorOverview : public QDialog { @@ -50,8 +52,11 @@ public: explicit PluginErrorOverview(QWidget *parent = 0); ~PluginErrorOverview(); +private slots: + void showDetails(QListWidgetItem *item); + private: - Internal::PluginErrorOverviewPrivate *d; + Internal::Ui::PluginErrorOverview *m_ui; }; } // ExtensionSystem diff --git a/src/libs/glsl/glsl.qbs b/src/libs/glsl/glsl.qbs index 7ee3557673..0a49bc50db 100644 --- a/src/libs/glsl/glsl.qbs +++ b/src/libs/glsl/glsl.qbs @@ -4,10 +4,6 @@ import "../QtcLibrary.qbs" as QtcLibrary QtcLibrary { name: "GLSL" - cpp.includePaths: [ - ".", - ".." - ] cpp.defines: base.concat([ "QT_CREATOR", "GLSL_BUILD_LIB" @@ -17,40 +13,35 @@ QtcLibrary { Depends { name: "Qt.gui" } files: [ + "glsl.g", "glsl.h", - "glsllexer.h", - "glslparser.h", - "glslparsertable_p.h", + "glslast.cpp", "glslast.h", + "glslastdump.cpp", + "glslastdump.h", + "glslastvisitor.cpp", "glslastvisitor.h", + "glslengine.cpp", "glslengine.h", - "glslmemorypool.h", - "glslastdump.h", - "glslsemantic.h", - "glsltype.h", - "glsltypes.h", - "glslsymbol.h", - "glslsymbols.h", "glslkeywords.cpp", - "glslparser.cpp", - "glslparsertable.cpp", "glsllexer.cpp", - "glslast.cpp", - "glslastvisitor.cpp", - "glslengine.cpp", + "glsllexer.h", "glslmemorypool.cpp", - "glslastdump.cpp", + "glslmemorypool.h", + "glslparser.cpp", + "glslparser.h", + "glslparsertable.cpp", + "glslparsertable_p.h", "glslsemantic.cpp", - "glsltype.cpp", - "glsltypes.cpp", + "glslsemantic.h", "glslsymbol.cpp", + "glslsymbol.h", "glslsymbols.cpp", - "glsl.g" + "glslsymbols.h", + "glsltype.cpp", + "glsltype.h", + "glsltypes.cpp", + "glsltypes.h", ] - - ProductModule { - Depends { name: "cpp" } - cpp.includePaths: ["."] - } } diff --git a/src/libs/languageutils/languageutils.qbs b/src/libs/languageutils/languageutils.qbs index abd23f95c8..811c4a9609 100644 --- a/src/libs/languageutils/languageutils.qbs +++ b/src/libs/languageutils/languageutils.qbs @@ -4,11 +4,7 @@ import "../QtcLibrary.qbs" as QtcLibrary QtcLibrary { name: "LanguageUtils" - cpp.includePaths: [ - ".", - "..", - "../3rdparty/cplusplus" - ] + cpp.includePaths: base.concat("../3rdparty/cplusplus") cpp.defines: base.concat([ "QT_CREATOR", "LANGUAGEUTILS_BUILD_DIR" @@ -19,11 +15,11 @@ QtcLibrary { Depends { name: "Qt.core" } files: [ - "languageutils_global.h", - "fakemetaobject.h", + "componentversion.cpp", "componentversion.h", "fakemetaobject.cpp", - "componentversion.cpp" + "fakemetaobject.h", + "languageutils_global.h", ] } diff --git a/src/libs/qmldebug/qmldebug.qbs b/src/libs/qmldebug/qmldebug.qbs index c2e8a40996..c43a728280 100644 --- a/src/libs/qmldebug/qmldebug.qbs +++ b/src/libs/qmldebug/qmldebug.qbs @@ -4,10 +4,6 @@ import "../QtcLibrary.qbs" as QtcLibrary QtcLibrary { name: "QmlDebug" - cpp.includePaths: [ - ".", - ".." - ] cpp.defines: base.concat([ "QMLDEBUG_LIB" ]) @@ -27,28 +23,23 @@ QtcLibrary { "declarativetoolsclient.h", "qdebugmessageclient.cpp", "qdebugmessageclient.h", + "qmldebug_global.h", "qmldebugclient.cpp", "qmldebugclient.h", "qmldebugconstants.h", - "qmldebug_global.h", + "qmlenginedebugclient.h", "qmloutputparser.cpp", "qmloutputparser.h", "qmlprofilereventlocation.h", "qmlprofilereventtypes.h", "qmlprofilertraceclient.cpp", "qmlprofilertraceclient.h", + "qmltoolsclient.cpp", + "qmltoolsclient.h", "qpacketprotocol.cpp", "qpacketprotocol.h", - "qmlenginedebugclient.h", "qv8profilerclient.cpp", "qv8profilerclient.h", - "qmltoolsclient.cpp", - "qmltoolsclient.h" ] - - ProductModule { - Depends { name: "cpp" } - cpp.includePaths: ["."] - } } diff --git a/src/libs/qmleditorwidgets/colorbox.h b/src/libs/qmleditorwidgets/colorbox.h index cd2ec8bd30..1dff3be003 100644 --- a/src/libs/qmleditorwidgets/colorbox.h +++ b/src/libs/qmleditorwidgets/colorbox.h @@ -30,7 +30,7 @@ #ifndef COLORBOX_H #define COLORBOX_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QWidget> #include <qdeclarative.h> diff --git a/src/libs/qmleditorwidgets/colorbutton.cpp b/src/libs/qmleditorwidgets/colorbutton.cpp index aec1783a96..a991713e04 100644 --- a/src/libs/qmleditorwidgets/colorbutton.cpp +++ b/src/libs/qmleditorwidgets/colorbutton.cpp @@ -89,15 +89,15 @@ static inline QColor properColor(const QString &str) namespace QmlEditorWidgets { -void ColorButton::setColor(const QString &colorStr) +void ColorButton::setColor(const QVariant &colorStr) { - if (m_colorString == colorStr) + if (m_colorString == colorStr.toString()) return; - setEnabled(isColorString(colorStr)); + setEnabled(isColorString(colorStr.toString())); - m_colorString = colorStr; + m_colorString = colorStr.toString(); update(); emit colorChanged(); } diff --git a/src/libs/qmleditorwidgets/colorbutton.h b/src/libs/qmleditorwidgets/colorbutton.h index dedc3f7411..3a66e16701 100644 --- a/src/libs/qmleditorwidgets/colorbutton.h +++ b/src/libs/qmleditorwidgets/colorbutton.h @@ -30,7 +30,7 @@ #ifndef COLORBUTTON_H #define COLORBUTTON_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QToolButton> #include <qdeclarative.h> @@ -40,15 +40,15 @@ class QMLEDITORWIDGETS_EXPORT ColorButton : public QToolButton { Q_OBJECT -Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) +Q_PROPERTY(QVariant color READ color WRITE setColor NOTIFY colorChanged) Q_PROPERTY(bool noColor READ noColor WRITE setNoColor) Q_PROPERTY(bool showArrow READ showArrow WRITE setShowArrow) public: ColorButton(QWidget *parent = 0) : QToolButton (parent), m_colorString("#ffffff"), m_noColor(false), m_showArrow(true) {} - void setColor(const QString &colorStr); - QString color() const { return m_colorString; } + void setColor(const QVariant &colorStr); + QVariant color() const { return m_colorString; } QColor convertedColor() const; bool noColor() const { return m_noColor; } void setNoColor(bool f) { m_noColor = f; update(); } diff --git a/src/libs/qmleditorwidgets/colorwidgets.h b/src/libs/qmleditorwidgets/colorwidgets.h index c7a210296b..fdc667d091 100644 --- a/src/libs/qmleditorwidgets/colorwidgets.h +++ b/src/libs/qmleditorwidgets/colorwidgets.h @@ -30,7 +30,7 @@ #ifndef COLORWIDGET_H #define COLORWIDGET_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" namespace QmlEditorWidgets { diff --git a/src/libs/qmleditorwidgets/contextpanetextwidget.cpp b/src/libs/qmleditorwidgets/contextpanetextwidget.cpp index e9c60a2093..fcf13a6d9f 100644 --- a/src/libs/qmleditorwidgets/contextpanetextwidget.cpp +++ b/src/libs/qmleditorwidgets/contextpanetextwidget.cpp @@ -264,7 +264,7 @@ void ContextPaneTextWidget::onTextColorButtonToggled(bool flag) if (flag) ui->colorButton->setChecked(false); QPoint p = mapToGlobal(ui->textColorButton->pos()); - parentContextWidget->colorDialog()->setupColor(ui->textColorButton->color()); + parentContextWidget->colorDialog()->setupColor(ui->textColorButton->color().toString()); p = parentContextWidget->colorDialog()->parentWidget()->mapFromGlobal(p); parentContextWidget->onShowColorDialog(flag, p); } @@ -275,7 +275,7 @@ void ContextPaneTextWidget::onColorButtonToggled(bool flag) ui->textColorButton->setChecked(false); ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget()); QPoint p = mapToGlobal(ui->colorButton->pos()); - parentContextWidget->colorDialog()->setupColor(ui->colorButton->color()); + parentContextWidget->colorDialog()->setupColor(ui->colorButton->color().toString()); p = parentContextWidget->colorDialog()->parentWidget()->mapFromGlobal(p); parentContextWidget->onShowColorDialog(flag, p); } diff --git a/src/libs/qmleditorwidgets/contextpanetextwidget.h b/src/libs/qmleditorwidgets/contextpanetextwidget.h index a53228329f..a8611815b2 100644 --- a/src/libs/qmleditorwidgets/contextpanetextwidget.h +++ b/src/libs/qmleditorwidgets/contextpanetextwidget.h @@ -30,7 +30,7 @@ #ifndef CONTEXTPANETEXTWIDGET_H #define CONTEXTPANETEXTWIDGET_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QWidget> QT_BEGIN_NAMESPACE diff --git a/src/libs/qmleditorwidgets/contextpanewidget.cpp b/src/libs/qmleditorwidgets/contextpanewidget.cpp index 4a6fc752ae..ee88507835 100644 --- a/src/libs/qmleditorwidgets/contextpanewidget.cpp +++ b/src/libs/qmleditorwidgets/contextpanewidget.cpp @@ -28,6 +28,9 @@ ****************************************************************************/ #include "contextpanewidget.h" + +#include <utils/hostosinfo.h> + #include <QToolButton> #include <QFontComboBox> #include <QComboBox> @@ -48,6 +51,8 @@ #include "customcolordialog.h" #include "colorbutton.h" +using namespace Utils; + namespace QmlEditorWidgets { /* XPM */ @@ -101,12 +106,12 @@ DragWidget::DragWidget(QWidget *parent) : QFrame(parent) // TODO: The following code should be enabled for OSX // when QTBUG-23205 is fixed -#ifndef Q_OS_MAC - m_dropShadowEffect = new QGraphicsDropShadowEffect; - m_dropShadowEffect->setBlurRadius(6); - m_dropShadowEffect->setOffset(2, 2); - setGraphicsEffect(m_dropShadowEffect); -#endif + if (!HostOsInfo::isMacHost()) { + m_dropShadowEffect = new QGraphicsDropShadowEffect; + m_dropShadowEffect->setBlurRadius(6); + m_dropShadowEffect->setOffset(2, 2); + setGraphicsEffect(m_dropShadowEffect); + } } void DragWidget::mousePressEvent(QMouseEvent * event) @@ -126,12 +131,12 @@ void DragWidget::mouseReleaseEvent(QMouseEvent *event) m_startPos = QPoint(-1, -1); // TODO: The following code should be enabled for OSX // when QTBUG-23205 is fixed -#ifndef Q_OS_MAC - m_dropShadowEffect = new QGraphicsDropShadowEffect; - m_dropShadowEffect->setBlurRadius(6); - m_dropShadowEffect->setOffset(2, 2); - setGraphicsEffect(m_dropShadowEffect); -#endif + if (!HostOsInfo::isMacHost()) { + m_dropShadowEffect = new QGraphicsDropShadowEffect; + m_dropShadowEffect->setBlurRadius(6); + m_dropShadowEffect->setOffset(2, 2); + setGraphicsEffect(m_dropShadowEffect); + } } QFrame::mouseReleaseEvent(event); } @@ -176,16 +181,14 @@ void DragWidget::protectedMoved() void DragWidget::leaveEvent(QEvent *) { -#ifdef Q_OS_MAC - unsetCursor(); -#endif + if (HostOsInfo::isMacHost()) + unsetCursor(); } void DragWidget::enterEvent(QEvent *) { -#ifdef Q_OS_MAC - setCursor(Qt::ArrowCursor); -#endif + if (HostOsInfo::isMacHost()) + setCursor(Qt::ArrowCursor); } ContextPaneWidget::ContextPaneWidget(QWidget *parent) : DragWidget(parent), m_currentWidget(0) @@ -231,9 +234,8 @@ ContextPaneWidget::ContextPaneWidget(QWidget *parent) : DragWidget(parent), m_cu m_disableAction->setCheckable(true); connect(m_disableAction.data(), SIGNAL(toggled(bool)), this, SLOT(onDisable(bool))); m_pinned = false; -#ifdef Q_OS_MAC - setCursor(Qt::ArrowCursor); -#endif + if (HostOsInfo::isMacHost()) + setCursor(Qt::ArrowCursor); } ContextPaneWidget::~ContextPaneWidget() @@ -241,7 +243,7 @@ ContextPaneWidget::~ContextPaneWidget() //if the pane was never activated the widget is not in a widget tree if (!m_bauhausColorDialog.isNull()) delete m_bauhausColorDialog.data(); - m_bauhausColorDialog.clear(); + m_bauhausColorDialog = 0; } void ContextPaneWidget::activate(const QPoint &pos, const QPoint &alternative, const QPoint &alternative2, bool pinned) diff --git a/src/libs/qmleditorwidgets/contextpanewidget.h b/src/libs/qmleditorwidgets/contextpanewidget.h index ce6d2f900b..3fffe1a1b7 100644 --- a/src/libs/qmleditorwidgets/contextpanewidget.h +++ b/src/libs/qmleditorwidgets/contextpanewidget.h @@ -30,9 +30,9 @@ #ifndef CONTEXTPANEWIDGET_H #define CONTEXTPANEWIDGET_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QFrame> -#include <QWeakPointer> +#include <QPointer> QT_BEGIN_NAMESPACE class QToolButton; @@ -75,7 +75,7 @@ private: QGraphicsDropShadowEffect *m_dropShadowEffect; QGraphicsOpacityEffect *m_opacityEffect; QPoint m_startPos; - QWeakPointer<QWidget> m_secondaryTarget; + QPointer<QWidget> m_secondaryTarget; }; class QMLEDITORWIDGETS_EXPORT ContextPaneWidget : public DragWidget @@ -137,9 +137,9 @@ private: ContextPaneWidgetImage *m_imageWidget; ContextPaneWidgetImage *m_borderImageWidget; ContextPaneWidgetRectangle *m_rectangleWidget; - QWeakPointer<CustomColorDialog> m_bauhausColorDialog; - QWeakPointer<QAction> m_resetAction; - QWeakPointer<QAction> m_disableAction; + QPointer<CustomColorDialog> m_bauhausColorDialog; + QPointer<QAction> m_resetAction; + QPointer<QAction> m_disableAction; QString m_colorName; QPoint m_originalPos; bool m_pinned; diff --git a/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp b/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp index 5758e7384f..bab194ef89 100644 --- a/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp +++ b/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp @@ -28,6 +28,9 @@ ****************************************************************************/ #include "contextpanewidgetimage.h" + +#include <utils/hostosinfo.h> + #include "ui_contextpanewidgetimage.h" #include "ui_contextpanewidgetborderimage.h" #include <qmljs/qmljspropertyreader.h> @@ -610,12 +613,12 @@ PreviewLabel::PreviewLabel(QWidget *parent) // TODO: The following code should be enabled for OSX // when QTBUG-23205 is fixed -#ifndef Q_OS_MAC - QGraphicsDropShadowEffect *dropShadowEffect = new QGraphicsDropShadowEffect; - dropShadowEffect->setBlurRadius(4); - dropShadowEffect->setOffset(2, 2); - m_hooverInfo->setGraphicsEffect(dropShadowEffect); -#endif + if (!Utils::HostOsInfo::isMacHost()) { + QGraphicsDropShadowEffect *dropShadowEffect = new QGraphicsDropShadowEffect; + dropShadowEffect->setBlurRadius(4); + dropShadowEffect->setOffset(2, 2); + m_hooverInfo->setGraphicsEffect(dropShadowEffect); + } m_hooverInfo->setAutoFillBackground(true); m_hooverInfo->raise(); } diff --git a/src/libs/qmleditorwidgets/contextpanewidgetimage.h b/src/libs/qmleditorwidgets/contextpanewidgetimage.h index 9f057ea629..39df5fa38d 100644 --- a/src/libs/qmleditorwidgets/contextpanewidgetimage.h +++ b/src/libs/qmleditorwidgets/contextpanewidgetimage.h @@ -30,11 +30,13 @@ #ifndef CONTEXTPANEWIDGETIMAGE_H #define CONTEXTPANEWIDGETIMAGE_H -#include <qmleditorwidgets_global.h> -#include <QLabel> -#include <contextpanewidget.h> +#include "qmleditorwidgets_global.h" +#include "contextpanewidget.h" #include <qdrawutil.h> +#include <QLabel> +#include <QPointer> + QT_BEGIN_NAMESPACE namespace Ui { class ContextPaneWidgetImage; @@ -156,7 +158,7 @@ private: Ui::ContextPaneWidgetImage *ui; Ui::ContextPaneWidgetBorderImage *uiBorderImage; QString m_path; - QWeakPointer<PreviewDialog> m_previewDialog; + QPointer<PreviewDialog> m_previewDialog; FileWidget *m_fileWidget; QLabel *m_sizeLabel; bool m_borderImage; diff --git a/src/libs/qmleditorwidgets/contextpanewidgetrectangle.h b/src/libs/qmleditorwidgets/contextpanewidgetrectangle.h index c881647f38..02c1492924 100644 --- a/src/libs/qmleditorwidgets/contextpanewidgetrectangle.h +++ b/src/libs/qmleditorwidgets/contextpanewidgetrectangle.h @@ -30,7 +30,7 @@ #ifndef CONTEXTPANEWIDGETRECTANGLE_H #define CONTEXTPANEWIDGETRECTANGLE_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QWidget> QT_BEGIN_NAMESPACE diff --git a/src/libs/qmleditorwidgets/customcolordialog.cpp b/src/libs/qmleditorwidgets/customcolordialog.cpp index e727a67cb7..195de19d8a 100644 --- a/src/libs/qmleditorwidgets/customcolordialog.cpp +++ b/src/libs/qmleditorwidgets/customcolordialog.cpp @@ -31,6 +31,8 @@ #include "huecontrol.h" #include "colorbox.h" +#include <utils/hostosinfo.h> + #include <QHBoxLayout> #include <QLabel> #include <QPainter> @@ -40,6 +42,8 @@ #include <QDialogButtonBox> #include <QGraphicsEffect> +using namespace Utils; + namespace QmlEditorWidgets { CustomColorDialog::CustomColorDialog(QWidget *parent) : QFrame(parent ) @@ -51,12 +55,12 @@ CustomColorDialog::CustomColorDialog(QWidget *parent) : QFrame(parent ) // TODO: The following code should be enabled for OSX // when QTBUG-23205 is fixed -#ifndef Q_OS_MAC - QGraphicsDropShadowEffect *dropShadowEffect = new QGraphicsDropShadowEffect; - dropShadowEffect->setBlurRadius(6); - dropShadowEffect->setOffset(2, 2); - setGraphicsEffect(dropShadowEffect); -#endif + if (!HostOsInfo::isMacHost()) { + QGraphicsDropShadowEffect *dropShadowEffect = new QGraphicsDropShadowEffect; + dropShadowEffect->setBlurRadius(6); + dropShadowEffect->setOffset(2, 2); + setGraphicsEffect(dropShadowEffect); + } setAutoFillBackground(true); m_hueControl = new HueControl(this); @@ -183,16 +187,14 @@ void CustomColorDialog::setupWidgets() void CustomColorDialog::leaveEvent(QEvent *) { -#ifdef Q_OS_MAC - unsetCursor(); -#endif + if (HostOsInfo::isMacHost()) + unsetCursor(); } void CustomColorDialog::enterEvent(QEvent *) { -#ifdef Q_OS_MAC - setCursor(Qt::ArrowCursor); -#endif + if (HostOsInfo::isMacHost()) + setCursor(Qt::ArrowCursor); } diff --git a/src/libs/qmleditorwidgets/customcolordialog.h b/src/libs/qmleditorwidgets/customcolordialog.h index 55fe43d1f0..24acc341fe 100644 --- a/src/libs/qmleditorwidgets/customcolordialog.h +++ b/src/libs/qmleditorwidgets/customcolordialog.h @@ -30,7 +30,7 @@ #ifndef CUSTOMCOLORDIALOG_H #define CUSTOMCOLORDIALOG_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QFrame> QT_BEGIN_NAMESPACE diff --git a/src/libs/qmleditorwidgets/filewidget.h b/src/libs/qmleditorwidgets/filewidget.h index 9aa917e540..2c30ce1ceb 100644 --- a/src/libs/qmleditorwidgets/filewidget.h +++ b/src/libs/qmleditorwidgets/filewidget.h @@ -31,7 +31,7 @@ #ifndef FILEWIDGET_H #define FILEWIDGET_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QWidget> diff --git a/src/libs/qmleditorwidgets/fontsizespinbox.h b/src/libs/qmleditorwidgets/fontsizespinbox.h index a82291ffc6..c494b9405b 100644 --- a/src/libs/qmleditorwidgets/fontsizespinbox.h +++ b/src/libs/qmleditorwidgets/fontsizespinbox.h @@ -30,7 +30,7 @@ #ifndef FONTSIZESPINBOX_H #define FONTSIZESPINBOX_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QAbstractSpinBox> namespace QmlEditorWidgets { diff --git a/src/libs/qmleditorwidgets/gradientline.h b/src/libs/qmleditorwidgets/gradientline.h index 433373f205..247f8fbe7f 100644 --- a/src/libs/qmleditorwidgets/gradientline.h +++ b/src/libs/qmleditorwidgets/gradientline.h @@ -30,7 +30,7 @@ #ifndef GRADIENTLINE_H #define GRADIENTLINE_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QWidget> #include <QLinearGradient> diff --git a/src/libs/qmleditorwidgets/huecontrol.h b/src/libs/qmleditorwidgets/huecontrol.h index b4323c2a39..f9e6d1d88e 100644 --- a/src/libs/qmleditorwidgets/huecontrol.h +++ b/src/libs/qmleditorwidgets/huecontrol.h @@ -30,7 +30,7 @@ #ifndef HUECONTROL_H #define HUECONTROL_H -#include <qmleditorwidgets_global.h> +#include "qmleditorwidgets_global.h" #include <QWidget> #include <qdeclarative.h> diff --git a/src/libs/qmleditorwidgets/qmleditorwidgets.pro b/src/libs/qmleditorwidgets/qmleditorwidgets.pro index c449baac71..99eced9375 100644 --- a/src/libs/qmleditorwidgets/qmleditorwidgets.pro +++ b/src/libs/qmleditorwidgets/qmleditorwidgets.pro @@ -7,5 +7,6 @@ unix:QMAKE_CXXFLAGS_DEBUG += -O3 include(../../qtcreatorlibrary.pri) include(../qmljs/qmljs.pri) +include(../utils/utils.pri) include(qmleditorwidgets-lib.pri) diff --git a/src/libs/qmleditorwidgets/qmleditorwidgets.qbs b/src/libs/qmleditorwidgets/qmleditorwidgets.qbs index 551056f6f5..19099b4156 100644 --- a/src/libs/qmleditorwidgets/qmleditorwidgets.qbs +++ b/src/libs/qmleditorwidgets/qmleditorwidgets.qbs @@ -4,11 +4,7 @@ import "../QtcLibrary.qbs" as QtcLibrary QtcLibrary { name: "QmlEditorWidgets" - cpp.includePaths: [ - ".", - "..", - "easingpane" - ] + cpp.includePaths: base.concat("easingpane") cpp.defines: base.concat([ "QWEAKPOINTER_ENABLE_ARROW", "BUILD_QMLEDITORWIDGETS_LIB", @@ -19,49 +15,45 @@ QtcLibrary { Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["widgets", "declarative", "script"] } Depends { name: "QmlJS" } + Depends { name: "Utils" } files: [ - "resources.qrc", - "fontsizespinbox.h", - "filewidget.h", - "contextpanewidgetrectangle.h", - "contextpanewidgetimage.h", - "contextpanewidget.h", - "contextpanetextwidget.h", - "colorwidgets.h", - "colorbutton.h", + "colorbox.cpp", "colorbox.h", + "colorbutton.cpp", + "colorbutton.h", + "colorwidgets.cpp", + "colorwidgets.h", + "contextpanetext.ui", + "contextpanetextwidget.cpp", + "contextpanetextwidget.h", + "contextpanewidget.cpp", + "contextpanewidget.h", + "contextpanewidgetborderimage.ui", + "contextpanewidgetimage.cpp", + "contextpanewidgetimage.h", + "contextpanewidgetimage.ui", + "contextpanewidgetrectangle.cpp", + "contextpanewidgetrectangle.h", + "contextpanewidgetrectangle.ui", + "customcolordialog.cpp", "customcolordialog.h", + "filewidget.cpp", + "filewidget.h", + "fontsizespinbox.cpp", + "fontsizespinbox.h", + "gradientline.cpp", "gradientline.h", + "huecontrol.cpp", "huecontrol.h", "qmleditorwidgets_global.h", - "fontsizespinbox.cpp", - "filewidget.cpp", - "contextpanewidgetrectangle.cpp", - "contextpanewidgetimage.cpp", - "contextpanewidget.cpp", - "contextpanetextwidget.cpp", - "colorwidgets.cpp", - "colorbox.cpp", - "customcolordialog.cpp", - "huecontrol.cpp", - "gradientline.cpp", - "colorbutton.cpp", - "contextpanewidgetrectangle.ui", - "contextpanewidgetimage.ui", - "contextpanewidgetborderimage.ui", - "contextpanetext.ui", - "easingpane/easinggraph.cpp", + "resources.qrc", "easingpane/easingcontextpane.cpp", - "easingpane/easinggraph.h", "easingpane/easingcontextpane.h", + "easingpane/easingcontextpane.ui", + "easingpane/easinggraph.cpp", + "easingpane/easinggraph.h", "easingpane/easingpane.qrc", - "easingpane/easingcontextpane.ui" ] - - ProductModule { - Depends { name: "cpp" } - cpp.includePaths: ["."] - } } diff --git a/src/libs/qmljs/consoleitem.cpp b/src/libs/qmljs/consoleitem.cpp new file mode 100644 index 0000000000..9e9150d145 --- /dev/null +++ b/src/libs/qmljs/consoleitem.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "consoleitem.h" + +namespace QmlJS { + +/////////////////////////////////////////////////////////////////////// +// +// ConsoleItem +// +/////////////////////////////////////////////////////////////////////// + +ConsoleItem::ConsoleItem(ConsoleItem *parent, ConsoleItem::ItemType itemType, + const QString &text) + : m_parentItem(parent), + itemType(itemType), + line(-1) + +{ + setText(text); +} + +ConsoleItem::~ConsoleItem() +{ + qDeleteAll(m_childItems); +} + +ConsoleItem *ConsoleItem::child(int number) +{ + return m_childItems.value(number); +} + +int ConsoleItem::childCount() const +{ + return m_childItems.size(); +} + +int ConsoleItem::childNumber() const +{ + if (m_parentItem) + return m_parentItem->m_childItems.indexOf(const_cast<ConsoleItem *>(this)); + + return 0; +} + +bool ConsoleItem::insertChildren(int position, int count) +{ + if (position < 0 || position > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) { + ConsoleItem *item = new ConsoleItem(this, ConsoleItem::UndefinedType, + QString()); + m_childItems.insert(position, item); + } + + return true; +} + +void ConsoleItem::insertChild(ConsoleItem *item, bool sorted) +{ + if (!sorted) { + m_childItems.insert(m_childItems.count(), item); + return; + } + + int i = 0; + for (; i < m_childItems.count(); i++) { + if (item->m_text < m_childItems[i]->m_text) + break; + } + m_childItems.insert(i, item); +} + +bool ConsoleItem::insertChild(int position, ConsoleItem *item) +{ + if (position < 0 || position > m_childItems.size()) + return false; + + m_childItems.insert(position, item); + + return true; +} + +ConsoleItem *ConsoleItem::parent() +{ + return m_parentItem; +} + +bool ConsoleItem::removeChildren(int position, int count) +{ + if (position < 0 || position + count > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) + delete m_childItems.takeAt(position); + + return true; +} + +bool ConsoleItem::detachChild(int position) +{ + if (position < 0 || position > m_childItems.size()) + return false; + + m_childItems.removeAt(position); + + return true; +} + +void ConsoleItem::setText(const QString &text) +{ + m_text = text; + for (int i = 0; i < m_text.length(); ++i) { + if (m_text.at(i).isPunct()) + m_text.insert(++i, QChar(0x200b)); // ZERO WIDTH SPACE + } +} + +const QString &ConsoleItem::text() const +{ + return m_text; +} + +} // QmlJS diff --git a/src/plugins/remotelinux/deployablefile.h b/src/libs/qmljs/consoleitem.h index 452850207d..15db44387c 100644 --- a/src/plugins/remotelinux/deployablefile.h +++ b/src/libs/qmljs/consoleitem.h @@ -27,55 +27,58 @@ ** ****************************************************************************/ -#ifndef DEPLOYABLEFILE_H -#define DEPLOYABLEFILE_H +#ifndef CONSOLEITEM_H +#define CONSOLEITEM_H -#include "remotelinux_export.h" +#include "qmljs_global.h" -#include <QFileInfo> -#include <QHash> +#include <QList> #include <QString> -namespace RemoteLinux { +namespace QmlJS { -class REMOTELINUX_EXPORT DeployableFile +class QMLJS_EXPORT ConsoleItem { public: - enum Type + enum ItemType { - TypeNormal, - TypeExecutable + UndefinedType = 0x01, // Can be used for unknown and for Return values + DebugType = 0x02, + WarningType = 0x04, + ErrorType = 0x08, + InputType = 0x10, + DefaultTypes = InputType | UndefinedType }; + Q_DECLARE_FLAGS(ItemTypes, ItemType) - DeployableFile() {} + ConsoleItem(ConsoleItem *parent, + ConsoleItem::ItemType type = ConsoleItem::UndefinedType, + const QString &data = QString()); + ~ConsoleItem(); - DeployableFile(const QString &localFilePath, const QString &remoteDir, Type type = TypeNormal) - : localFilePath(localFilePath), remoteDir(remoteDir), type(type) {} + ConsoleItem *child(int number); + int childCount() const; + bool insertChildren(int position, int count); + void insertChild(ConsoleItem *item, bool sorted); + bool insertChild(int position, ConsoleItem *item); + ConsoleItem *parent(); + bool removeChildren(int position, int count); + bool detachChild(int position); + int childNumber() const; + void setText(const QString &text); + const QString &text() const; - bool operator==(const DeployableFile &other) const - { - return localFilePath == other.localFilePath - && remoteDir == other.remoteDir; - } - - QString remoteFilePath() const { - return remoteDir + QLatin1Char('/') + QFileInfo(localFilePath).fileName(); - } - - bool isExecutable() const { - return type == TypeExecutable; - } +private: + ConsoleItem *m_parentItem; + QList<ConsoleItem *> m_childItems; + QString m_text; - QString localFilePath; - QString remoteDir; - Type type; +public: + ConsoleItem::ItemType itemType; + QString file; + int line; }; -inline uint qHash(const DeployableFile &d) -{ - return qHash(qMakePair(d.localFilePath, d.remoteDir)); -} - -} // namespace RemoteLinux +} // QmlJS -#endif // DEPLOYABLEFILE_H +#endif // CONSOLEITEM_H diff --git a/src/plugins/qmldesigner/extrasplugin/extrasplugin.cpp b/src/libs/qmljs/consolemanagerinterface.cpp index 3e25be0156..c78e3a6633 100644 --- a/src/plugins/qmldesigner/extrasplugin/extrasplugin.cpp +++ b/src/libs/qmljs/consolemanagerinterface.cpp @@ -27,30 +27,28 @@ ** ****************************************************************************/ -#include "extrasplugin.h" -#include <widgetplugin_helper.h> -#include <QtPlugin> +#include "consolemanagerinterface.h" -namespace QmlDesigner { +namespace QmlJS { +static ConsoleManagerInterface *g_instance = 0; -ExtrasPlugin::ExtrasPlugin() +ConsoleManagerInterface::ConsoleManagerInterface(QObject *parent) + : QObject(parent) { + Q_ASSERT(!g_instance); + g_instance = this; } -QString ExtrasPlugin::pluginName() const +ConsoleManagerInterface::~ConsoleManagerInterface() { - return ("ExtrasPlugin"); + Q_ASSERT(g_instance == this); + g_instance = 0; } -QString ExtrasPlugin::metaInfo() const +ConsoleManagerInterface *ConsoleManagerInterface::instance() { - return QString(":/extrasplugin/extras.metainfo"); + return g_instance; } -} - -#if QT_VERSION < 0x050000 -Q_EXPORT_PLUGIN(QmlDesigner::ExtrasPlugin) -#endif - +} // QmlJS diff --git a/src/libs/qmljs/consolemanagerinterface.h b/src/libs/qmljs/consolemanagerinterface.h new file mode 100644 index 0000000000..4ee6067f29 --- /dev/null +++ b/src/libs/qmljs/consolemanagerinterface.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CONSOLEMANAGERINTERFACE_H +#define CONSOLEMANAGERINTERFACE_H + +#include "qmljs_global.h" +#include "consoleitem.h" + +#include <QObject> + +namespace QmlJS { + +class IScriptEvaluator; +class QMLJS_EXPORT ConsoleManagerInterface : public QObject +{ + Q_OBJECT +public: + ConsoleManagerInterface(QObject *parent = 0); + ~ConsoleManagerInterface(); + + static ConsoleManagerInterface *instance(); + + virtual void showConsolePane() = 0; + + virtual ConsoleItem *rootItem() const = 0; + + virtual void setScriptEvaluator(IScriptEvaluator *scriptEvaluator) = 0; + virtual void setContext(const QString &context) = 0; + + virtual void printToConsolePane(ConsoleItem::ItemType itemType, const QString &text, + bool bringToForeground = false) = 0; + virtual void printToConsolePane(ConsoleItem *item, bool bringToForeground = false) = 0; +}; + +} // QmlJS + +#endif // CONSOLEMANAGERINTERFACE_H diff --git a/tests/manual/appwizards/qmlimportscenario_02/subfolder3/com/nokia/QmlModule02/QmlComponent02.qml b/src/libs/qmljs/iscriptevaluator.h index e954b7b670..85585ee56f 100644 --- a/tests/manual/appwizards/qmlimportscenario_02/subfolder3/com/nokia/QmlModule02/QmlComponent02.qml +++ b/src/libs/qmljs/iscriptevaluator.h @@ -27,19 +27,22 @@ ** ****************************************************************************/ -import Qt 4.7 +#ifndef ISCRIPTEVALUATOR_H +#define ISCRIPTEVALUATOR_H -Rectangle { - color: "#ffdddd" +#include "qmljs_global.h" - Image { - source: "tomato.svg" - anchors.right: parent.right - anchors.bottom: parent.bottom - } +#include <QString> - Text { - text: "QmlComponent02" - font.pointSize: 14 - } -} +namespace QmlJS { + +class IScriptEvaluator +{ +public: + IScriptEvaluator() {} + + virtual bool evaluateScript(const QString &script) = 0; +}; +} // QmlJS + +#endif // ISCRIPTEVALUATOR_H diff --git a/src/libs/qmljs/parser/gen-parser.sh b/src/libs/qmljs/parser/gen-parser.sh index 1a755052e9..e6fdadf675 100755 --- a/src/libs/qmljs/parser/gen-parser.sh +++ b/src/libs/qmljs/parser/gen-parser.sh @@ -1,5 +1,15 @@ #!/bin/bash +# This is the script that generates the copy of the QmlJS parser from the sources +# in the qtdeclarative source tree. +# +# It applies a bunch of renames to make the source compatible with the Qt Creator +# sources as well as rewrites of the licenses. +# +# Example: +# cd src/libs/qmljs/parser +# QTDIR=~/path/to/qtdeclarative-checkout ./gen-parser.sh + me=$(dirname $0) for i in $QTDIR/src/qml/qml/parser/*.{g,h,cpp,pri}; do diff --git a/src/libs/qmljs/qmljs-lib.pri b/src/libs/qmljs/qmljs-lib.pri index bbc1d06bda..3d335f62f4 100644 --- a/src/libs/qmljs/qmljs-lib.pri +++ b/src/libs/qmljs/qmljs-lib.pri @@ -33,7 +33,11 @@ HEADERS += \ $$PWD/qmljsscopechain.h \ $$PWD/qmljsutils.h \ $$PWD/qmljsstaticanalysismessage.h \ - $$PWD/jsoncheck.h + $$PWD/jsoncheck.h \ + $$PWD/consolemanagerinterface.h \ + $$PWD/consoleitem.h \ + $$PWD/iscriptevaluator.h \ + $$PWD/qmljssimplereader.h SOURCES += \ $$PWD/qmljsbind.cpp \ @@ -58,7 +62,10 @@ SOURCES += \ $$PWD/qmljsscopechain.cpp \ $$PWD/qmljsutils.cpp \ $$PWD/qmljsstaticanalysismessage.cpp \ - $$PWD/jsoncheck.cpp + $$PWD/jsoncheck.cpp \ + $$PWD/consolemanagerinterface.cpp \ + $$PWD/consoleitem.cpp \ + $$PWD/qmljssimplereader.cpp RESOURCES += \ $$PWD/qmljs.qrc diff --git a/src/libs/qmljs/qmljs.qbs b/src/libs/qmljs/qmljs.qbs index d7b556b06b..7a981b7d2a 100644 --- a/src/libs/qmljs/qmljs.qbs +++ b/src/libs/qmljs/qmljs.qbs @@ -4,11 +4,7 @@ import "../QtcLibrary.qbs" as QtcLibrary QtcLibrary { name: "QmlJS" - cpp.includePaths: [ - ".", - "..", - "parser" - ] + cpp.includePaths: base.concat("parser") cpp.defines: base.concat([ "QMLJS_BUILD_DIR", "QT_CREATOR" @@ -21,6 +17,8 @@ QtcLibrary { Depends { name: "Qt"; submodules: ["widgets", "script"] } files: [ + "jsoncheck.cpp", + "jsoncheck.h", "qmljs.qrc", "qmljs_global.h", "qmljsbind.cpp", @@ -55,6 +53,7 @@ QtcLibrary { "qmljspropertyreader.cpp", "qmljspropertyreader.h", "qmljsreformatter.cpp", + "qmljsreformatter.h", "qmljsrewriter.cpp", "qmljsrewriter.h", "qmljsscanner.cpp", @@ -73,9 +72,6 @@ QtcLibrary { "qmljsutils.h", "qmljsvalueowner.cpp", "qmljsvalueowner.h", - "qmljsreformatter.h", - "jsoncheck.cpp", - "jsoncheck.h", "images/element.png", "images/func.png", "images/property.png", @@ -99,16 +95,17 @@ QtcLibrary { "parser/qmljslexer_p.h", "parser/qmljsmemorypool_p.h", "parser/qmljsparser.cpp", - "parser/qmljsparser_p.h" + "parser/qmljsparser_p.h", + "consolemanagerinterface.cpp", + "consolemanagerinterface.h", + "consoleitem.cpp", + "consoleitem.h", + "iscriptevaluator.h" ] ProductModule { Depends { name: "cpp" } Depends { name: "LanguageUtils" } - cpp.includePaths: [ - ".", - "parser" - ] cpp.defines: [ "QT_CREATOR" ] diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index 1f46e4c58f..af670d4d88 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -502,8 +502,44 @@ private: bool _seenNonDeclarationStatement; }; +class VisualAspectsPropertyBlackList : public QStringList +{ +public: + VisualAspectsPropertyBlackList() + { + (*this) << QLatin1String("x") << QLatin1String("y") << QLatin1String("z") + << QLatin1String("width") << QLatin1String("height") << QLatin1String("color") + << QLatin1String("opacity") << QLatin1String("scale") + << QLatin1String("rotation") << QLatin1String("margins") + << QLatin1String("verticalCenterOffset") << QLatin1String("horizontalCenterOffset") + << QLatin1String("baselineOffset") << QLatin1String("bottomMargin") + << QLatin1String("topMargin") << QLatin1String("leftMargin") + << QLatin1String("rightMargin") << QLatin1String("baseline") + << QLatin1String("centerIn") << QLatin1String("fill") + << QLatin1String("left") << QLatin1String("right") + << QLatin1String("mirrored") << QLatin1String("verticalCenter") + << QLatin1String("horizontalCenter"); + + } +}; + +class UnsupportedTypesByVisualDesigner : public QStringList +{ +public: + UnsupportedTypesByVisualDesigner() + { + (*this) << QLatin1String("Transform") << QLatin1String("Timer") + << QLatin1String("Rotation") << QLatin1String("Scale") + << QLatin1String("Translate") << QLatin1String("Package") + << QLatin1String("Particles"); + } + +}; } // end of anonymous namespace +Q_GLOBAL_STATIC(VisualAspectsPropertyBlackList, visualAspectsPropertyBlackList) +Q_GLOBAL_STATIC(UnsupportedTypesByVisualDesigner, unsupportedTypesByVisualDesigner) + Check::Check(Document::Ptr doc, const ContextPtr &context) : _doc(doc) , _context(context) @@ -523,6 +559,11 @@ Check::Check(Document::Ptr doc, const ContextPtr &context) disableMessage(HintBinaryOperatorSpacing); disableMessage(HintOneStatementPerLine); disableMessage(HintExtraParentheses); + disableMessage(WarnImperativeCodeNotEditableInVisualDesigner); + disableMessage(WarnUnsupportedTypeInVisualDesigner); + disableMessage(WarnReferenceToParentItemNotSupportedByVisualDesigner); + disableMessage(WarnUndefinedValueForVisualDesigner); + disableMessage(WarnStatesOnlyInRootItemForVisualDesigner); } Check::~Check() @@ -568,21 +609,27 @@ bool Check::visit(UiProgram *) bool Check::visit(UiObjectInitializer *) { + QString typeName; m_propertyStack.push(StringSet()); - UiObjectDefinition *objectDefinition = cast<UiObjectDefinition *>(parent()); - if (objectDefinition && objectDefinition->qualifiedTypeNameId->name == "Component") - m_idStack.push(StringSet()); - UiObjectBinding *objectBinding = cast<UiObjectBinding *>(parent()); - if (objectBinding && objectBinding->qualifiedTypeNameId->name == "Component") - m_idStack.push(StringSet()); + UiQualifiedId *qualifiedTypeId = qualifiedTypeNameId(parent()); + if (qualifiedTypeId) { + typeName = qualifiedTypeId->name.toString(); + if (typeName == QLatin1String("Component")) + m_idStack.push(StringSet()); + } + + m_typeStack.push(typeName); + if (m_idStack.isEmpty()) m_idStack.push(StringSet()); + return true; } void Check::endVisit(UiObjectInitializer *) { m_propertyStack.pop(); + m_typeStack.pop(); UiObjectDefinition *objectDenition = cast<UiObjectDefinition *>(parent()); if (objectDenition && objectDenition->qualifiedTypeNameId->name == "Component") m_idStack.pop(); @@ -618,6 +665,57 @@ bool Check::visit(UiObjectBinding *ast) return false; } +static bool expressionAffectsVisualAspects(BinaryExpression *expression) +{ + if (expression->op == QSOperator::Assign + || expression->op == QSOperator::InplaceSub + || expression->op == QSOperator::InplaceAdd + || expression->op == QSOperator::InplaceDiv + || expression->op == QSOperator::InplaceMul + || expression->op == QSOperator::InplaceOr + || expression->op == QSOperator::InplaceXor + || expression->op == QSOperator::InplaceAnd) { + + const ExpressionNode *lhsValue = expression->left; + + if (const IdentifierExpression* identifierExpression = cast<const IdentifierExpression *>(lhsValue)) { + if (visualAspectsPropertyBlackList()->contains(identifierExpression->name.toString())) + return true; + } else if (const FieldMemberExpression* fieldMemberExpression = cast<const FieldMemberExpression *>(lhsValue)) { + if (visualAspectsPropertyBlackList()->contains(fieldMemberExpression->name.toString())) + return true; + } + } + return false; +} + +static UiQualifiedId *getRightMostIdentifier(UiQualifiedId *typeId) +{ + if (typeId->next) + return getRightMostIdentifier(typeId->next); + + return typeId; +} + +static bool checkTypeForDesignerSupport(UiQualifiedId *typeId) +{ + return unsupportedTypesByVisualDesigner()->contains(getRightMostIdentifier(typeId)->name.toString()); +} + +static bool checkTopLevelBindingForParentReference(ExpressionStatement *expStmt, const QString &source) +{ + if (!expStmt) + return false; + + SourceLocation location = locationFromRange(expStmt->firstSourceLocation(), expStmt->lastSourceLocation()); + QString stmtSource = source.mid(location.begin(), location.length); + + if (stmtSource.contains(QRegExp("(^|\\W)parent\\."))) + return true; + + return false; +} + void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId, UiObjectInitializer *initializer) { @@ -629,9 +727,16 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId, return; } + const SourceLocation typeErrorLocation = fullLocationForQualifiedId(typeId); + + if (checkTypeForDesignerSupport(typeId)) + addMessage(WarnUnsupportedTypeInVisualDesigner, typeErrorLocation); + + if (m_typeStack.count() > 1 && getRightMostIdentifier(typeId)->name.toString() == QLatin1String("State")) + addMessage(WarnStatesOnlyInRootItemForVisualDesigner, typeErrorLocation); + bool typeError = false; if (_importsOk) { - const SourceLocation typeErrorLocation = fullLocationForQualifiedId(typeId); const ObjectValue *prototype = _context->lookupType(_doc.data(), typeId); if (!prototype) { typeError = true; @@ -711,6 +816,13 @@ bool Check::visit(UiScriptBinding *ast) m_idStack.top().insert(id); } + if (m_typeStack.count() == 1 + && visualAspectsPropertyBlackList()->contains(ast->qualifiedId->name.toString()) + && checkTopLevelBindingForParentReference(cast<ExpressionStatement *>(ast->statement), _doc->source())) { + addMessage(WarnReferenceToParentItemNotSupportedByVisualDesigner, + locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation())); + } + checkProperty(ast->qualifiedId); if (!ast->statement) @@ -721,6 +833,12 @@ bool Check::visit(UiScriptBinding *ast) Evaluate evaluator(&_scopeChain); const Value *rhsValue = evaluator(ast->statement); + if (visualAspectsPropertyBlackList()->contains(ast->qualifiedId->name.toString()) && + rhsValue->asUndefinedValue()) { + addMessage(WarnUndefinedValueForVisualDesigner, + locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation())); + } + const SourceLocation loc = locationFromRange(ast->statement->firstSourceLocation(), ast->statement->lastSourceLocation()); AssignmentCheck assignmentCheck; @@ -910,6 +1028,11 @@ bool Check::visit(BinaryExpression *ast) addMessage(HintBinaryOperatorSpacing, op); } + SourceLocation expressionSourceLocation = locationFromRange(ast->firstSourceLocation(), + ast->lastSourceLocation()); + if (expressionAffectsVisualAspects(ast)) + addMessage(WarnImperativeCodeNotEditableInVisualDesigner, expressionSourceLocation); + // check ==, != if (ast->op == QSOperator::Equal || ast->op == QSOperator::NotEqual) { Evaluate eval(&_scopeChain); diff --git a/src/libs/qmljs/qmljscheck.h b/src/libs/qmljs/qmljscheck.h index e39493cf3c..9cdb0df1ad 100644 --- a/src/libs/qmljs/qmljscheck.h +++ b/src/libs/qmljs/qmljscheck.h @@ -132,6 +132,7 @@ private: QList<AST::Node *> _chain; QStack<StringSet> m_idStack; QStack<StringSet> m_propertyStack; + QStack<QString> m_typeStack; class MessageTypeAndSuppression { diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 1ab8d8d7a9..0c7126582f 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -1357,7 +1357,8 @@ template void CppQmlTypes::load< QHash<QString, FakeMetaObject::ConstPtr> >(cons QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QString &package, ComponentVersion version) { - QList<const CppComponentValue *> exportedObjects; + QHash<QString, const CppComponentValue *> exportedObjects; + QList<const CppComponentValue *> newObjects; // make new exported objects @@ -1397,8 +1398,11 @@ QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QStri // use package.cppname importversion as key _objectsByQualifiedName.insert(key, newComponent); - if (exported) - exportedObjects += newComponent; + if (exported) { + if (!exportedObjects.contains(name) // we might have the same type in different versions + || (newComponent->componentVersion() > exportedObjects.value(name)->componentVersion())) + exportedObjects.insert(name, newComponent); + } newObjects += newComponent; } } @@ -1436,7 +1440,7 @@ QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QStri } } - return exportedObjects; + return exportedObjects.values(); } bool CppQmlTypes::hasModule(const QString &module) const diff --git a/src/libs/qmljs/qmljssimplereader.cpp b/src/libs/qmljs/qmljssimplereader.cpp new file mode 100644 index 0000000000..250b7f8c0a --- /dev/null +++ b/src/libs/qmljs/qmljssimplereader.cpp @@ -0,0 +1,346 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmljssimplereader.h" + +#include "parser/qmljsparser_p.h" +#include "parser/qmljslexer_p.h" +#include "parser/qmljsengine_p.h" +#include "parser/qmljsast_p.h" +#include "parser/qmljsastvisitor_p.h" +#include <qmljs/qmljsdocument.h> + +#include "qmljsbind.h" +#include "qmljsinterpreter.h" +#include "qmljsutils.h" + +#include <QFile> + +enum { + debug = false +}; + + +using namespace QmlJS; + +QVariant SimpleReaderNode::property(const QString &name) const +{ + return m_properties.value(name); +} + +QStringList SimpleReaderNode::propertyNames() const +{ + return m_properties.keys(); +} + +SimpleReaderNode::PropertyHash SimpleReaderNode::properties() const +{ + return m_properties; +} + +bool SimpleReaderNode::isRoot() const +{ + return m_parentNode.isNull(); +} + +bool SimpleReaderNode::isValid() const +{ + return !m_name.isEmpty(); +} + +SimpleReaderNode::Ptr SimpleReaderNode::invalidNode() +{ + return Ptr(new SimpleReaderNode); +} + +SimpleReaderNode::WeakPtr SimpleReaderNode::parent() const +{ + return m_parentNode; +} + +QString SimpleReaderNode::name() const +{ + return m_name; +} + +SimpleReaderNode::SimpleReaderNode() +{ +} + +SimpleReaderNode::SimpleReaderNode(const QString &name, WeakPtr parent) + : m_name(name), m_parentNode(parent) +{ +} + +SimpleReaderNode::Ptr SimpleReaderNode::create(const QString &name, WeakPtr parent) +{ + Ptr newNode(new SimpleReaderNode(name, parent)); + newNode->m_weakThis = newNode; + if (parent) + parent.data()->m_children.append(newNode); + return newNode; +} + +const SimpleReaderNode::List SimpleReaderNode::children() const +{ + return m_children; +} + +void SimpleReaderNode::setProperty(const QString &name, const QVariant &value) +{ + m_properties.insert(name, value); +} + +SimpleAbstractStreamReader::SimpleAbstractStreamReader() +{ +} + +bool SimpleAbstractStreamReader::readFile(const QString &fileName) +{ + QFile file(fileName); + if (file.open(QIODevice::ReadOnly)) { + QByteArray source = file.readAll(); + file.close(); + return readFromSource(source); + } + addError(tr("Cannot find file %1").arg(fileName)); + return false; +} + +bool SimpleAbstractStreamReader::readFromSource(const QString &source) +{ + m_errors.clear(); + m_currentSourceLocation = AST::SourceLocation(); + + Engine engine; + Lexer lexer(&engine); + Parser parser(&engine); + + lexer.setCode(source, /*line = */ 1, /*qmlMode = */true); + + if (!parser.parse()) { + QString errorMessage = QString("%1:%2: %3").arg( + QString::number(parser.errorLineNumber()), + QString::number(parser.errorColumnNumber()), + parser.errorMessage()); + addError(errorMessage); + return false; + } + return readDocument(parser.ast()); +} + +QStringList SimpleAbstractStreamReader::errors() const +{ + return m_errors; +} + +void SimpleAbstractStreamReader::addError(const QString &error, const AST::SourceLocation &sourceLocation) +{ + m_errors << QString("%1:%2: %3\n").arg( + QString::number(sourceLocation.startLine), + QString::number(sourceLocation.startColumn), + error); +} + +AST::SourceLocation SimpleAbstractStreamReader::currentSourceLocation() const +{ + return m_currentSourceLocation; +} + +bool SimpleAbstractStreamReader::readDocument(AST::UiProgram *ast) +{ + if (!ast) { + addError(tr("Could not parse document")); + return false; + } + + AST::UiObjectDefinition *uiObjectDefinition = AST::cast<AST::UiObjectDefinition *>(ast->members->member); + if (!uiObjectDefinition) { + addError(tr("Expected document to contain a single object definition")); + return false; + } + readChild(uiObjectDefinition); + + return errors().isEmpty(); +} + +void SimpleAbstractStreamReader::readChildren(AST::UiObjectDefinition *uiObjectDefinition) +{ + Q_ASSERT(uiObjectDefinition); + + for (AST::UiObjectMemberList *it = uiObjectDefinition->initializer->members; it; it = it->next) { + AST::UiObjectMember *member = it->member; + AST::UiObjectDefinition *uiObjectDefinition = AST::cast<AST::UiObjectDefinition *>(member); + if (uiObjectDefinition) + readChild(uiObjectDefinition); + } +} + +void SimpleAbstractStreamReader::readChild(AST::UiObjectDefinition *uiObjectDefinition) +{ + Q_ASSERT(uiObjectDefinition); + + setSourceLocation(uiObjectDefinition->firstSourceLocation()); + + elementStart(toString(uiObjectDefinition->qualifiedTypeNameId)); + + readProperties(uiObjectDefinition); + readChildren(uiObjectDefinition); + + elementEnd(); +} + +void SimpleAbstractStreamReader::readProperties(AST::UiObjectDefinition *uiObjectDefinition) +{ + Q_ASSERT(uiObjectDefinition); + + for (AST::UiObjectMemberList *it = uiObjectDefinition->initializer->members; it; it = it->next) { + AST::UiObjectMember *member = it->member; + AST::UiScriptBinding *scriptBinding = AST::cast<AST::UiScriptBinding *>(member); + if (scriptBinding) + readProperty(scriptBinding); + } +} + +void SimpleAbstractStreamReader::readProperty(AST::UiScriptBinding *uiScriptBinding) +{ + Q_ASSERT(uiScriptBinding); + + setSourceLocation(uiScriptBinding->firstSourceLocation()); + + const QString name = toString(uiScriptBinding->qualifiedId); + const QVariant value = parsePropertyScriptBinding(uiScriptBinding); + + propertyDefinition(name, value); +} + +QVariant SimpleAbstractStreamReader::parsePropertyScriptBinding(AST::UiScriptBinding *uiScriptBinding) +{ + Q_ASSERT(uiScriptBinding); + + AST::ExpressionStatement *expStmt = AST::cast<AST::ExpressionStatement *>(uiScriptBinding->statement); + if (!expStmt) { + addError(tr("Expected expression statement after colon"), uiScriptBinding->statement->firstSourceLocation()); + return QVariant(); + } + + return parsePropertyExpression(expStmt->expression); +} + +QVariant SimpleAbstractStreamReader::parsePropertyExpression(AST::ExpressionNode *expressionNode) +{ + Q_ASSERT(expressionNode); + + AST::ArrayLiteral *arrayLiteral = AST::cast<AST::ArrayLiteral *>(expressionNode); + + if (arrayLiteral) { + QList<QVariant> variantList; + for (AST::ElementList *it = arrayLiteral->elements; it; it = it->next) + variantList << parsePropertyExpression(it->expression); + return variantList; + } + + AST::StringLiteral *stringLiteral = AST::cast<AST::StringLiteral *>(expressionNode); + if (stringLiteral) + return stringLiteral->value.toString(); + + AST::TrueLiteral *trueLiteral = AST::cast<AST::TrueLiteral *>(expressionNode); + if (trueLiteral) + return true; + + AST::FalseLiteral *falseLiteral = AST::cast<AST::FalseLiteral *>(expressionNode); + if (falseLiteral) + return false; + + AST::NumericLiteral *numericLiteral = AST::cast<AST::NumericLiteral *>(expressionNode); + if (numericLiteral) + return numericLiteral->value; + + addError(tr("Expected expression statement to be a literal"), expressionNode->firstSourceLocation()); + return QVariant(); +} + +void SimpleAbstractStreamReader::setSourceLocation(const AST::SourceLocation &sourceLocation) +{ + m_currentSourceLocation = sourceLocation; +} + +SimpleReader::SimpleReader() +{ +} + +SimpleReaderNode::Ptr SimpleReader::readFile(const QString &fileName) +{ + SimpleAbstractStreamReader::readFile(fileName); + return m_rootNode; +} + +SimpleReaderNode::Ptr SimpleReader::readFromSource(const QString &source) +{ + SimpleAbstractStreamReader::readFromSource(source); + return m_rootNode; +} + +void SimpleReader::elementStart(const QString &name) +{ + if (debug) + qDebug() << "SimpleReader::elementStart()" << name; + + SimpleReaderNode::Ptr newNode = SimpleReaderNode::create(name, m_currentNode); + + if (newNode->isRoot()) + m_rootNode = newNode; + + Q_ASSERT(newNode->isValid()); + + m_currentNode = newNode; +} + +void SimpleReader::elementEnd() +{ + Q_ASSERT(m_currentNode); + + if (debug) + qDebug() << "SimpleReader::elementEnd()" << m_currentNode.data()->name(); + + m_currentNode = m_currentNode.data()->parent(); +} + +void SimpleReader::propertyDefinition(const QString &name, const QVariant &value) +{ + Q_ASSERT(m_currentNode); + + if (debug) + qDebug() << "SimpleReader::propertyDefinition()" << m_currentNode.data()->name() << name << value; + + if (m_currentNode.data()->propertyNames().contains(name)) + addError(tr("Property is defined twice"), currentSourceLocation()); + + m_currentNode.data()->setProperty(name, value); +} diff --git a/src/libs/qmljs/qmljssimplereader.h b/src/libs/qmljs/qmljssimplereader.h new file mode 100644 index 0000000000..351b590326 --- /dev/null +++ b/src/libs/qmljs/qmljssimplereader.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QMLJS_SIMPLEREADER_H +#define QMLJS_SIMPLEREADER_H + +#include <qmljs/qmljs_global.h> +#include <qmljs/parser/qmljsastfwd_p.h> + +#include <QHash> +#include <QList> +#include <QStringList> +#include <QSharedPointer> +#include <QWeakPointer> + +// for Q_DECLARE_TR_FUNCTIONS +#include <QCoreApplication> + +namespace QmlJS { + +class QMLJS_EXPORT SimpleReaderNode +{ +public: + typedef QSharedPointer<SimpleReaderNode> Ptr; + typedef QWeakPointer<SimpleReaderNode> WeakPtr; + typedef QHash<QString, QVariant> PropertyHash; + typedef QList<Ptr> List; + + QVariant property(const QString &name) const; + QStringList propertyNames() const; + PropertyHash properties() const; + bool isRoot() const; + bool isValid() const; + static Ptr invalidNode(); + WeakPtr parent() const; + QString name() const; + const List children() const; + +protected: + SimpleReaderNode(); + SimpleReaderNode(const QString &name, WeakPtr parent); + static Ptr create(const QString &name, WeakPtr parent); + void setProperty(const QString &name, const QVariant &value); + +private: + const QString m_name; + PropertyHash m_properties; + const WeakPtr m_parentNode; + List m_children; + WeakPtr m_weakThis; + + friend class SimpleReader; +}; + +class QMLJS_EXPORT SimpleAbstractStreamReader +{ + Q_DECLARE_TR_FUNCTIONS(QmlJS::SimpleAbstractStreamReader) + +public: + SimpleAbstractStreamReader(); + bool readFile(const QString &fileName); + bool readFromSource(const QString &source); + QStringList errors() const; + +protected: + void addError(const QString &error, const AST::SourceLocation &sourceLocation = AST::SourceLocation()); + AST::SourceLocation currentSourceLocation() const; + + virtual void elementStart(const QString &name) = 0; + virtual void elementEnd() = 0; + virtual void propertyDefinition(const QString &name, const QVariant &value) = 0; + +private: + bool readDocument(AST::UiProgram *ast); + void readChildren(AST::UiObjectDefinition *ast); + void readChild(AST::UiObjectDefinition *uiObjectDefinition); + void readProperties(AST::UiObjectDefinition *ast); + void readProperty(AST::UiScriptBinding *uiScriptBinding); + QVariant parsePropertyScriptBinding(AST::UiScriptBinding *ExpressionNode); + QVariant parsePropertyExpression(AST::ExpressionNode *expressionNode); + void setSourceLocation(const AST::SourceLocation &sourceLocation); + + QStringList m_errors; + AST::SourceLocation m_currentSourceLocation; +}; + +class QMLJS_EXPORT SimpleReader: public SimpleAbstractStreamReader +{ + Q_DECLARE_TR_FUNCTIONS(QmlJS::SimpleReader) + +public: + SimpleReader(); + SimpleReaderNode::Ptr readFile(const QString &fileName); + SimpleReaderNode::Ptr readFromSource(const QString &source); + +protected: + virtual void elementStart(const QString &name); + virtual void elementEnd(); + virtual void propertyDefinition(const QString &name, const QVariant &value); + +private: + SimpleReaderNode::Ptr m_rootNode; + SimpleReaderNode::WeakPtr m_currentNode; +}; + +} // namespace QmlJS + +#endif // QMLJS_SIMPLEREADER_H diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp index bd0a79e79d..8da87b317e 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp +++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp @@ -214,6 +214,17 @@ StaticAnalysisMessages::StaticAnalysisMessages() tr("maximum string value length is %1"), 1); newMsg(ErrInvalidArrayValueLength, Error, tr("%1 elements expected in array value"), 1); + newMsg(WarnImperativeCodeNotEditableInVisualDesigner, Warning, + tr("Imperative code is not supported in the Qt Quick Designer")); + newMsg(WarnUnsupportedTypeInVisualDesigner, Warning, + tr("This type is not supported in the Qt Quick Designer")); + newMsg(WarnReferenceToParentItemNotSupportedByVisualDesigner, Warning, + tr("Reference to parent item cannot be resolved correctly by the Qt Quick Designer")); + newMsg(WarnUndefinedValueForVisualDesigner, Warning, + tr("This visual property binding cannot be evaluted in the local context " + "and might not show up in Qt Quick Designer as expected")); + newMsg(WarnStatesOnlyInRootItemForVisualDesigner, Warning, + tr("Qt Quick Designer only supports states in the root item ")); } } // anonymous namespace diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.h b/src/libs/qmljs/qmljsstaticanalysismessage.h index b1f5999775..6b40ebfb01 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.h +++ b/src/libs/qmljs/qmljsstaticanalysismessage.h @@ -100,6 +100,11 @@ enum Type WarnConfusingExpressionStatement = 127, HintDeclarationsShouldBeAtStartOfFunction = 201, HintOneStatementPerLine = 202, + WarnImperativeCodeNotEditableInVisualDesigner = 203, + WarnUnsupportedTypeInVisualDesigner = 204, + WarnReferenceToParentItemNotSupportedByVisualDesigner = 205, + WarnUndefinedValueForVisualDesigner = 206, + WarnStatesOnlyInRootItemForVisualDesigner = 207, ErrUnknownComponent = 300, ErrCouldNotResolvePrototypeOf = 301, ErrCouldNotResolvePrototype = 302, diff --git a/src/libs/qtcomponents/styleitem/styleitem.qbs b/src/libs/qtcomponents/styleitem/styleitem.qbs index b5444dcd3a..a233b0771a 100644 --- a/src/libs/qtcomponents/styleitem/styleitem.qbs +++ b/src/libs/qtcomponents/styleitem/styleitem.qbs @@ -1,4 +1,5 @@ import qbs.base 1.0 +import "../../../../qbs/defaults.js" as Defaults DynamicLibrary { name: "styleplugin" @@ -7,7 +8,7 @@ DynamicLibrary { Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["core", "widgets", "declarative", "script"] } - cpp.defines: project.additionalCppDefines + cpp.defines: Defaults.defines(qbs) files: [ "qdeclarativefolderlistmodel.cpp", @@ -26,7 +27,7 @@ DynamicLibrary { "qtmenuitem.cpp", "qtmenuitem.h", "qwheelarea.cpp", - "qwheelarea.h" + "qwheelarea.h", ] } diff --git a/src/libs/ssh/sftpchannel_p.h b/src/libs/ssh/sftpchannel_p.h index f3a46189f1..482f82753a 100644 --- a/src/libs/ssh/sftpchannel_p.h +++ b/src/libs/ssh/sftpchannel_p.h @@ -48,14 +48,8 @@ class SftpChannelPrivate : public AbstractSshChannel Q_OBJECT friend class QSsh::SftpChannel; public: - enum SftpState { Inactive, SubsystemRequested, InitSent, Initialized }; - virtual void handleChannelSuccess(); - virtual void handleChannelFailure(); - - virtual void closeHook(); - signals: void initialized(); void initializationFailed(const QString &reason); @@ -71,6 +65,9 @@ private: SftpChannel *sftp); SftpJobId createJob(const AbstractSftpOperation::Ptr &job); + virtual void handleChannelSuccess(); + virtual void handleChannelFailure(); + virtual void handleOpenSuccessInternal(); virtual void handleOpenFailureInternal(const QString &reason); virtual void handleChannelDataInternal(const QByteArray &data); @@ -79,6 +76,8 @@ private: virtual void handleExitStatus(const SshChannelExitStatus &exitStatus); virtual void handleExitSignal(const SshChannelExitSignal &signal); + virtual void closeHook(); + void handleCurrentPacket(); void handleServerVersion(); void handleHandle(); diff --git a/src/libs/ssh/ssh.pro b/src/libs/ssh/ssh.pro index d0b90af988..477cf4b91f 100644 --- a/src/libs/ssh/ssh.pro +++ b/src/libs/ssh/ssh.pro @@ -29,7 +29,8 @@ SOURCES = $$PWD/sshsendfacility.cpp \ $$PWD/sshconnectionmanager.cpp \ $$PWD/sshkeypasswordretriever.cpp \ $$PWD/sftpfilesystemmodel.cpp \ - $$PWD/sshkeycreationdialog.cpp + $$PWD/sshkeycreationdialog.cpp \ + $$PWD/sshdirecttcpiptunnel.cpp HEADERS = $$PWD/sshsendfacility_p.h \ $$PWD/sshremoteprocess.h \ @@ -62,7 +63,9 @@ HEADERS = $$PWD/sshsendfacility_p.h \ $$PWD/sshkeypasswordretriever_p.h \ $$PWD/sftpfilesystemmodel.h \ $$PWD/sshkeycreationdialog.h \ - $$PWD/ssh_global.h + $$PWD/ssh_global.h \ + $$PWD/sshdirecttcpiptunnel_p.h \ + $$PWD/sshdirecttcpiptunnel.h FORMS = $$PWD/sshkeycreationdialog.ui diff --git a/src/libs/ssh/ssh.qbs b/src/libs/ssh/ssh.qbs index 052e80fabc..e6b1b9ba6d 100644 --- a/src/libs/ssh/ssh.qbs +++ b/src/libs/ssh/ssh.qbs @@ -5,13 +5,8 @@ QtcLibrary { name: "QtcSsh" cpp.defines: base.concat(["QSSH_LIBRARY"]).concat(botanDefines) + cpp.includePaths: botanIncludes cpp.dynamicLibraries: botanLibs - cpp.includePaths: [ - ".", - "..", - "../..", - buildDirectory - ].concat(botanIncludes) Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["widgets", "network" ] } @@ -19,33 +14,34 @@ QtcLibrary { files: [ "sftpchannel.h", "sftpchannel_p.h", "sftpchannel.cpp", "sftpdefs.cpp", "sftpdefs.h", + "sftpfilesystemmodel.cpp", "sftpfilesystemmodel.h", "sftpincomingpacket.cpp", "sftpincomingpacket_p.h", "sftpoperation.cpp", "sftpoperation_p.h", "sftpoutgoingpacket.cpp", "sftpoutgoingpacket_p.h", "sftppacket.cpp", "sftppacket_p.h", + "sshbotanconversions_p.h", "sshcapabilities_p.h", "sshcapabilities.cpp", "sshchannel.cpp", "sshchannel_p.h", "sshchannelmanager.cpp", "sshchannelmanager_p.h", "sshconnection.h", "sshconnection_p.h", "sshconnection.cpp", "sshconnectionmanager.cpp", "sshconnectionmanager.h", "sshcryptofacility.cpp", "sshcryptofacility_p.h", + "sshdirecttcpiptunnel.h", "sshdirecttcpiptunnel_p.h", "sshdirecttcpiptunnel.cpp", + "ssherrors.h", + "sshexception_p.h", + "sshincomingpacket_p.h", "sshincomingpacket.cpp", + "sshkeycreationdialog.cpp", "sshkeycreationdialog.h", "sshkeycreationdialog.ui", "sshkeyexchange.cpp", "sshkeyexchange_p.h", + "sshkeygenerator.cpp", "sshkeygenerator.h", + "sshkeypasswordretriever.cpp", "sshkeypasswordretriever_p.h", "sshoutgoingpacket.cpp", "sshoutgoingpacket_p.h", "sshpacket.cpp", "sshpacket_p.h", "sshpacketparser.cpp", "sshpacketparser_p.h", + "sshpseudoterminal.h", "sshremoteprocess.cpp", "sshremoteprocess.h", "sshremoteprocess_p.h", "sshremoteprocessrunner.cpp", "sshremoteprocessrunner.h", "sshsendfacility.cpp", "sshsendfacility_p.h", - "sshkeypasswordretriever.cpp", - "sshkeygenerator.cpp", "sshkeygenerator.h", - "sshkeycreationdialog.cpp", "sshkeycreationdialog.h", "sshkeycreationdialog.ui", - "sftpfilesystemmodel.cpp", "sftpfilesystemmodel.h", - "sshincomingpacket_p.h", "sshincomingpacket.cpp", - "ssherrors.h", - "sshexception_p.h", - "sshpseudoterminal.h", - "sshbotanconversions_p.h" ].concat(botanFiles) property var botanIncludes: ["../3rdparty"] @@ -90,8 +86,6 @@ QtcLibrary { } ProductModule { - Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["widgets", "network"] } - cpp.includePaths: [".."] } } diff --git a/src/libs/ssh/sshchannel.cpp b/src/libs/ssh/sshchannel.cpp index 915d7cb698..dada1ad12c 100644 --- a/src/libs/ssh/sshchannel.cpp +++ b/src/libs/ssh/sshchannel.cpp @@ -39,18 +39,14 @@ namespace QSsh { namespace Internal { -namespace { - const quint32 MinMaxPacketSize = 32768; - const quint32 MaxPacketSize = 16 * 1024 * 1024; - const quint32 InitialWindowSize = MaxPacketSize; - const quint32 NoChannel = 0xffffffffu; -} // anonymous namespace +const quint32 MinMaxPacketSize = 32768; +const quint32 NoChannel = 0xffffffffu; AbstractSshChannel::AbstractSshChannel(quint32 channelId, SshSendFacility &sendFacility) : m_sendFacility(sendFacility), m_timeoutTimer(new QTimer(this)), m_localChannel(channelId), m_remoteChannel(NoChannel), - m_localWindowSize(InitialWindowSize), m_remoteWindowSize(0), + m_localWindowSize(initialWindowSize()), m_remoteWindowSize(0), m_state(Inactive) { m_timeoutTimer->setSingleShot(true); @@ -76,8 +72,7 @@ void AbstractSshChannel::requestSessionStart() // with our cryptography stuff, it would have hit us before, on // establishing the connection. try { - m_sendFacility.sendSessionPacket(m_localChannel, InitialWindowSize, - MaxPacketSize); + m_sendFacility.sendSessionPacket(m_localChannel, initialWindowSize(), maxPacketSize()); setChannelState(SessionRequested); m_timeoutTimer->start(ReplyTimeout); } catch (Botan::Exception &e) { @@ -97,6 +92,16 @@ void AbstractSshChannel::sendData(const QByteArray &data) } } +quint32 AbstractSshChannel::initialWindowSize() +{ + return maxPacketSize(); +} + +quint32 AbstractSshChannel::maxPacketSize() +{ + return 16 * 1024 * 1024; +} + void AbstractSshChannel::handleWindowAdjust(quint32 bytesToAdd) { checkChannelActive(); @@ -173,6 +178,7 @@ void AbstractSshChannel::handleChannelEof() "Unexpected SSH_MSG_CHANNEL_EOF message."); } m_localWindowSize = 0; + emit eof(); } void AbstractSshChannel::handleChannelClose() @@ -223,10 +229,9 @@ int AbstractSshChannel::handleChannelOrExtendedChannelData(const QByteArray &dat qWarning("Misbehaving server does not respect local window, clipping."); m_localWindowSize -= bytesToDeliver; - if (m_localWindowSize < MaxPacketSize) { - m_localWindowSize += MaxPacketSize; - m_sendFacility.sendWindowAdjustPacket(m_remoteChannel, - MaxPacketSize); + if (m_localWindowSize < maxPacketSize()) { + m_localWindowSize += maxPacketSize(); + m_sendFacility.sendWindowAdjustPacket(m_remoteChannel, maxPacketSize()); } return bytesToDeliver; } @@ -255,7 +260,7 @@ void AbstractSshChannel::checkChannelActive() quint32 AbstractSshChannel::maxDataSize() const { - return qMin(m_localWindowSize, MaxPacketSize); + return qMin(m_localWindowSize, maxPacketSize()); } } // namespace Internal diff --git a/src/libs/ssh/sshchannel_p.h b/src/libs/ssh/sshchannel_p.h index 087c8202f2..ed5f078b63 100644 --- a/src/libs/ssh/sshchannel_p.h +++ b/src/libs/ssh/sshchannel_p.h @@ -52,17 +52,12 @@ public: Inactive, SessionRequested, SessionEstablished, CloseRequested, Closed }; - ChannelState channelState() const { return m_state; } - void setChannelState(ChannelState state); - quint32 localChannelId() const { return m_localChannel; } quint32 remoteChannel() const { return m_remoteChannel; } virtual void handleChannelSuccess() = 0; virtual void handleChannelFailure() = 0; - virtual void closeHook() = 0; - void handleOpenSuccess(quint32 remoteChannelId, quint32 remoteWindowSize, quint32 remoteMaxPacketSize); void handleOpenFailure(const QString &reason); @@ -73,20 +68,28 @@ public: void handleChannelExtendedData(quint32 type, const QByteArray &data); void handleChannelRequest(const SshIncomingPacket &packet); - void requestSessionStart(); - void sendData(const QByteArray &data); void closeChannel(); virtual ~AbstractSshChannel(); static const int ReplyTimeout = 10000; // milli seconds + ChannelState channelState() const { return m_state; } signals: void timeout(); + void eof(); protected: AbstractSshChannel(quint32 channelId, SshSendFacility &sendFacility); + void setChannelState(ChannelState state); + + void requestSessionStart(); + void sendData(const QByteArray &data); + + static quint32 initialWindowSize(); + static quint32 maxPacketSize(); + quint32 maxDataSize() const; void checkChannelActive(); @@ -102,7 +105,8 @@ private: virtual void handleExitStatus(const SshChannelExitStatus &exitStatus) = 0; virtual void handleExitSignal(const SshChannelExitSignal &signal) = 0; - void setState(ChannelState newState); + virtual void closeHook() = 0; + void flushSendBuffer(); int handleChannelOrExtendedChannelData(const QByteArray &data); diff --git a/src/libs/ssh/sshchannelmanager.cpp b/src/libs/ssh/sshchannelmanager.cpp index 49c231fe00..b430a0d9ce 100644 --- a/src/libs/ssh/sshchannelmanager.cpp +++ b/src/libs/ssh/sshchannelmanager.cpp @@ -31,6 +31,8 @@ #include "sftpchannel.h" #include "sftpchannel_p.h" +#include "sshdirecttcpiptunnel.h" +#include "sshdirecttcpiptunnel_p.h" #include "sshincomingpacket_p.h" #include "sshremoteprocess.h" #include "sshremoteprocess_p.h" @@ -167,6 +169,15 @@ QSsh::SftpChannel::Ptr SshChannelManager::createSftpChannel() return sftp; } +SshDirectTcpIpTunnel::Ptr SshChannelManager::createTunnel(quint16 remotePort, + const SshConnectionInfo &connectionInfo) +{ + SshDirectTcpIpTunnel::Ptr tunnel(new SshDirectTcpIpTunnel(m_nextLocalChannelId++, remotePort, + connectionInfo, m_sendFacility)); + insertChannel(tunnel->d, tunnel); + return tunnel; +} + void SshChannelManager::insertChannel(AbstractSshChannel *priv, const QSharedPointer<QObject> &pub) { diff --git a/src/libs/ssh/sshchannelmanager_p.h b/src/libs/ssh/sshchannelmanager_p.h index 50b11cbd36..f6e6010e4a 100644 --- a/src/libs/ssh/sshchannelmanager_p.h +++ b/src/libs/ssh/sshchannelmanager_p.h @@ -35,8 +35,9 @@ #include <QSharedPointer> namespace QSsh { - class SftpChannel; +class SshConnectionInfo; +class SshDirectTcpIpTunnel; class SshRemoteProcess; namespace Internal { @@ -54,8 +55,10 @@ public: QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command); QSharedPointer<SshRemoteProcess> createRemoteShell(); QSharedPointer<SftpChannel> createSftpChannel(); - int channelCount() const; + QSharedPointer<SshDirectTcpIpTunnel> createTunnel(quint16 remotePort, + const SshConnectionInfo &connectionInfo); + int channelCount() const; enum CloseAllMode { CloseAllRegular, CloseAllAndReset }; int closeAllChannels(CloseAllMode mode); diff --git a/src/libs/ssh/sshconnection.cpp b/src/libs/ssh/sshconnection.cpp index 86489e3d67..5b7db878d6 100644 --- a/src/libs/ssh/sshconnection.cpp +++ b/src/libs/ssh/sshconnection.cpp @@ -34,8 +34,10 @@ #include "sshcapabilities_p.h" #include "sshchannelmanager_p.h" #include "sshcryptofacility_p.h" +#include "sshdirecttcpiptunnel.h" #include "sshexception_p.h" #include "sshkeyexchange_p.h" +#include "sshremoteprocess.h" #include <botan/botan.h> @@ -79,8 +81,10 @@ namespace { SshConnectionParameters::SshConnectionParameters() : - timeout(0), authenticationType(AuthenticationByKey), port(0), proxyType(NoProxy) + timeout(0), authenticationType(AuthenticationByKey), port(0) { + options |= SshIgnoreDefaultProxy; + options |= SshEnableStrictConformanceChecks; } static inline bool equals(const SshConnectionParameters &p1, const SshConnectionParameters &p2) @@ -191,6 +195,12 @@ QSharedPointer<SftpChannel> SshConnection::createSftpChannel() return d->createSftpChannel(); } +SshDirectTcpIpTunnel::Ptr SshConnection::createTunnel(quint16 remotePort) +{ + QSSH_ASSERT_AND_RETURN_VALUE(state() == Connected, SshDirectTcpIpTunnel::Ptr()); + return d->createTunnel(remotePort); +} + int SshConnection::closeAllChannels() { try { @@ -217,8 +227,8 @@ SshConnectionPrivate::SshConnectionPrivate(SshConnection *conn, m_conn(conn) { setupPacketHandlers(); - m_socket->setProxy(m_connParams.proxyType == SshConnectionParameters::DefaultProxy - ? QNetworkProxy::DefaultProxy : QNetworkProxy::NoProxy); + m_socket->setProxy((m_connParams.options & SshIgnoreDefaultProxy) + ? QNetworkProxy::NoProxy : QNetworkProxy::DefaultProxy); m_timeoutTimer.setSingleShot(true); m_timeoutTimer.setInterval(m_connParams.timeout * 1000); m_keepAliveTimer.setSingleShot(true); @@ -331,7 +341,7 @@ void SshConnectionPrivate::handleIncomingData() e.errorString); } catch (Botan::Exception &e) { closeConnection(SSH_DISCONNECT_BY_APPLICATION, SshInternalError, "", - tr("Botan library exception: %1").arg(QString::fromAscii(e.what()))); + tr("Botan library exception: %1").arg(QString::fromLatin1(e.what()))); } } @@ -390,21 +400,19 @@ void SshConnectionPrivate::handleServerId() .arg(serverProtoVersion)); } - // TODO: Remove #if on 2.7 -#if 0 - // Disable this check to accept older OpenSSH servers that do this wrong. - if (serverProtoVersion == QLatin1String("2.0") && !hasCarriageReturn) { - throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR, - "Identification string is invalid.", - tr("Server identification string is invalid (missing carriage return).")); - } -#endif + if (m_connParams.options & SshEnableStrictConformanceChecks) { + if (serverProtoVersion == QLatin1String("2.0") && !hasCarriageReturn) { + throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR, + "Identification string is invalid.", + tr("Server identification string is invalid (missing carriage return).")); + } - if (serverProtoVersion == QLatin1String("1.99") && m_serverHasSentDataBeforeId) { - throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR, - "No extra data preceding identification string allowed for 1.99.", - tr("Server reports protocol version 1.99, but sends data " - "before the identification string, which is not allowed.")); + if (serverProtoVersion == QLatin1String("1.99") && m_serverHasSentDataBeforeId) { + throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR, + "No extra data preceding identification string allowed for 1.99.", + tr("Server reports protocol version 1.99, but sends data " + "before the identification string, which is not allowed.")); + } } m_keyExchange.reset(new SshKeyExchange(m_sendFacility)); @@ -774,6 +782,11 @@ QSharedPointer<SftpChannel> SshConnectionPrivate::createSftpChannel() return m_channelManager->createSftpChannel(); } +SshDirectTcpIpTunnel::Ptr SshConnectionPrivate::createTunnel(quint16 remotePort) +{ + return m_channelManager->createTunnel(remotePort, m_conn->connectionInfo()); +} + const quint64 SshConnectionPrivate::InvalidSeqNr = static_cast<quint64>(-1); } // namespace Internal diff --git a/src/libs/ssh/sshconnection.h b/src/libs/ssh/sshconnection.h index 1ebfe7e803..a007db478d 100644 --- a/src/libs/ssh/sshconnection.h +++ b/src/libs/ssh/sshconnection.h @@ -35,6 +35,7 @@ #include "ssh_global.h" #include <QByteArray> +#include <QFlags> #include <QObject> #include <QSharedPointer> #include <QString> @@ -42,16 +43,23 @@ namespace QSsh { class SftpChannel; +class SshDirectTcpIpTunnel; class SshRemoteProcess; namespace Internal { class SshConnectionPrivate; } // namespace Internal +enum SshConnectionOption { + SshIgnoreDefaultProxy = 0x1, + SshEnableStrictConformanceChecks = 0x2 +}; + +Q_DECLARE_FLAGS(SshConnectionOptions, SshConnectionOption) + class QSSH_EXPORT SshConnectionParameters { public: - enum ProxyType { DefaultProxy, NoProxy }; enum AuthenticationType { AuthenticationByPassword, AuthenticationByKey }; SshConnectionParameters(); @@ -62,7 +70,7 @@ public: int timeout; // In seconds. AuthenticationType authenticationType; quint16 port; - ProxyType proxyType; + SshConnectionOptions options; }; QSSH_EXPORT bool operator==(const SshConnectionParameters &p1, const SshConnectionParameters &p2); @@ -102,6 +110,7 @@ public: QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command); QSharedPointer<SshRemoteProcess> createRemoteShell(); QSharedPointer<SftpChannel> createSftpChannel(); + QSharedPointer<SshDirectTcpIpTunnel> createTunnel(quint16 remotePort); // -1 if an error occurred, number of channels closed otherwise. int closeAllChannels(); diff --git a/src/libs/ssh/sshconnection_p.h b/src/libs/ssh/sshconnection_p.h index 0a5be8814f..55b6de5654 100644 --- a/src/libs/ssh/sshconnection_p.h +++ b/src/libs/ssh/sshconnection_p.h @@ -33,7 +33,6 @@ #include "sshconnection.h" #include "sshexception_p.h" #include "sshincomingpacket_p.h" -#include "sshremoteprocess.h" #include "sshsendfacility_p.h" #include <QHash> @@ -49,6 +48,8 @@ QT_END_NAMESPACE namespace QSsh { class SftpChannel; +class SshRemoteProcess; +class SshDirectTcpIpTunnel; namespace Internal { class SshChannelManager; @@ -87,6 +88,8 @@ public: QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command); QSharedPointer<SshRemoteProcess> createRemoteShell(); QSharedPointer<SftpChannel> createSftpChannel(); + QSharedPointer<SshDirectTcpIpTunnel> createTunnel(quint16 remotePort); + SshStateInternal state() const { return m_state; } SshError error() const { return m_error; } QString errorString() const { return m_errorString; } diff --git a/src/libs/ssh/sshdirecttcpiptunnel.cpp b/src/libs/ssh/sshdirecttcpiptunnel.cpp new file mode 100644 index 0000000000..ef0cada653 --- /dev/null +++ b/src/libs/ssh/sshdirecttcpiptunnel.cpp @@ -0,0 +1,194 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ +#include "sshdirecttcpiptunnel.h" +#include "sshdirecttcpiptunnel_p.h" + +#include "sshincomingpacket_p.h" +#include "sshsendfacility_p.h" + +#include <QTimer> + +namespace QSsh { +namespace Internal { + +SshDirectTcpIpTunnelPrivate::SshDirectTcpIpTunnelPrivate(quint32 channelId, quint16 remotePort, + const SshConnectionInfo &connectionInfo, SshSendFacility &sendFacility) + : AbstractSshChannel(channelId, sendFacility), + m_remotePort(remotePort), + m_connectionInfo(connectionInfo) +{ + connect(this, SIGNAL(eof()), SLOT(handleEof())); +} + +void SshDirectTcpIpTunnelPrivate::handleChannelSuccess() +{ + throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, + "Unexpected SSH_MSG_CHANNEL_SUCCESS message."); +} + +void SshDirectTcpIpTunnelPrivate::handleChannelFailure() +{ + throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, + "Unexpected SSH_MSG_CHANNEL_FAILURE message."); +} + +void SshDirectTcpIpTunnelPrivate::handleOpenSuccessInternal() +{ + emit initialized(); +} + +void SshDirectTcpIpTunnelPrivate::handleOpenFailureInternal(const QString &reason) +{ + emit error(reason); + closeChannel(); +} + +void SshDirectTcpIpTunnelPrivate::handleChannelDataInternal(const QByteArray &data) +{ + m_data += data; + emit readyRead(); +} + +void SshDirectTcpIpTunnelPrivate::handleChannelExtendedDataInternal(quint32 type, + const QByteArray &data) +{ + qDebug("%s: Unexpected extended channel data. Type is %u, content is '%s'.", Q_FUNC_INFO, type, + data.constData()); +} + +void SshDirectTcpIpTunnelPrivate::handleExitStatus(const SshChannelExitStatus &exitStatus) +{ + qDebug("%s: Unexpected exit status %d.", Q_FUNC_INFO, exitStatus.exitStatus); +} + +void SshDirectTcpIpTunnelPrivate::handleExitSignal(const SshChannelExitSignal &signal) +{ + qDebug("%s: Unexpected exit signal %s.", Q_FUNC_INFO, signal.signal.constData()); +} + +void SshDirectTcpIpTunnelPrivate::closeHook() +{ + emit closed(); +} + +void SshDirectTcpIpTunnelPrivate::handleEof() +{ + /* + * For some reason, the OpenSSH server only sends EOF when the remote port goes away, + * but does not close the channel, even though it becomes useless in that case. + * So we close it ourselves. + */ + closeChannel(); +} + +} // namespace Internal + +using namespace Internal; + +SshDirectTcpIpTunnel::SshDirectTcpIpTunnel(quint32 channelId, quint16 remotePort, + const SshConnectionInfo &connectionInfo, SshSendFacility &sendFacility) + : d(new SshDirectTcpIpTunnelPrivate(channelId, remotePort, connectionInfo, sendFacility)) +{ + connect(d, SIGNAL(initialized()), SIGNAL(initialized()), Qt::QueuedConnection); + connect(d, SIGNAL(readyRead()), SIGNAL(readyRead()), Qt::QueuedConnection); + connect(d, SIGNAL(closed()), SIGNAL(tunnelClosed()), Qt::QueuedConnection); + connect(d, SIGNAL(error(QString)), SLOT(handleError(QString)), Qt::QueuedConnection); +} + +SshDirectTcpIpTunnel::~SshDirectTcpIpTunnel() +{ + d->closeChannel(); + delete d; +} + +bool SshDirectTcpIpTunnel::atEnd() const +{ + return QIODevice::atEnd() && d->m_data.isEmpty(); +} + +qint64 SshDirectTcpIpTunnel::bytesAvailable() const +{ + return QIODevice::bytesAvailable() + d->m_data.count(); +} + +bool SshDirectTcpIpTunnel::canReadLine() const +{ + return QIODevice::canReadLine() || d->m_data.contains('\n'); +} + +void SshDirectTcpIpTunnel::close() +{ + d->closeChannel(); + QIODevice::close(); +} + +void SshDirectTcpIpTunnel::initialize() +{ + QSSH_ASSERT_AND_RETURN(d->channelState() == AbstractSshChannel::Inactive); + + try { + QIODevice::open(QIODevice::ReadWrite); + d->m_sendFacility.sendDirectTcpIpPacket(d->localChannelId(), d->initialWindowSize(), + d->maxPacketSize(), d->m_connectionInfo.peerAddress.toString().toUtf8(), + d->m_remotePort, d->m_connectionInfo.localAddress.toString().toUtf8(), + d->m_connectionInfo.localPort); + d->setChannelState(AbstractSshChannel::SessionRequested); + d->m_timeoutTimer->start(d->ReplyTimeout); + } catch (Botan::Exception &e) { // Won't happen, but let's play it safe. + qDebug("Botan error: %s", e.what()); + d->closeChannel(); + } +} + +qint64 SshDirectTcpIpTunnel::readData(char *data, qint64 maxlen) +{ + const qint64 bytesRead = qMin(qint64(d->m_data.count()), maxlen); + memcpy(data, d->m_data.constData(), bytesRead); + d->m_data.remove(0, bytesRead); + return bytesRead; +} + +qint64 SshDirectTcpIpTunnel::writeData(const char *data, qint64 len) +{ + QSSH_ASSERT_AND_RETURN_VALUE(d->channelState() == AbstractSshChannel::SessionEstablished, 0); + + d->sendData(QByteArray(data, len)); + return len; +} + +void SshDirectTcpIpTunnel::handleError(const QString &reason) +{ + setErrorString(reason); + emit error(reason); +} + +} // namespace QSsh diff --git a/src/libs/ssh/sshdirecttcpiptunnel.h b/src/libs/ssh/sshdirecttcpiptunnel.h new file mode 100644 index 0000000000..b451c96afc --- /dev/null +++ b/src/libs/ssh/sshdirecttcpiptunnel.h @@ -0,0 +1,90 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#ifndef SSHDIRECTTCPIPTUNNEL_H +#define SSHDIRECTTCPIPTUNNEL_H + +#include "ssh_global.h" + +#include <QIODevice> +#include <QSharedPointer> + +namespace QSsh { +class SshConnectionInfo; + +namespace Internal { +class SshChannelManager; +class SshDirectTcpIpTunnelPrivate; +class SshSendFacility; +} // namespace Internal + +class QSSH_EXPORT SshDirectTcpIpTunnel : public QIODevice +{ + Q_OBJECT + + friend class Internal::SshChannelManager; + +public: + typedef QSharedPointer<SshDirectTcpIpTunnel> Ptr; + + ~SshDirectTcpIpTunnel(); + + // QIODevice stuff + bool atEnd() const; + qint64 bytesAvailable() const; + bool canReadLine() const; + void close(); + bool isSequential() const { return true; } + + void initialize(); + +signals: + void initialized(); + void error(const QString &reason); + void tunnelClosed(); + +private: + SshDirectTcpIpTunnel(quint32 channelId, quint16 remotePort, + const SshConnectionInfo &connectionInfo, Internal::SshSendFacility &sendFacility); + + // QIODevice stuff + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 len); + + Q_SLOT void handleError(const QString &reason); + + Internal::SshDirectTcpIpTunnelPrivate * const d; +}; + +} // namespace QSsh + +#endif // SSHDIRECTTCPIPTUNNEL_H diff --git a/src/libs/ssh/sshdirecttcpiptunnel_p.h b/src/libs/ssh/sshdirecttcpiptunnel_p.h new file mode 100644 index 0000000000..7122c4dc2a --- /dev/null +++ b/src/libs/ssh/sshdirecttcpiptunnel_p.h @@ -0,0 +1,84 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ +#ifndef DIRECTTCPIPCHANNEL_P_H +#define DIRECTTCPIPCHANNEL_P_H + +#include "sshchannel_p.h" + +#include "sshconnection.h" + +namespace QSsh { +class SshDirectTcpIpTunnel; + +namespace Internal { + +class SshDirectTcpIpTunnelPrivate : public AbstractSshChannel +{ + Q_OBJECT + + friend class QSsh::SshDirectTcpIpTunnel; + +public: + explicit SshDirectTcpIpTunnelPrivate(quint32 channelId, quint16 remotePort, + const SshConnectionInfo &connectionInfo, SshSendFacility &sendFacility); + +signals: + void initialized(); + void readyRead(); + void error(const QString &reason); + void closed(); + +private slots: + void handleEof(); + +private: + void handleChannelSuccess(); + void handleChannelFailure(); + + void handleOpenSuccessInternal(); + void handleOpenFailureInternal(const QString &reason); + void handleChannelDataInternal(const QByteArray &data); + void handleChannelExtendedDataInternal(quint32 type, const QByteArray &data); + void handleExitStatus(const SshChannelExitStatus &exitStatus); + void handleExitSignal(const SshChannelExitSignal &signal); + + void closeHook(); + + const quint16 m_remotePort; + const SshConnectionInfo m_connectionInfo; + QByteArray m_data; +}; + +} // namespace Internal +} // namespace QSsh + +#endif // DIRECTTCPIPCHANNEL_P_H diff --git a/src/libs/ssh/sshkeygenerator.cpp b/src/libs/ssh/sshkeygenerator.cpp index e6aa9676cc..4fc9da5af4 100644 --- a/src/libs/ssh/sshkeygenerator.cpp +++ b/src/libs/ssh/sshkeygenerator.cpp @@ -76,7 +76,7 @@ bool SshKeyGenerator::generateKeys(KeyType type, PrivateKeyFormat format, int ke } return true; } catch (Botan::Exception &e) { - m_error = tr("Error generating key: %1").arg(QString::fromAscii(e.what())); + m_error = tr("Error generating key: %1").arg(QString::fromLatin1(e.what())); return false; } } diff --git a/src/libs/ssh/sshoutgoingpacket.cpp b/src/libs/ssh/sshoutgoingpacket.cpp index 85c644b990..2724ab8e37 100644 --- a/src/libs/ssh/sshoutgoingpacket.cpp +++ b/src/libs/ssh/sshoutgoingpacket.cpp @@ -142,7 +142,16 @@ void SshOutgoingPacket::generateSessionPacket(quint32 channelId, quint32 windowSize, quint32 maxPacketSize) { init(SSH_MSG_CHANNEL_OPEN).appendString("session").appendInt(channelId) - .appendInt(windowSize).appendInt(maxPacketSize).finalize(); + .appendInt(windowSize).appendInt(maxPacketSize).finalize(); +} + +void SshOutgoingPacket::generateDirectTcpIpPacket(quint32 channelId, quint32 windowSize, + quint32 maxPacketSize, const QByteArray &remoteHost, quint32 remotePort, + const QByteArray &localIpAddress, quint32 localPort) +{ + init(SSH_MSG_CHANNEL_OPEN).appendString("direct-tcpip").appendInt(channelId) + .appendInt(windowSize).appendInt(maxPacketSize).appendString(remoteHost) + .appendInt(remotePort).appendString(localIpAddress).appendInt(localPort).finalize(); } void SshOutgoingPacket::generateEnvPacket(quint32 remoteChannel, diff --git a/src/libs/ssh/sshoutgoingpacket_p.h b/src/libs/ssh/sshoutgoingpacket_p.h index 612ffb90a5..7f9c6db104 100644 --- a/src/libs/ssh/sshoutgoingpacket_p.h +++ b/src/libs/ssh/sshoutgoingpacket_p.h @@ -61,6 +61,9 @@ public: void generateInvalidMessagePacket(); void generateSessionPacket(quint32 channelId, quint32 windowSize, quint32 maxPacketSize); + void generateDirectTcpIpPacket(quint32 channelId, quint32 windowSize, + quint32 maxPacketSize, const QByteArray &remoteHost, quint32 remotePort, + const QByteArray &localIpAddress, quint32 localPort); void generateEnvPacket(quint32 remoteChannel, const QByteArray &var, const QByteArray &value); void generatePtyRequestPacket(quint32 remoteChannel, diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp index 98ec11b7cb..fac94be3c1 100644 --- a/src/libs/ssh/sshremoteprocess.cpp +++ b/src/libs/ssh/sshremoteprocess.cpp @@ -166,6 +166,7 @@ void SshRemoteProcess::init() connect(d, SIGNAL(readyReadStandardError()), this, SIGNAL(readyReadStandardError()), Qt::QueuedConnection); connect(d, SIGNAL(closed(int)), this, SIGNAL(closed(int)), Qt::QueuedConnection); + connect(d, SIGNAL(eof()), SIGNAL(readChannelFinished()), Qt::QueuedConnection); } void SshRemoteProcess::addToEnvironment(const QByteArray &var, const QByteArray &value) @@ -205,7 +206,7 @@ void SshRemoteProcess::sendSignal(Signal signal) d->m_sendFacility.sendChannelSignalPacket(d->remoteChannel(), signalString); } } catch (Botan::Exception &e) { - setErrorString(QString::fromAscii(e.what())); + setErrorString(QString::fromLatin1(e.what())); d->closeChannel(); } } diff --git a/src/libs/ssh/sshremoteprocess_p.h b/src/libs/ssh/sshremoteprocess_p.h index e70acc77c0..cd1bcf2754 100644 --- a/src/libs/ssh/sshremoteprocess_p.h +++ b/src/libs/ssh/sshremoteprocess_p.h @@ -53,13 +53,6 @@ public: NotYetStarted, ExecRequested, StartFailed, Running, Exited }; - virtual void handleChannelSuccess(); - virtual void handleChannelFailure(); - - virtual void closeHook(); - - QByteArray &data(); - signals: void started(); void readyRead(); @@ -73,6 +66,9 @@ private: SshRemoteProcessPrivate(quint32 channelId, SshSendFacility &sendFacility, SshRemoteProcess *proc); + virtual void handleChannelSuccess(); + virtual void handleChannelFailure(); + virtual void handleOpenSuccessInternal(); virtual void handleOpenFailureInternal(const QString &reason); virtual void handleChannelDataInternal(const QByteArray &data); @@ -81,8 +77,11 @@ private: virtual void handleExitStatus(const SshChannelExitStatus &exitStatus); virtual void handleExitSignal(const SshChannelExitSignal &signal); + virtual void closeHook(); + void init(); void setProcState(ProcessState newState); + QByteArray &data(); QProcess::ProcessChannel m_readChannel; diff --git a/src/libs/ssh/sshsendfacility.cpp b/src/libs/ssh/sshsendfacility.cpp index 46c3a21e2a..966022f436 100644 --- a/src/libs/ssh/sshsendfacility.cpp +++ b/src/libs/ssh/sshsendfacility.cpp @@ -149,6 +149,15 @@ void SshSendFacility::sendSessionPacket(quint32 channelId, quint32 windowSize, sendPacket(); } +void SshSendFacility::sendDirectTcpIpPacket(quint32 channelId, quint32 windowSize, + quint32 maxPacketSize, const QByteArray &remoteHost, quint32 remotePort, + const QByteArray &localIpAddress, quint32 localPort) +{ + m_outgoingPacket.generateDirectTcpIpPacket(channelId, windowSize, maxPacketSize, remoteHost, + remotePort, localIpAddress, localPort); + sendPacket(); +} + void SshSendFacility::sendPtyRequestPacket(quint32 remoteChannel, const SshPseudoTerminal &terminal) { diff --git a/src/libs/ssh/sshsendfacility_p.h b/src/libs/ssh/sshsendfacility_p.h index 597973dbab..8d7e793a74 100644 --- a/src/libs/ssh/sshsendfacility_p.h +++ b/src/libs/ssh/sshsendfacility_p.h @@ -68,6 +68,9 @@ public: void sendInvalidPacket(); void sendSessionPacket(quint32 channelId, quint32 windowSize, quint32 maxPacketSize); + void sendDirectTcpIpPacket(quint32 channelId, quint32 windowSize, quint32 maxPacketSize, + const QByteArray &remoteHost, quint32 remotePort, const QByteArray &localIpAddress, + quint32 localPort); void sendPtyRequestPacket(quint32 remoteChannel, const SshPseudoTerminal &terminal); void sendEnvPacket(quint32 remoteChannel, const QByteArray &var, diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp index 1e668404d7..cce091d75d 100644 --- a/src/libs/utils/basetreeview.cpp +++ b/src/libs/utils/basetreeview.cpp @@ -30,11 +30,31 @@ #include "basetreeview.h" #include <QHeaderView> +#include <QItemDelegate> +#include <QLabel> #include <QMenu> #include <QMouseEvent> namespace Utils { +class BaseTreeViewDelegate : public QItemDelegate +{ +public: + BaseTreeViewDelegate() {} + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const + { + Q_UNUSED(option); + QLabel *label = new QLabel(parent); + label->setAutoFillBackground(true); + label->setTextInteractionFlags(Qt::TextSelectableByMouse + | Qt::LinksAccessibleByMouse); + label->setText(index.data().toString()); + return label; + } +}; + BaseTreeView::BaseTreeView(QWidget *parent) : QTreeView(parent) { @@ -44,7 +64,7 @@ BaseTreeView::BaseTreeView(QWidget *parent) setIconSize(QSize(10, 10)); setSelectionMode(QAbstractItemView::ExtendedSelection); setUniformRowHeights(true); - + setItemDelegate(new BaseTreeViewDelegate); header()->setDefaultAlignment(Qt::AlignLeft); header()->setClickable(true); diff --git a/src/libs/utils/buildablehelperlibrary.cpp b/src/libs/utils/buildablehelperlibrary.cpp index 75396f33c9..873fe67921 100644 --- a/src/libs/utils/buildablehelperlibrary.cpp +++ b/src/libs/utils/buildablehelperlibrary.cpp @@ -37,8 +37,9 @@ #include <QDateTime> #include <utils/environment.h> -#include <utils/synchronousprocess.h> #include <utils/fileutils.h> +#include <utils/hostosinfo.h> +#include <utils/synchronousprocess.h> #include <QDesktopServices> #include <QDebug> @@ -122,15 +123,14 @@ QString BuildableHelperLibrary::qtVersionForQMake(const QString &qmakePath, bool QStringList BuildableHelperLibrary::possibleQMakeCommands() { // On windows no one has renamed qmake, right? -#ifdef Q_OS_WIN - return QStringList(QLatin1String("qmake.exe")); -#else + if (HostOsInfo::isWindowsHost()) + return QStringList(QLatin1String("qmake.exe")); + // On unix some distributions renamed qmake to avoid clashes QStringList result; result << QLatin1String("qmake-qt4") << QLatin1String("qmake4") << QLatin1String("qmake-qt5") << QLatin1String("qmake5") << QLatin1String("qmake"); return result; -#endif } // Copy helper source files to a target directory, replacing older files. @@ -140,7 +140,7 @@ bool BuildableHelperLibrary::copyFiles(const QString &sourcePath, QString *errorMessage) { // try remove the directory - if (!FileUtils::removeRecursively(targetDirectory, errorMessage)) + if (!FileUtils::removeRecursively(FileName::fromString(targetDirectory), errorMessage)) return false; if (!QDir().mkpath(targetDirectory)) { *errorMessage = QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary", "The target directory %1 could not be created.").arg(targetDirectory); diff --git a/src/libs/utils/consoleprocess.cpp b/src/libs/utils/consoleprocess.cpp index b7f1f3fd73..a4876a9b5d 100644 --- a/src/libs/utils/consoleprocess.cpp +++ b/src/libs/utils/consoleprocess.cpp @@ -124,7 +124,7 @@ QString ConsoleProcess::msgCannotCreateTempDir(const QString & dir, const QStrin QString ConsoleProcess::msgUnexpectedOutput(const QByteArray &what) { - return tr("Unexpected output from helper program (%1).").arg(QString::fromAscii(what)); + return tr("Unexpected output from helper program (%1).").arg(QString::fromLatin1(what)); } QString ConsoleProcess::msgCannotChangeToWorkDir(const QString & dir, const QString &why) diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp index c13430e33c..6607e71ed7 100644 --- a/src/libs/utils/consoleprocess_unix.cpp +++ b/src/libs/utils/consoleprocess_unix.cpp @@ -32,6 +32,8 @@ #include "environment.h" #include "qtcprocess.h" +#include <utils/hostosinfo.h> + #include <QCoreApplication> #include <QDir> #include <QSettings> @@ -133,12 +135,14 @@ bool ConsoleProcess::start(const QString &program, const QString &args) } } + if (Utils::HostOsInfo::isMacHost()) { + xtermArgs << (QCoreApplication::applicationDirPath() + + QLatin1String("/../Resources/qtcreator_process_stub")); + } else { + xtermArgs << (QCoreApplication::applicationDirPath() + + QLatin1String("/qtcreator_process_stub")); + } xtermArgs -#ifdef Q_OS_MAC - << (QCoreApplication::applicationDirPath() + QLatin1String("/../Resources/qtcreator_process_stub")) -#else - << (QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_process_stub")) -#endif << modeOption(d->m_mode) << d->m_stubServer.fullServerName() << msgPromptToClose() @@ -295,9 +299,9 @@ static const Terminal knownTerminals[] = QString ConsoleProcess::defaultTerminalEmulator() { -#ifdef Q_OS_MAC - return QLatin1String("/usr/X11/bin/xterm -e"); -#else + if (Utils::HostOsInfo::isMacHost()) + return QLatin1String("/usr/X11/bin/xterm"); + const Environment env = Environment::systemEnvironment(); const int terminalCount = int(sizeof(knownTerminals) / sizeof(knownTerminals[0])); for (int i = 0; i < terminalCount; ++i) { @@ -309,14 +313,13 @@ QString ConsoleProcess::defaultTerminalEmulator() } } return QLatin1String("xterm -e"); -#endif } QStringList ConsoleProcess::availableTerminalEmulators() { -#ifdef Q_OS_MAC - return QStringList(defaultTerminalEmulator()); -#else + if (Utils::HostOsInfo::isMacHost()) + return QStringList(defaultTerminalEmulator()); + QStringList result; const Environment env = Environment::systemEnvironment(); const int terminalCount = int(sizeof(knownTerminals) / sizeof(knownTerminals[0])); @@ -330,7 +333,6 @@ QStringList ConsoleProcess::availableTerminalEmulators() } result.sort(); return result; -#endif } QString ConsoleProcess::terminalEmulator(const QSettings *settings) diff --git a/src/libs/utils/crumblepath.cpp b/src/libs/utils/crumblepath.cpp index 2829e5f3fc..5ae6ced83e 100644 --- a/src/libs/utils/crumblepath.cpp +++ b/src/libs/utils/crumblepath.cpp @@ -28,6 +28,7 @@ ****************************************************************************/ #include "crumblepath.h" +#include "qtcassert.h" #include "stylehelper.h" #include <QList> @@ -39,8 +40,6 @@ #include <QPainter> #include <QImage> -#include <qtcassert.h> - namespace Utils { static const int ArrowBorderSize = 12; diff --git a/src/libs/utils/detailsbutton.cpp b/src/libs/utils/detailsbutton.cpp index dad496b8d1..35f8f232b7 100644 --- a/src/libs/utils/detailsbutton.cpp +++ b/src/libs/utils/detailsbutton.cpp @@ -29,6 +29,7 @@ #include "detailsbutton.h" +#include <utils/hostosinfo.h> #include <utils/stylehelper.h> #include <QPropertyAnimation> @@ -82,11 +83,9 @@ QSize DetailsButton::sizeHint() const { // TODO: Adjust this when icons become available! const int w = fontMetrics().width(text()) + 32; -#ifdef Q_OS_MAC - return QSize(w, 34); -#else + if (HostOsInfo::isMacHost()) + return QSize(w, 34); return QSize(w, 22); -#endif } bool DetailsButton::event(QEvent *e) @@ -119,11 +118,10 @@ void DetailsButton::paintEvent(QPaintEvent *e) QWidget::paintEvent(e); QPainter p(this); -#ifndef Q_OS_MAC + // draw hover animation - if (!isDown() && m_fader > 0) + if (!HostOsInfo::isMacHost() && !isDown() && m_fader > 0) p.fillRect(rect().adjusted(1, 1, -2, -2), QColor(255, 255, 255, int(m_fader*180))); -#endif if (isChecked()) { if (m_checkedPixmap.isNull() || m_checkedPixmap.size() != contentsRect().size()) diff --git a/src/libs/utils/detailswidget.cpp b/src/libs/utils/detailswidget.cpp index b7aee2c8d3..9f71e36229 100644 --- a/src/libs/utils/detailswidget.cpp +++ b/src/libs/utils/detailswidget.cpp @@ -29,6 +29,7 @@ #include "detailswidget.h" #include "detailsbutton.h" +#include "hostosinfo.h" #include <QStack> #include <QPropertyAnimation> @@ -68,7 +69,6 @@ class DetailsWidgetPrivate public: DetailsWidgetPrivate(QWidget *parent); - QPixmap cacheBackground(const QSize &size); void updateControls(); void changeHoverState(bool hovered); @@ -130,22 +130,18 @@ DetailsWidgetPrivate::DetailsWidgetPrivate(QWidget *parent) : m_grid->addWidget(m_additionalSummaryLabel, 1, 0, 1, 3); } -QPixmap DetailsWidgetPrivate::cacheBackground(const QSize &size) +QPixmap DetailsWidget::createBackground(const QSize &size, int topHeight, QWidget *widget) { QPixmap pixmap(size); pixmap.fill(Qt::transparent); QPainter p(&pixmap); - int topHeight = m_useCheckBox ? m_summaryCheckBox->height() : m_summaryLabel->height(); - if (m_state == DetailsWidget::Expanded || m_state == DetailsWidget::Collapsed) // Details Button is shown - topHeight = qMax(m_detailsButton->height(), topHeight); - QRect topRect(0, 0, size.width(), topHeight); QRect fullRect(0, 0, size.width(), size.height()); -#ifdef Q_OS_MAC - p.fillRect(fullRect, qApp->palette().window().color()); -#endif - p.fillRect(fullRect, QColor(255, 255, 255, 40)); + if (HostOsInfo::isMacHost()) + p.fillRect(fullRect, qApp->palette().window().color()); + else + p.fillRect(fullRect, QColor(255, 255, 255, 40)); QLinearGradient lg(topRect.topLeft(), topRect.bottomLeft()); lg.setColorAt(0, QColor(255, 255, 255, 130)); @@ -159,7 +155,7 @@ QPixmap DetailsWidgetPrivate::cacheBackground(const QSize &size) p.setBrush(Qt::NoBrush); p.setPen(QColor(255,255,255,140)); p.drawRoundedRect(fullRect.adjusted(1, 1, -2, -2), 2, 2); - p.setPen(QPen(q->palette().color(QPalette::Mid))); + p.setPen(QPen(widget->palette().color(QPalette::Mid))); return pixmap; } @@ -187,11 +183,10 @@ void DetailsWidgetPrivate::changeHoverState(bool hovered) { if (!m_toolWidget) return; -#ifdef Q_OS_MAC - m_toolWidget->setOpacity(hovered ? 1.0 : 0); -#else - m_toolWidget->fadeTo(hovered ? 1.0 : 0); -#endif + if (HostOsInfo::isMacHost()) + m_toolWidget->setOpacity(hovered ? 1.0 : 0); + else + m_toolWidget->fadeTo(hovered ? 1.0 : 0); m_hovered = hovered; } @@ -263,15 +258,19 @@ void DetailsWidget::paintEvent(QPaintEvent *paintEvent) QPoint topLeft(topLeftWidget->geometry().left() - MARGIN, contentsRect().top()); const QRect paintArea(topLeft, contentsRect().bottomRight()); + int topHeight = d->m_useCheckBox ? d->m_summaryCheckBox->height() : d->m_summaryLabel->height(); + if (d->m_state == DetailsWidget::Expanded || d->m_state == DetailsWidget::Collapsed) // Details Button is shown + topHeight = qMax(d->m_detailsButton->height(), topHeight); + if (d->m_state == Collapsed) { if (d->m_collapsedPixmap.isNull() || d->m_collapsedPixmap.size() != size()) - d->m_collapsedPixmap = d->cacheBackground(paintArea.size()); + d->m_collapsedPixmap = createBackground(paintArea.size(), topHeight, this); p.drawPixmap(paintArea, d->m_collapsedPixmap); } else { if (d->m_expandedPixmap.isNull() || d->m_expandedPixmap.size() != size()) - d->m_expandedPixmap = d->cacheBackground(paintArea.size()); + d->m_expandedPixmap = createBackground(paintArea.size(), topHeight, this); p.drawPixmap(paintArea, d->m_expandedPixmap); } } @@ -380,9 +379,8 @@ void DetailsWidget::setToolWidget(Utils::FadingPanel *widget) d->m_toolWidget->adjustSize(); d->m_grid->addWidget(d->m_toolWidget, 0, 1, 1, 1, Qt::AlignRight); -#ifdef Q_OS_MAC - d->m_toolWidget->setOpacity(1.0); -#endif + if (HostOsInfo::isMacHost()) + d->m_toolWidget->setOpacity(1.0); d->changeHoverState(d->m_hovered); } diff --git a/src/libs/utils/detailswidget.h b/src/libs/utils/detailswidget.h index 726cc9a650..5ab4470e1e 100644 --- a/src/libs/utils/detailswidget.h +++ b/src/libs/utils/detailswidget.h @@ -86,6 +86,8 @@ public: /// Sets an icon, only supported if useCheckBox is true void setIcon(const QIcon &icon); + static QPixmap createBackground(const QSize &size, int topHeight, QWidget *widget); + signals: void checked(bool); void linkActivated(const QString &link); diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp index fff002ef87..7a5849823b 100644 --- a/src/libs/utils/environment.cpp +++ b/src/libs/utils/environment.cpp @@ -29,6 +29,8 @@ #include "environment.h" +#include "hostosinfo.h" + #include <QDir> #include <QProcess> #include <QString> @@ -40,18 +42,18 @@ public: SystemEnvironment() : Environment(QProcess::systemEnvironment()) { -#ifdef Q_OS_LINUX - QString ldLibraryPath = value(QLatin1String("LD_LIBRARY_PATH")); - QDir lib(QCoreApplication::applicationDirPath()); - lib.cd("../lib"); - QString toReplace = lib.path(); - lib.cd("qtcreator"); - toReplace.append(QLatin1String(":")); - toReplace.append(lib.path()); - - if (ldLibraryPath.startsWith(toReplace)) - set(QLatin1String("LD_LIBRARY_PATH"), ldLibraryPath.remove(0, toReplace.length())); -#endif + if (Utils::HostOsInfo::isLinuxHost()) { + QString ldLibraryPath = value(QLatin1String("LD_LIBRARY_PATH")); + QDir lib(QCoreApplication::applicationDirPath()); + lib.cd("../lib"); + QString toReplace = lib.path(); + lib.cd("qtcreator"); + toReplace.append(QLatin1String(":")); + toReplace.append(lib.path()); + + if (ldLibraryPath.startsWith(toReplace)) + set(QLatin1String("LD_LIBRARY_PATH"), ldLibraryPath.remove(0, toReplace.length())); + } } }; @@ -103,11 +105,10 @@ Environment::Environment(const QStringList &env) foreach (const QString &s, env) { int i = s.indexOf(QLatin1Char('=')); if (i >= 0) { -#ifdef Q_OS_WIN - m_values.insert(s.left(i).toUpper(), s.mid(i+1)); -#else - m_values.insert(s.left(i), s.mid(i+1)); -#endif + if (HostOsInfo::isWindowsHost()) + m_values.insert(s.left(i).toUpper(), s.mid(i+1)); + else + m_values.insert(s.left(i), s.mid(i+1)); } } } @@ -127,32 +128,18 @@ QStringList Environment::toStringList() const void Environment::set(const QString &key, const QString &value) { -#ifdef Q_OS_WIN - QString _key = key.toUpper(); -#else - const QString &_key = key; -#endif - m_values.insert(_key, value); + m_values.insert(HostOsInfo::isWindowsHost() ? key.toUpper() : key, value); } void Environment::unset(const QString &key) { -#ifdef Q_OS_WIN - QString _key = key.toUpper(); -#else - const QString &_key = key; -#endif - m_values.remove(_key); + m_values.remove(HostOsInfo::isWindowsHost() ? key.toUpper() : key); } void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep) { -#ifdef Q_OS_WIN - QString _key = key.toUpper(); -#else - const QString &_key = key; -#endif - QMap<QString, QString>::iterator it = m_values.find(key); + const QString &_key = HostOsInfo::isWindowsHost() ? key.toUpper() : key; + QMap<QString, QString>::iterator it = m_values.find(_key); if (it == m_values.end()) { m_values.insert(_key, value); } else { @@ -165,12 +152,8 @@ void Environment::appendOrSet(const QString &key, const QString &value, const QS void Environment::prependOrSet(const QString&key, const QString &value, const QString &sep) { -#ifdef Q_OS_WIN - QString _key = key.toUpper(); -#else - const QString &_key = key; -#endif - QMap<QString, QString>::iterator it = m_values.find(key); + const QString &_key = HostOsInfo::isWindowsHost() ? key.toUpper() : key; + QMap<QString, QString>::iterator it = m_values.find(_key); if (it == m_values.end()) { m_values.insert(_key, value); } else { @@ -183,38 +166,35 @@ void Environment::prependOrSet(const QString&key, const QString &value, const QS void Environment::appendOrSetPath(const QString &value) { -#ifdef Q_OS_WIN - const QChar sep = QLatin1Char(';'); -#else - const QChar sep = QLatin1Char(':'); -#endif - appendOrSet(QLatin1String("PATH"), QDir::toNativeSeparators(value), QString(sep)); + appendOrSet(QLatin1String("PATH"), QDir::toNativeSeparators(value), + QString(HostOsInfo::pathListSeparator())); } void Environment::prependOrSetPath(const QString &value) { -#ifdef Q_OS_WIN - const QChar sep = QLatin1Char(';'); -#else - const QChar sep = QLatin1Char(':'); -#endif - prependOrSet(QLatin1String("PATH"), QDir::toNativeSeparators(value), QString(sep)); + prependOrSet(QLatin1String("PATH"), QDir::toNativeSeparators(value), + QString(HostOsInfo::pathListSeparator())); } void Environment::prependOrSetLibrarySearchPath(const QString &value) { -#ifdef Q_OS_MAC - Q_UNUSED(value); - // we could set DYLD_LIBRARY_PATH on Mac but it is unnecessary in practice -#elif defined(Q_OS_WIN) - const QChar sep = QLatin1Char(';'); - const QLatin1String path("PATH"); - prependOrSet(path, QDir::toNativeSeparators(value), QString(sep)); -#elif defined(Q_OS_UNIX) - const QChar sep = QLatin1Char(':'); - const QLatin1String path("LD_LIBRARY_PATH"); - prependOrSet(path, QDir::toNativeSeparators(value), QString(sep)); -#endif + switch (HostOsInfo::hostOs()) { + case HostOsInfo::HostOsWindows: { + const QChar sep = QLatin1Char(';'); + const QLatin1String path("PATH"); + prependOrSet(path, QDir::toNativeSeparators(value), QString(sep)); + break; + } + case HostOsInfo::HostOsLinux: + case HostOsInfo::HostOsOtherUnix: { + const QChar sep = QLatin1Char(':'); + const QLatin1String path("LD_LIBRARY_PATH"); + prependOrSet(path, QDir::toNativeSeparators(value), QString(sep)); + break; + } + default: // we could set DYLD_LIBRARY_PATH on Mac but it is unnecessary in practice + break; + } } Environment Environment::systemEnvironment() @@ -257,16 +237,16 @@ QString Environment::searchInPath(const QString &executable, return QString(); QStringList execs(exec); -#ifdef Q_OS_WIN - // Check all the executable extensions on windows: - // PATHEXT is only used if the executable has no extension - if (fi.suffix().isEmpty()) { - QStringList extensions = value(QLatin1String("PATHEXT")).split(QLatin1Char(';')); - - foreach (const QString &ext, extensions) - execs << executable + ext.toLower(); + if (HostOsInfo::isWindowsHost()) { + // Check all the executable extensions on windows: + // PATHEXT is only used if the executable has no extension + if (fi.suffix().isEmpty()) { + QStringList extensions = value(QLatin1String("PATHEXT")).split(QLatin1Char(';')); + + foreach (const QString &ext, extensions) + execs << executable + ext.toLower(); + } } -#endif foreach (QString dir, additionalDirs) { QString tmp = searchInDirectory(execs, dir); @@ -287,12 +267,8 @@ QString Environment::searchInPath(const QString &executable, QStringList Environment::path() const { -#ifdef Q_OS_WIN - const QChar sep = QLatin1Char(';'); -#else - const QChar sep = QLatin1Char(':'); -#endif - return m_values.value(QLatin1String("PATH")).split(sep, QString::SkipEmptyParts); + return m_values.value(QLatin1String("PATH")).split(HostOsInfo::pathListSeparator(), + QString::SkipEmptyParts); } QString Environment::value(const QString &key) const @@ -404,6 +380,11 @@ bool Environment::hasKey(const QString &key) return m_values.contains(key); } +QString Environment::userName() const +{ + return value(QLatin1String(HostOsInfo::isWindowsHost() ? "USERNAME" : "USER")); +} + bool Environment::operator!=(const Environment &other) const { return !(*this == other); @@ -425,68 +406,68 @@ QString Environment::expandVariables(const QString &input) const { QString result = input; -#ifdef Q_OS_WIN - for (int vStart = -1, i = 0; i < result.length(); ) { - if (result.at(i++) == QLatin1Char('%')) { - if (vStart > 0) { - const_iterator it = m_values.constFind(result.mid(vStart, i - vStart - 1).toUpper()); - if (it != m_values.constEnd()) { - result.replace(vStart - 1, i - vStart + 1, *it); - i = vStart - 1 + it->length(); - vStart = -1; + if (HostOsInfo::isWindowsHost()) { + for (int vStart = -1, i = 0; i < result.length(); ) { + if (result.at(i++) == QLatin1Char('%')) { + if (vStart > 0) { + const_iterator it = m_values.constFind(result.mid(vStart, i - vStart - 1).toUpper()); + if (it != m_values.constEnd()) { + result.replace(vStart - 1, i - vStart + 1, *it); + i = vStart - 1 + it->length(); + vStart = -1; + } else { + vStart = i; + } } else { vStart = i; } - } else { - vStart = i; } } - } -#else - enum { BASE, OPTIONALVARIABLEBRACE, VARIABLE, BRACEDVARIABLE } state = BASE; - int vStart = -1; - - for (int i = 0; i < result.length();) { - QChar c = result.at(i++); - if (state == BASE) { - if (c == QLatin1Char('$')) - state = OPTIONALVARIABLEBRACE; - } else if (state == OPTIONALVARIABLEBRACE) { - if (c == QLatin1Char('{')) { - state = BRACEDVARIABLE; - vStart = i; - } else if (c.isLetterOrNumber() || c == QLatin1Char('_')) { - state = VARIABLE; - vStart = i - 1; - } else { - state = BASE; - } - } else if (state == BRACEDVARIABLE) { - if (c == QLatin1Char('}')) { - const_iterator it = m_values.constFind(result.mid(vStart, i - 1 - vStart)); - if (it != constEnd()) { - result.replace(vStart - 2, i - vStart + 2, *it); - i = vStart - 2 + it->length(); + } else { + enum { BASE, OPTIONALVARIABLEBRACE, VARIABLE, BRACEDVARIABLE } state = BASE; + int vStart = -1; + + for (int i = 0; i < result.length();) { + QChar c = result.at(i++); + if (state == BASE) { + if (c == QLatin1Char('$')) + state = OPTIONALVARIABLEBRACE; + } else if (state == OPTIONALVARIABLEBRACE) { + if (c == QLatin1Char('{')) { + state = BRACEDVARIABLE; + vStart = i; + } else if (c.isLetterOrNumber() || c == QLatin1Char('_')) { + state = VARIABLE; + vStart = i - 1; + } else { + state = BASE; } - state = BASE; - } - } else if (state == VARIABLE) { - if (!c.isLetterOrNumber() && c != QLatin1Char('_')) { - const_iterator it = m_values.constFind(result.mid(vStart, i - vStart - 1)); - if (it != constEnd()) { - result.replace(vStart - 1, i - vStart, *it); - i = vStart - 1 + it->length(); + } else if (state == BRACEDVARIABLE) { + if (c == QLatin1Char('}')) { + const_iterator it = m_values.constFind(result.mid(vStart, i - 1 - vStart)); + if (it != constEnd()) { + result.replace(vStart - 2, i - vStart + 2, *it); + i = vStart - 2 + it->length(); + } + state = BASE; + } + } else if (state == VARIABLE) { + if (!c.isLetterOrNumber() && c != QLatin1Char('_')) { + const_iterator it = m_values.constFind(result.mid(vStart, i - vStart - 1)); + if (it != constEnd()) { + result.replace(vStart - 1, i - vStart, *it); + i = vStart - 1 + it->length(); + } + state = BASE; } - state = BASE; } } + if (state == VARIABLE) { + const_iterator it = m_values.constFind(result.mid(vStart)); + if (it != constEnd()) + result.replace(vStart - 1, result.length() - vStart + 1, *it); + } } - if (state == VARIABLE) { - const_iterator it = m_values.constFind(result.mid(vStart)); - if (it != constEnd()) - result.replace(vStart - 1, result.length() - vStart + 1, *it); - } -#endif return result; } diff --git a/src/libs/utils/environment.h b/src/libs/utils/environment.h index 501a29d9f6..1e8d2984dc 100644 --- a/src/libs/utils/environment.h +++ b/src/libs/utils/environment.h @@ -78,6 +78,8 @@ public: QList<EnvironmentItem> diff(const Environment &other) const; bool hasKey(const QString &key); + QString userName() const; + void appendOrSet(const QString &key, const QString &value, const QString &sep = QString()); void prependOrSet(const QString &key, const QString &value, const QString &sep = QString()); diff --git a/src/libs/utils/environmentmodel.cpp b/src/libs/utils/environmentmodel.cpp index 02c1cecd39..a6386866bf 100644 --- a/src/libs/utils/environmentmodel.cpp +++ b/src/libs/utils/environmentmodel.cpp @@ -30,8 +30,10 @@ #include "environmentmodel.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <QFont> +#include <QTextEdit> namespace Utils { namespace Internal { @@ -147,7 +149,14 @@ QVariant EnvironmentModel::data(const QModelIndex &index, int role) const if (pos >= 0) return d->m_items.at(pos).value; } - return d->m_resultEnvironment.value(d->m_resultEnvironment.constBegin() + index.row()); + QString value = d->m_resultEnvironment.value(d->m_resultEnvironment.constBegin() + index.row()); + if (role == Qt::ToolTipRole && value.length() > 80) { + // Use html to enable text wrapping + value = Qt::escape(value); + value.prepend("<html><body>"); + value.append("</body></html>"); + } + return value; } } if (role == Qt::FontRole) { @@ -201,11 +210,8 @@ bool EnvironmentModel::setData(const QModelIndex &index, const QVariant &value, if (index.column() == 0) { //fail if a variable with the same name already exists -#if defined(Q_OS_WIN) - const QString &newName = value.toString().toUpper(); -#else - const QString &newName = value.toString(); -#endif + const QString &newName = HostOsInfo::isWindowsHost() + ? value.toString().toUpper() : value.toString(); // Does the new name exist already? if (d->m_resultEnvironment.hasKey(newName) || newName.isEmpty()) return false; diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp index ac8fb43906..29ed7f4068 100644 --- a/src/libs/utils/fancymainwindow.cpp +++ b/src/libs/utils/fancymainwindow.cpp @@ -256,7 +256,7 @@ void FancyMainWindow::restoreSettings(const QHash<QString, QVariant> &settings) QList<QDockWidget *> FancyMainWindow::dockWidgets() const { - return qFindChildren<QDockWidget *>(this); + return findChildren<QDockWidget *>(); } bool FancyMainWindow::isLocked() const @@ -274,7 +274,7 @@ static bool actionLessThan(const QAction *action1, const QAction *action2) QMenu *FancyMainWindow::createPopupMenu() { QList<QAction *> actions; - QList<QDockWidget *> dockwidgets = qFindChildren<QDockWidget *>(this); + QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>(); for (int i = 0; i < dockwidgets.size(); ++i) { QDockWidget *dockWidget = dockwidgets.at(i); if (dockWidget->property("managed_dockwidget").isNull() diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index 7194d523ab..743eab73b2 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -30,6 +30,7 @@ #include "fileutils.h" #include "savefile.h" +#include "hostosinfo.h" #include "qtcassert.h" #include <QDir> @@ -57,14 +58,14 @@ namespace Utils { \return Whether the operation succeeded. */ -bool FileUtils::removeRecursively(const QString &filePath, QString *error) +bool FileUtils::removeRecursively(const FileName &filePath, QString *error) { - QFileInfo fileInfo(filePath); + QFileInfo fileInfo = filePath.toFileInfo(); if (!fileInfo.exists() && !fileInfo.isSymLink()) return true; - QFile::setPermissions(filePath, fileInfo.permissions() | QFile::WriteUser); + QFile::setPermissions(filePath.toString(), fileInfo.permissions() | QFile::WriteUser); if (fileInfo.isDir()) { - QDir dir(filePath); + QDir dir(filePath.toString()); dir = dir.canonicalPath(); if (dir.isRoot()) { if (error) { @@ -84,21 +85,21 @@ bool FileUtils::removeRecursively(const QString &filePath, QString *error) QStringList fileNames = dir.entryList(QDir::Files | QDir::Hidden | QDir::System | QDir::Dirs | QDir::NoDotAndDotDot); foreach (const QString &fileName, fileNames) { - if (!removeRecursively(filePath + QLatin1Char('/') + fileName, error)) + if (!removeRecursively(FileName(filePath).appendPath(fileName), error)) return false; } if (!QDir::root().rmdir(dir.path())) { if (error) { *error = QCoreApplication::translate("Utils::FileUtils", "Failed to remove directory '%1'.") - .arg(QDir::toNativeSeparators(filePath)); + .arg(filePath.toUserOutput()); } return false; } } else { - if (!QFile::remove(filePath)) { + if (!QFile::remove(filePath.toString())) { if (error) { *error = QCoreApplication::translate("Utils::FileUtils", "Failed to remove file '%1'.") - .arg(QDir::toNativeSeparators(filePath)); + .arg(filePath.toUserOutput()); } return false; } @@ -123,36 +124,36 @@ bool FileUtils::removeRecursively(const QString &filePath, QString *error) \return Whether the operation succeeded. */ -bool FileUtils::copyRecursively(const QString &srcFilePath, - const QString &tgtFilePath, QString *error) +bool FileUtils::copyRecursively(const FileName &srcFilePath, const FileName &tgtFilePath, + QString *error) { - QFileInfo srcFileInfo(srcFilePath); + QFileInfo srcFileInfo = srcFilePath.toFileInfo(); if (srcFileInfo.isDir()) { - QDir targetDir(tgtFilePath); + QDir targetDir(tgtFilePath.toString()); targetDir.cdUp(); - if (!targetDir.mkdir(QFileInfo(tgtFilePath).fileName())) { + if (!targetDir.mkdir(tgtFilePath.toFileInfo().fileName())) { if (error) { *error = QCoreApplication::translate("Utils::FileUtils", "Failed to create directory '%1'.") - .arg(QDir::toNativeSeparators(tgtFilePath)); + .arg(tgtFilePath.toUserOutput()); } return false; } - QDir sourceDir(srcFilePath); - QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System); + QDir sourceDir(srcFilePath.toString()); + QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot + | QDir::Hidden | QDir::System); foreach (const QString &fileName, fileNames) { - const QString newSrcFilePath - = srcFilePath + QLatin1Char('/') + fileName; - const QString newTgtFilePath - = tgtFilePath + QLatin1Char('/') + fileName; + FileName newSrcFilePath = srcFilePath; + newSrcFilePath.appendPath(fileName); + FileName newTgtFilePath = tgtFilePath; + newTgtFilePath.appendPath(fileName); if (!copyRecursively(newSrcFilePath, newTgtFilePath, error)) return false; } } else { - if (!QFile::copy(srcFilePath, tgtFilePath)) { + if (!QFile::copy(srcFilePath.toString(), tgtFilePath.toString())) { if (error) { *error = QCoreApplication::translate("Utils::FileUtils", "Could not copy file '%1' to '%2'.") - .arg(QDir::toNativeSeparators(srcFilePath), - QDir::toNativeSeparators(tgtFilePath)); + .arg(srcFilePath.toUserOutput(), tgtFilePath.toUserOutput()); } return false; } @@ -167,19 +168,16 @@ bool FileUtils::copyRecursively(const QString &srcFilePath, \return Whether at least one file in \a filePath has a newer date than \a timeStamp. */ -bool FileUtils::isFileNewerThan(const QString &filePath, - const QDateTime &timeStamp) +bool FileUtils::isFileNewerThan(const FileName &filePath, const QDateTime &timeStamp) { - QFileInfo fileInfo(filePath); + QFileInfo fileInfo = filePath.toFileInfo(); if (!fileInfo.exists() || fileInfo.lastModified() >= timeStamp) return true; if (fileInfo.isDir()) { - const QStringList dirContents = QDir(filePath) + const QStringList dirContents = QDir(filePath.toString()) .entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); foreach (const QString &curFileName, dirContents) { - const QString curFilePath - = filePath + QLatin1Char('/') + curFileName; - if (isFileNewerThan(curFilePath, timeStamp)) + if (isFileNewerThan(FileName(filePath).appendPath(curFileName), timeStamp)) return true; } } @@ -195,15 +193,33 @@ bool FileUtils::isFileNewerThan(const QString &filePath, return Symlink target file path. */ -QString FileUtils::resolveSymlinks(const QString &path) +FileName FileUtils::resolveSymlinks(const FileName &path) { - QFileInfo f(path); + QFileInfo f = path.toFileInfo(); int links = 16; while (links-- && f.isSymLink()) f.setFile(f.symLinkTarget()); if (links <= 0) - return QString(); - return f.filePath(); + return FileName(); + return FileName::fromString(f.filePath()); +} + +/*! + Like QDir::toNativeSeparators(), but use prefix '~' instead of $HOME on unix systems when an + absolute path is given. + + return Possibly shortened path with native separators. +*/ +QString FileUtils::shortNativePath(const FileName &path) +{ + if (HostOsInfo::isAnyUnixHost()) { + const FileName home = FileName::fromString(QDir::cleanPath(QDir::homePath())); + if (path.isChildOf(home)) { + return QLatin1Char('~') + QDir::separator() + + QDir::toNativeSeparators(path.relativeChildPath(home).toString()); + } + } + return path.toUserOutput(); } QByteArray FileReader::fetchQrc(const QString &fileName) @@ -411,13 +427,6 @@ TempFileSaver::~TempFileSaver() On windows filenames are compared case insensitively. */ - -#ifdef Q_OS_WIN -Qt::CaseSensitivity FileName::cs = Qt::CaseInsensitive; -#else -Qt::CaseSensitivity FileName::cs = Qt::CaseSensitive; -#endif - FileName::FileName() : QString() { @@ -480,10 +489,9 @@ FileName FileName::fromString(const QString &filename) /// Constructs a FileName from \a fileName /// \a fileName is only passed through QDir::cleanPath -/// and QDir::fromNativeSeparators FileName FileName::fromUserInput(const QString &filename) { - return FileName(QDir::cleanPath(QDir::fromNativeSeparators(filename))); + return FileName(QDir::cleanPath(filename)); } FileName::FileName(const QString &string) @@ -494,7 +502,7 @@ FileName::FileName(const QString &string) bool FileName::operator==(const FileName &other) const { - return QString::compare(*this, other, cs) == 0; + return QString::compare(*this, other, HostOsInfo::fileNameCaseSensitivity()) == 0; } bool FileName::operator!=(const FileName &other) const @@ -504,12 +512,12 @@ bool FileName::operator!=(const FileName &other) const bool FileName::operator<(const FileName &other) const { - return QString::compare(*this, other, cs) < 0; + return QString::compare(*this, other, HostOsInfo::fileNameCaseSensitivity()) < 0; } bool FileName::operator<=(const FileName &other) const { - return QString::compare(*this, other, cs) <= 0; + return QString::compare(*this, other, HostOsInfo::fileNameCaseSensitivity()) <= 0; } bool FileName::operator>(const FileName &other) const @@ -527,7 +535,7 @@ bool FileName::isChildOf(const FileName &s) const { if (s.isEmpty()) return false; - if (!QString::startsWith(s, cs)) + if (!QString::startsWith(s, HostOsInfo::fileNameCaseSensitivity())) return false; if (size() <= s.size()) return false; @@ -547,7 +555,7 @@ bool FileName::isChildOf(const QDir &dir) const /// \returns whether FileName endsWith \a s bool FileName::endsWith(const QString &s) const { - return QString::endsWith(s, cs); + return QString::endsWith(s, HostOsInfo::fileNameCaseSensitivity()); } /// \returns the relativeChildPath of FileName to parent if FileName is a child of parent @@ -586,10 +594,8 @@ FileName &FileName::append(QChar str) QT_BEGIN_NAMESPACE uint qHash(const Utils::FileName &a) { -#ifdef Q_OS_WIN - return qHash(a.toString().toUpper()); -#else + if (Utils::HostOsInfo::isWindowsHost()) + return qHash(a.toString().toUpper()); return qHash(a.toString()); -#endif } QT_END_NAMESPACE diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 1c209e8dfb..9ccbc05656 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -49,14 +49,53 @@ QT_END_NAMESPACE namespace Utils { +class QTCREATOR_UTILS_EXPORT FileName : private QString +{ +public: + FileName(); + explicit FileName(const QFileInfo &info); + QFileInfo toFileInfo() const; + static FileName fromString(const QString &filename); + static FileName fromUserInput(const QString &filename); + QString toString() const; + QString toUserOutput() const; + + FileName parentDir() const; + + bool operator==(const FileName &other) const; + bool operator!=(const FileName &other) const; + bool operator<(const FileName &other) const; + bool operator<=(const FileName &other) const; + bool operator>(const FileName &other) const; + bool operator>=(const FileName &other) const; + + bool isChildOf(const FileName &s) const; + bool isChildOf(const QDir &dir) const; + bool endsWith(const QString &s) const; + + Utils::FileName relativeChildPath(const FileName &parent) const; + Utils::FileName &appendPath(const QString &s); + Utils::FileName &append(const QString &str); + Utils::FileName &append(QChar str); + + using QString::size; + using QString::count; + using QString::length; + using QString::isEmpty; + using QString::isNull; + using QString::clear; +private: + FileName(const QString &string); +}; + class QTCREATOR_UTILS_EXPORT FileUtils { public: - static bool removeRecursively(const QString &filePath, QString *error = 0); - static bool copyRecursively(const QString &srcFilePath, - const QString &tgtFilePath, QString *error = 0); - static bool isFileNewerThan(const QString &filePath, - const QDateTime &timeStamp); - static QString resolveSymlinks(const QString &path); + static bool removeRecursively(const FileName &filePath, QString *error = 0); + static bool copyRecursively(const FileName &srcFilePath, const FileName &tgtFilePath, + QString *error = 0); + static bool isFileNewerThan(const FileName &filePath, const QDateTime &timeStamp); + static FileName resolveSymlinks(const FileName &path); + static QString shortNativePath(const FileName &path); }; class QTCREATOR_UTILS_EXPORT FileReader @@ -138,46 +177,6 @@ private: bool m_autoRemove; }; -class QTCREATOR_UTILS_EXPORT FileName : private QString -{ -public: - FileName(); - explicit FileName(const QFileInfo &info); - QFileInfo toFileInfo() const; - static FileName fromString(const QString &filename); - static FileName fromUserInput(const QString &filename); - QString toString() const; - QString toUserOutput() const; - - FileName parentDir() const; - - bool operator==(const FileName &other) const; - bool operator!=(const FileName &other) const; - bool operator<(const FileName &other) const; - bool operator<=(const FileName &other) const; - bool operator>(const FileName &other) const; - bool operator>=(const FileName &other) const; - - bool isChildOf(const FileName &s) const; - bool isChildOf(const QDir &dir) const; - bool endsWith(const QString &s) const; - - Utils::FileName relativeChildPath(const FileName &parent) const; - Utils::FileName &appendPath(const QString &s); - Utils::FileName &append(const QString &str); - Utils::FileName &append(QChar str); - - using QString::size; - using QString::count; - using QString::length; - using QString::isEmpty; - using QString::isNull; - using QString::clear; -private: - static Qt::CaseSensitivity cs; - FileName(const QString &string); -}; - } // namespace Utils QT_BEGIN_NAMESPACE diff --git a/src/libs/utils/filewizarddialog.cpp b/src/libs/utils/filewizarddialog.cpp index 46e401238b..63545ef7ef 100644 --- a/src/libs/utils/filewizarddialog.cpp +++ b/src/libs/utils/filewizarddialog.cpp @@ -30,6 +30,8 @@ #include "filewizarddialog.h" #include "filewizardpage.h" +#include "hostosinfo.h" + #include <QAbstractButton> /*! @@ -48,15 +50,15 @@ FileWizardDialog::FileWizardDialog(QWidget *parent) : setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setOption(QWizard::NoCancelButton, false); setOption(QWizard::NoDefaultButton, false); -#ifdef Q_OS_MAC - setButtonLayout(QList<QWizard::WizardButton>() - << QWizard::CancelButton - << QWizard::Stretch - << QWizard::BackButton - << QWizard::NextButton - << QWizard::CommitButton - << QWizard::FinishButton); -#endif + if (HostOsInfo::isMacHost()) { + setButtonLayout(QList<QWizard::WizardButton>() + << QWizard::CancelButton + << QWizard::Stretch + << QWizard::BackButton + << QWizard::NextButton + << QWizard::CommitButton + << QWizard::FinishButton); + } const int filePageId = addPage(m_filePage); wizardProgress()->item(filePageId)->setTitle(tr("Location")); connect(m_filePage, SIGNAL(activated()), button(QWizard::FinishButton), SLOT(animateClick())); diff --git a/src/libs/utils/filewizardpage.ui b/src/libs/utils/filewizardpage.ui index 17b78cae6d..e8b3ca1b4b 100644 --- a/src/libs/utils/filewizardpage.ui +++ b/src/libs/utils/filewizardpage.ui @@ -45,7 +45,7 @@ <customwidget> <class>Utils::PathChooser</class> <extends>QWidget</extends> - <header>pathchooser.h</header> + <header location="global">utils/pathchooser.h</header> <container>1</container> </customwidget> </customwidgets> diff --git a/src/libs/utils/historycompleter.cpp b/src/libs/utils/historycompleter.cpp index 49bfaeaae6..ff092dc04b 100644 --- a/src/libs/utils/historycompleter.cpp +++ b/src/libs/utils/historycompleter.cpp @@ -138,17 +138,20 @@ bool HistoryCompleterPrivate::removeRows(int row, int count, const QModelIndex & void HistoryCompleterPrivate::clearHistory() { + beginResetModel(); list.clear(); - reset(); + endResetModel(); } void HistoryCompleterPrivate::saveEntry(const QString &str) { QTC_ASSERT(theSettings, return); - if (str.isEmpty()) - return; - if (list.contains(str)) - return; + int removeIndex = list.indexOf(str); + if (removeIndex != -1) { + beginRemoveRows(QModelIndex(), removeIndex, removeIndex); + list.removeAt(removeIndex); + endRemoveRows(); + } beginInsertRows (QModelIndex(), list.count(), list.count()); list.prepend(str); list = list.mid(0, maxLines); diff --git a/src/libs/utils/hostosinfo.h b/src/libs/utils/hostosinfo.h new file mode 100644 index 0000000000..e44be53617 --- /dev/null +++ b/src/libs/utils/hostosinfo.h @@ -0,0 +1,108 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef HOSTOSINFO_H +#define HOSTOSINFO_H + +#include "utils_global.h" + +#include <QString> + +#ifdef Q_OS_WIN +#define QTC_HOST_EXE_SUFFIX ".exe" +#else +#define QTC_HOST_EXE_SUFFIX "" +#endif // Q_OS_WIN + +namespace Utils { + +class QTCREATOR_UTILS_EXPORT HostOsInfo +{ +public: + // Add more as needed. + enum HostOs { HostOsWindows, HostOsLinux, HostOsMac, HostOsOtherUnix, HostOsOther }; + + static inline HostOs hostOs(); + + static bool isWindowsHost() { return hostOs() == HostOsWindows; } + static bool isLinuxHost() { return hostOs() == HostOsLinux; } + static bool isMacHost() { return hostOs() == HostOsMac; } + static inline bool isAnyUnixHost(); + + static QString appendExecutableSuffix(const QString &executable) + { + QString finalName = executable; + if (isWindowsHost()) + finalName += QLatin1String(QTC_HOST_EXE_SUFFIX); + return finalName; + } + + static Qt::CaseSensitivity fileNameCaseSensitivity() + { + return isWindowsHost() ? Qt::CaseInsensitive: Qt::CaseSensitive; + } + + static QChar pathListSeparator() + { + return isWindowsHost() ? QLatin1Char(';') : QLatin1Char(':'); + } + + static Qt::KeyboardModifier controlModifier() + { + return isMacHost() ? Qt::MetaModifier : Qt::ControlModifier; + } +}; + +HostOsInfo::HostOs HostOsInfo::hostOs() +{ +#if defined(Q_OS_WIN) + return HostOsWindows; +#elif defined(Q_OS_LINUX) + return HostOsLinux; +#elif defined(Q_OS_MAC) + return HostOsMac; +#elif defined(Q_OS_UNIX) + return HostOsOtherUnix; +#else + return HostOsOther; +#endif +} + +bool HostOsInfo::isAnyUnixHost() +{ +#ifdef Q_OS_UNIX + return true; +#else + return false; +#endif +} + +} // namespace Utils + +#endif // HOSTOSINFO_H diff --git a/src/libs/utils/networkaccessmanager.cpp b/src/libs/utils/networkaccessmanager.cpp index 54f8c44ed4..653d41051e 100644 --- a/src/libs/utils/networkaccessmanager.cpp +++ b/src/libs/utils/networkaccessmanager.cpp @@ -29,6 +29,7 @@ #include "networkaccessmanager.h" +#include <QCoreApplication> #include <QLocale> #include <QUrl> #include <QNetworkReply> @@ -37,8 +38,6 @@ #include <sys/utsname.h> #endif -#include <app/app_version.h> - /*! \class Utils::NetworkManager @@ -130,8 +129,9 @@ void NetworkAccessManager::getUrl(const QUrl &url) QNetworkReply* NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) { - QString agentStr = QString::fromLatin1("Qt-Creator/%1 (QNetworkAccessManager %2; %3; %4; %5 bit)") - .arg(QLatin1String(Core::Constants::IDE_VERSION_LONG), + QString agentStr = QString::fromLatin1("%1/%2 (QNetworkAccessManager %3; %4; %5; %6 bit)") + .arg(QCoreApplication::applicationName(), + QCoreApplication::applicationVersion(), QLatin1String(qVersion()), getOsString(), QLocale::system().name()) .arg(QSysInfo::WordSize); diff --git a/src/libs/utils/pathlisteditor.cpp b/src/libs/utils/pathlisteditor.cpp index a51e21fba4..2eb6758159 100644 --- a/src/libs/utils/pathlisteditor.cpp +++ b/src/libs/utils/pathlisteditor.cpp @@ -29,6 +29,8 @@ #include "pathlisteditor.h" +#include "hostosinfo.h" + #include <QVBoxLayout> #include <QHBoxLayout> #include <QPlainTextEdit> @@ -91,7 +93,7 @@ void PathListPlainTextEdit::insertFromMimeData(const QMimeData *source) if (source->hasText()) { // replace separator QString text = source->text().trimmed(); - text.replace(PathListEditor::separator(), QLatin1Char('\n')); + text.replace(HostOsInfo::pathListSeparator(), QLatin1Char('\n')); QSharedPointer<QMimeData> fixed(new QMimeData); fixed->setText(text); QPlainTextEdit::insertFromMimeData(fixed.data()); @@ -187,7 +189,7 @@ int PathListEditor::lastAddActionIndex() QString PathListEditor::pathListString() const { - return pathList().join(separator()); + return pathList().join(HostOsInfo::pathListSeparator()); } QStringList PathListEditor::pathList() const @@ -213,7 +215,8 @@ void PathListEditor::setPathList(const QString &pathString) if (pathString.isEmpty()) { clear(); } else { - setPathList(pathString.split(separator(), QString::SkipEmptyParts)); + setPathList(pathString.split(HostOsInfo::pathListSeparator(), + QString::SkipEmptyParts)); } } @@ -251,16 +254,6 @@ void PathListEditor::slotInsert() insertPathAtCursor(QDir::toNativeSeparators(dir)); } -QChar PathListEditor::separator() -{ -#ifdef Q_OS_WIN - static const QChar rc(QLatin1Char(';')); -#else - static const QChar rc(QLatin1Char(':')); -#endif - return rc; -} - // Add a button "Import from 'Path'" void PathListEditor::addEnvVariableImportAction(const QString &var) { diff --git a/src/libs/utils/pathlisteditor.h b/src/libs/utils/pathlisteditor.h index b0ac66d8a4..c885f3514a 100644 --- a/src/libs/utils/pathlisteditor.h +++ b/src/libs/utils/pathlisteditor.h @@ -53,8 +53,6 @@ public: QStringList pathList() const; QString fileDialogTitle() const; - static QChar separator(); - // Add a convenience action "Import from 'Path'" (environment variable) void addEnvVariableImportAction(const QString &var); diff --git a/src/libs/utils/persistentsettings.cpp b/src/libs/utils/persistentsettings.cpp index f772e13560..b9e9e37797 100644 --- a/src/libs/utils/persistentsettings.cpp +++ b/src/libs/utils/persistentsettings.cpp @@ -29,8 +29,6 @@ #include "persistentsettings.h" -#include <app/app_version.h> - #include <utils/fileutils.h> #include <QDebug> @@ -403,8 +401,9 @@ bool PersistentSettingsWriter::write(const QVariantMap &data, QWidget *parent) c w.setAutoFormattingIndent(1); // Historical, used to be QDom. w.writeStartDocument(); w.writeDTD(QLatin1String("<!DOCTYPE ") + m_docType + QLatin1Char('>')); - w.writeComment(QString::fromAscii(" Written by Qt Creator %1, %2. "). - arg(QLatin1String(Core::Constants::IDE_VERSION_LONG), + w.writeComment(QString::fromLatin1(" Written by %1 %2, %3. "). + arg(QCoreApplication::applicationName(), + QCoreApplication::applicationVersion(), QDateTime::currentDateTime().toString(Qt::ISODate))); w.writeStartElement(ctx.qtCreatorElement); const QVariantMap::const_iterator cend = data.constEnd(); diff --git a/src/libs/utils/portlist.cpp b/src/libs/utils/portlist.cpp index 2b27dd8e4c..3f643db35f 100644 --- a/src/libs/utils/portlist.cpp +++ b/src/libs/utils/portlist.cpp @@ -116,7 +116,7 @@ private: } bool atEnd() const { return m_pos == m_portsSpec.length(); } - char nextChar() const { return m_portsSpec.at(m_pos).toAscii(); } + char nextChar() const { return m_portsSpec.at(m_pos).toLatin1(); } PortList m_portList; int m_pos; diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 4ae9afeb3b..31bb841df6 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -278,7 +278,7 @@ QStringList QtcProcess::splitArgs(const QString &_args, bool abortOnMeta, SplitE inline static bool isQuoteMeta(QChar cUnicode) { - char c = cUnicode.toAscii(); + char c = cUnicode.toLatin1(); return c == '\\' || c == '\'' || c == '"' || c == '$'; } diff --git a/src/libs/utils/savefile.cpp b/src/libs/utils/savefile.cpp index 9ffde5b505..bd6278a587 100644 --- a/src/libs/utils/savefile.cpp +++ b/src/libs/utils/savefile.cpp @@ -99,7 +99,8 @@ bool SaveFile::commit() return false; } - QString finalFileName = Utils::FileUtils::resolveSymlinks(m_finalFileName); + QString finalFileName + = FileUtils::resolveSymlinks(FileName::fromString(m_finalFileName)).toString(); QString bakname = finalFileName + QLatin1Char('~'); QFile::remove(bakname); // Kill old backup QFile::rename(finalFileName, bakname); // Backup current file diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp index 7fb0bf545b..9948def8fe 100644 --- a/src/libs/utils/stringutils.cpp +++ b/src/libs/utils/stringutils.cpp @@ -29,6 +29,8 @@ #include "stringutils.h" +#include "hostosinfo.h" + #include <QString> #include <QStringList> #include <QFileInfo> @@ -94,19 +96,17 @@ QTCREATOR_UTILS_EXPORT QString commonPath(const QStringList &files) lastSeparatorPos = common.lastIndexOf(QLatin1Char('\\')); if (lastSeparatorPos == -1) return QString(); -#ifdef Q_OS_UNIX - if (lastSeparatorPos == 0) // Unix: "/a", "/b" -> '/' + if (HostOsInfo::isAnyUnixHost() && lastSeparatorPos == 0) // Unix: "/a", "/b" -> '/' lastSeparatorPos = 1; -#endif common.truncate(lastSeparatorPos); return common; } QTCREATOR_UTILS_EXPORT QString withTildeHomePath(const QString &path) { -#ifdef Q_OS_WIN - QString outPath = path; -#else + if (HostOsInfo::isWindowsHost()) + return path; + static const QString homePath = QDir::homePath(); QFileInfo fi(QDir::cleanPath(path)); @@ -115,7 +115,6 @@ QTCREATOR_UTILS_EXPORT QString withTildeHomePath(const QString &path) outPath = QLatin1Char('~') + outPath.mid(homePath.size()); else outPath = path; -#endif return outPath; } diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index 43f0b630d4..1a7aaa3472 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -29,6 +29,8 @@ #include "stylehelper.h" +#include "hostosinfo.h" + #include <QPixmapCache> #include <QWidget> #include <QRect> @@ -68,11 +70,7 @@ QColor StyleHelper::mergedColors(const QColor &colorA, const QColor &colorB, int qreal StyleHelper::sidebarFontSize() { -#if defined(Q_OS_MAC) - return 10; -#else - return 7.5; -#endif + return HostOsInfo::isMacHost() ? 10 : 7.5; } QPalette StyleHelper::sidebarFontPalette(const QPalette &original) diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp index c7cc525f48..fe18db3706 100644 --- a/src/libs/utils/synchronousprocess.cpp +++ b/src/libs/utils/synchronousprocess.cpp @@ -28,7 +28,8 @@ ****************************************************************************/ #include "synchronousprocess.h" -#include <qtcassert.h> +#include "qtcassert.h" +#include "hostosinfo.h" #include <QDebug> #include <QTimer> @@ -598,18 +599,6 @@ bool SynchronousProcess::stopProcess(QProcess &p) // Path utilities -enum OS_Type { OS_Mac, OS_Windows, OS_Unix }; - -#ifdef Q_OS_WIN -static const OS_Type pathOS = OS_Windows; -#else -# ifdef Q_OS_MAC -static const OS_Type pathOS = OS_Mac; -# else -static const OS_Type pathOS = OS_Unix; -# endif -#endif - // Locate a binary in a directory, applying all kinds of // extensions the operating system supports. static QString checkBinary(const QDir &dir, const QString &binary) @@ -621,16 +610,18 @@ static QString checkBinary(const QDir &dir, const QString &binary) // Does the OS have some weird extension concept or does the // binary have a 3 letter extension? - if (pathOS == OS_Unix) + if (HostOsInfo::isAnyUnixHost() && !HostOsInfo::isMacHost()) return QString(); const int dotIndex = binary.lastIndexOf(QLatin1Char('.')); if (dotIndex != -1 && dotIndex == binary.size() - 4) return QString(); - switch (pathOS) { - case OS_Unix: + switch (HostOsInfo::hostOs()) { + case HostOsInfo::HostOsLinux: + case HostOsInfo::HostOsOtherUnix: + case HostOsInfo::HostOsOther: break; - case OS_Windows: { + case HostOsInfo::HostOsWindows: { static const char *windowsExtensions[] = {".cmd", ".bat", ".exe", ".com" }; // Check the Windows extensions using the order const int windowsExtensionCount = sizeof(windowsExtensions)/sizeof(const char*); @@ -641,7 +632,7 @@ static QString checkBinary(const QDir &dir, const QString &binary) } } break; - case OS_Mac: { + case HostOsInfo::HostOsMac: { // Check for Mac app folders const QFileInfo appFolder(dir.filePath(binary + QLatin1String(".app"))); if (appFolder.isDir()) { @@ -666,13 +657,13 @@ QString SynchronousProcess::locateBinary(const QString &path, const QString &bin return checkBinary(absInfo.dir(), absInfo.fileName()); // Windows finds binaries in the current directory - if (pathOS == OS_Windows) { + if (HostOsInfo::isWindowsHost()) { const QString currentDirBinary = checkBinary(QDir::current(), binary); if (!currentDirBinary.isEmpty()) return currentDirBinary; } - const QStringList paths = path.split(pathSeparator()); + const QStringList paths = path.split(HostOsInfo::pathListSeparator()); if (paths.empty()) return QString(); const QStringList::const_iterator cend = paths.constEnd(); @@ -691,11 +682,4 @@ QString SynchronousProcess::locateBinary(const QString &binary) return locateBinary(QString::fromLocal8Bit(path), binary); } -QChar SynchronousProcess::pathSeparator() -{ - if (pathOS == OS_Windows) - return QLatin1Char(';'); - return QLatin1Char(':'); -} - } // namespace Utils diff --git a/src/libs/utils/synchronousprocess.h b/src/libs/utils/synchronousprocess.h index b89605ef68..2a6f8c34f4 100644 --- a/src/libs/utils/synchronousprocess.h +++ b/src/libs/utils/synchronousprocess.h @@ -139,7 +139,6 @@ public: // and file types. static QString locateBinary(const QString &binary); static QString locateBinary(const QString &path, const QString &binary); - static QChar pathSeparator(); signals: void stdOut(const QByteArray &data, bool firstTime); diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri index a8a6dfe1b7..5335d11222 100644 --- a/src/libs/utils/utils-lib.pri +++ b/src/libs/utils/utils-lib.pri @@ -79,7 +79,8 @@ SOURCES += $$PWD/environment.cpp \ $$PWD/basetreeview.cpp \ $$PWD/qtcassert.cpp \ $$PWD/elfreader.cpp \ - $$PWD/bracematcher.cpp + $$PWD/bracematcher.cpp \ + $$PWD/proxyaction.cpp win32 { SOURCES += \ @@ -165,7 +166,9 @@ HEADERS += \ $$PWD/appmainwindow.h \ $$PWD/basetreeview.h \ $$PWD/elfreader.h \ - $$PWD/bracematcher.h + $$PWD/bracematcher.h \ + $$PWD/proxyaction.h \ + $$PWD/hostosinfo.h FORMS += $$PWD/filewizardpage.ui \ $$PWD/projectintropage.ui \ diff --git a/src/libs/utils/utils.pro b/src/libs/utils/utils.pro index 873eb0c437..9f5d56d644 100644 --- a/src/libs/utils/utils.pro +++ b/src/libs/utils/utils.pro @@ -12,12 +12,6 @@ lessThan(QT_MAJOR_VERSION, 5) { win32:include(../../private_headers.pri) } -HEADERS += \ - proxyaction.h - -SOURCES += \ - proxyaction.cpp - win32: LIBS += -luser32 # PortsGatherer win32: LIBS += -liphlpapi -lws2_32 diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index 292ae6bb68..6d93ff3ba2 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -5,12 +5,6 @@ QtcLibrary { name: "Utils" cpp.defines: base.concat(["QTCREATOR_UTILS_LIB"]) - cpp.includePaths: [ - ".", - "..", - "../..", - buildDirectory - ] Properties { condition: qbs.targetOS == "windows" @@ -30,21 +24,22 @@ QtcLibrary { Depends { name: "app_version_header" } files: [ - "filewizardpage.ui", - "newclasswidget.ui", - "projectintropage.ui", - "utils.qrc", "annotateditemdelegate.cpp", "annotateditemdelegate.h", + "appmainwindow.cpp", + "appmainwindow.h", "basetreeview.cpp", "basetreeview.h", "basevalidatinglineedit.cpp", "basevalidatinglineedit.h", "bracematcher.cpp", "bracematcher.h", + "buildablehelperlibrary.cpp", "buildablehelperlibrary.h", "changeset.cpp", "changeset.h", + "checkablemessagebox.cpp", + "checkablemessagebox.h", "classnamevalidatinglineedit.cpp", "classnamevalidatinglineedit.h", "codegeneration.cpp", @@ -54,6 +49,7 @@ QtcLibrary { "consoleprocess.cpp", "consoleprocess.h", "consoleprocess_p.h", + "crumblepath.cpp", "crumblepath.h", "detailsbutton.cpp", "detailsbutton.h", @@ -61,6 +57,7 @@ QtcLibrary { "detailswidget.h", "elfreader.cpp", "elfreader.h", + "environment.cpp", "environment.h", "environmentmodel.cpp", "environmentmodel.h", @@ -70,27 +67,31 @@ QtcLibrary { "fancylineedit.h", "fancymainwindow.cpp", "fancymainwindow.h", - "appmainwindow.h", - "appmainwindow.cpp", "fileinprojectfinder.cpp", "fileinprojectfinder.h", + "filenamevalidatinglineedit.cpp", "filenamevalidatinglineedit.h", "filesearch.cpp", "filesearch.h", "filesystemwatcher.cpp", "filesystemwatcher.h", + "fileutils.cpp", "fileutils.h", "filewizarddialog.cpp", "filewizarddialog.h", "filewizardpage.cpp", "filewizardpage.h", + "filewizardpage.ui", "filterlineedit.cpp", "filterlineedit.h", "flowlayout.cpp", "flowlayout.h", + "historycompleter.cpp", "historycompleter.h", + "hostosinfo.h", "htmldocextractor.cpp", "htmldocextractor.h", + "ipaddresslineedit.cpp", "ipaddresslineedit.h", "iwelcomepage.cpp", "iwelcomepage.h", @@ -99,11 +100,14 @@ QtcLibrary { "linecolumnlabel.cpp", "linecolumnlabel.h", "listutils.h", + "multitask.h", "navigationtreeview.cpp", "navigationtreeview.h", + "networkaccessmanager.cpp", "networkaccessmanager.h", "newclasswidget.cpp", "newclasswidget.h", + "newclasswidget.ui", "outputformat.h", "outputformatter.cpp", "outputformatter.h", @@ -111,23 +115,34 @@ QtcLibrary { "parameteraction.h", "pathchooser.cpp", "pathchooser.h", + "pathlisteditor.cpp", "pathlisteditor.h", + "persistentsettings.cpp", + "persistentsettings.h", + "portlist.cpp", + "portlist.h", "projectintropage.cpp", "projectintropage.h", + "projectintropage.ui", "projectnamevalidatinglineedit.cpp", "projectnamevalidatinglineedit.h", + "proxyaction.cpp", "proxyaction.h", - "qtcassert.h", "qtcassert.cpp", + "qtcassert.h", "qtcolorbutton.cpp", "qtcolorbutton.h", + "qtcprocess.cpp", "qtcprocess.h", "reloadpromptutils.cpp", "reloadpromptutils.h", + "runextensions.h", + "savedaction.cpp", "savedaction.h", "savefile.cpp", "savefile.h", "settingsselector.cpp", + "settingsselector.h", "settingsutils.h", "statuslabel.cpp", "statuslabel.h", @@ -135,6 +150,7 @@ QtcLibrary { "stringutils.h", "styledbar.cpp", "styledbar.h", + "stylehelper.cpp", "stylehelper.h", "submiteditorwidget.cpp", "submiteditorwidget.h", @@ -151,31 +167,10 @@ QtcLibrary { "treewidgetcolumnstretcher.h", "uncommentselection.cpp", "uncommentselection.h", + "utils.qrc", "utils_global.h", "wizard.cpp", "wizard.h", - "persistentsettings.h", - "settingsselector.h", - "buildablehelperlibrary.cpp", - "checkablemessagebox.cpp", - "checkablemessagebox.h", - "crumblepath.cpp", - "environment.cpp", - "filenamevalidatinglineedit.cpp", - "fileutils.cpp", - "historycompleter.cpp", - "ipaddresslineedit.cpp", - "networkaccessmanager.cpp", - "pathlisteditor.cpp", - "persistentsettings.cpp", - "portlist.cpp", - "portlist.h", - "proxyaction.cpp", - "qtcprocess.cpp", - "savedaction.cpp", - "stylehelper.cpp", - "multitask.h", - "runextensions.h", "images/arrow.png", "images/crumblepath-segment-end.png", "images/crumblepath-segment-hover-end.png", @@ -206,15 +201,13 @@ QtcLibrary { Group { condition: qbs.targetOS == "linux" files: [ + "unixutils.cpp", "unixutils.h", - "unixutils.cpp" ] } ProductModule { - Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["concurrent", "widgets" ] } - cpp.includePaths: [".."] } } diff --git a/src/libs/zeroconf/embeddedLib.cpp b/src/libs/zeroconf/embeddedLib.cpp index c8bdb6a624..912ac24cae 100644 --- a/src/libs/zeroconf/embeddedLib.cpp +++ b/src/libs/zeroconf/embeddedLib.cpp @@ -128,7 +128,7 @@ public: logger->appendError(ErrorMessage::NoteLevel, ZConfLib::tr("%1: log of previous daemon run is: '%2'.\n") .arg(name()) - .arg(QString::fromAscii(logBA.constData(), logBA.size()))); + .arg(QString::fromLatin1(logBA.constData(), logBA.size()))); qDebug()<<logBA.size()<<oldLog.error()<<oldLog.errorString(); } oldLog.close(); diff --git a/src/libs/zeroconf/zeroconf.qbs b/src/libs/zeroconf/zeroconf.qbs index fcc98878a1..04274fd6f6 100644 --- a/src/libs/zeroconf/zeroconf.qbs +++ b/src/libs/zeroconf/zeroconf.qbs @@ -6,8 +6,8 @@ QtcLibrary { Depends { name: "cpp" } Depends { name: "Qt.network" } + cpp.includePaths: base.concat(".") - cpp.includePaths: "." cpp.defines: base.concat("ZEROCONF_LIBRARY") Properties { @@ -26,21 +26,16 @@ QtcLibrary { } files: [ - "servicebrowser.cpp", - "servicebrowser.h", - "servicebrowser_p.h", - "embeddedLib.cpp", - "mdnsderived.cpp", - "mdnsderived.h", "avahiLib.cpp", "dnsSdLib.cpp", "dns_sd_types.h", + "embeddedLib.cpp", + "mdnsderived.cpp", + "mdnsderived.h", + "servicebrowser.cpp", + "servicebrowser.h", + "servicebrowser_p.h", + "syssocket.h", "zeroconf_global.h", - "syssocket.h" ] - - ProductModule { - Depends { name: "cpp" } - cpp.includePaths: ["."] - } } diff --git a/src/plugins/QtcPlugin.qbs b/src/plugins/QtcPlugin.qbs index 8ed4ce13c0..9b53d47e01 100644 --- a/src/plugins/QtcPlugin.qbs +++ b/src/plugins/QtcPlugin.qbs @@ -1,5 +1,6 @@ import qbs.base 1.0 import qbs.fileinfo 1.0 as FileInfo +import "../../qbs/defaults.js" as Defaults Product { type: ["dynamiclibrary", "pluginSpec"] @@ -21,16 +22,21 @@ Product { Depends { name: "pluginspec" } Depends { name: "cpp" } - cpp.defines: project.additionalCppDefines.concat([name.toUpperCase() + "_LIBRARY"]) - cpp.rpaths: ["$ORIGIN/../../.."] + Depends { + condition: Defaults.testsEnabled(qbs) + name: "Qt.test" + } + + cpp.defines: Defaults.defines(qbs).concat([name.toUpperCase() + "_LIBRARY"]) + cpp.rpaths: ["$ORIGIN/../.."] cpp.linkerFlags: { if (qbs.buildVariant == "release" && (qbs.toolchain == "gcc" || qbs.toolchain == "mingw")) return ["-Wl,-s"] } + cpp.includePaths: [ ".", ".." ] Group { files: [ product.name + ".pluginspec.in" ] fileTags: ["pluginSpecIn"] } } - diff --git a/src/plugins/analyzerbase/analyzerbase.qbs b/src/plugins/analyzerbase/analyzerbase.qbs index 7fada29a11..36a11871ed 100644 --- a/src/plugins/analyzerbase/analyzerbase.qbs +++ b/src/plugins/analyzerbase/analyzerbase.qbs @@ -17,23 +17,23 @@ QtcPlugin { "ANALYZER_LIBRARY", "QT_NO_CAST_FROM_ASCII" ]) - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] files: [ "analyzerbase.qrc", "analyzerbase_global.h", "analyzerconstants.h", + "analyzermanager.cpp", + "analyzermanager.h", "analyzeroptionspage.cpp", "analyzeroptionspage.h", "analyzerplugin.cpp", "analyzerplugin.h", "analyzerrunconfigwidget.cpp", "analyzerrunconfigwidget.h", + "analyzerruncontrol.cpp", "analyzerruncontrol.h", + "analyzerruncontrolfactory.cpp", + "analyzerruncontrolfactory.h", "analyzersettings.cpp", "analyzersettings.h", "analyzerstartparameters.h", @@ -42,23 +42,15 @@ QtcPlugin { "ianalyzerengine.cpp", "ianalyzerengine.h", "ianalyzertool.cpp", + "ianalyzertool.h", "startremotedialog.cpp", "startremotedialog.h", - "analyzermanager.cpp", - "analyzermanager.h", - "analyzerruncontrol.cpp", - "analyzerruncontrolfactory.cpp", - "analyzerruncontrolfactory.h", - "ianalyzertool.h", "images/analyzer_category.png", "images/analyzer_mode.png", - "images/analyzer_start_small.png" + "images/analyzer_start_small.png", ] ProductModule { - Depends { name: "cpp" } - cpp.includePaths: ["."] - Depends { name: "CPlusPlus" } } } diff --git a/src/plugins/analyzerbase/analyzermanager.cpp b/src/plugins/analyzerbase/analyzermanager.cpp index 7434846208..54dcf858fd 100644 --- a/src/plugins/analyzerbase/analyzermanager.cpp +++ b/src/plugins/analyzerbase/analyzermanager.cpp @@ -88,6 +88,7 @@ #include <QLabel> #include <QCheckBox> #include <QDialogButtonBox> +#include <QPointer> #include <QPushButton> using namespace Core; @@ -211,7 +212,7 @@ public: MainWindowSettingsMap m_defaultSettings; // list of dock widgets to prevent memory leak - typedef QWeakPointer<QDockWidget> DockPtr; + typedef QPointer<QDockWidget> DockPtr; QList<DockPtr> m_dockWidgets; }; @@ -235,8 +236,6 @@ AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager *qq): setupActions(); - connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)), - this, SLOT(modeChanged(Core::IMode*))); ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance(); connect(pe, SIGNAL(updateRunActions()), SLOT(updateRunActions())); } @@ -294,6 +293,9 @@ void AnalyzerManagerPrivate::delayedInit() m_mode = new AnalyzerMode(q); createModeMainWindow(); + connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)), + this, SLOT(modeChanged(Core::IMode*))); + // Right-side window with editor, output etc. MiniSplitter *mainWindowSplitter = new MiniSplitter; mainWindowSplitter->addWidget(m_mainWindow); diff --git a/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp b/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp index f4faaa79a9..4ee4793af2 100644 --- a/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp +++ b/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp @@ -89,6 +89,14 @@ IRunConfigurationAspect *AnalyzerRunControlFactory::createRunConfigurationAspect return new AnalyzerRunConfigurationAspect; } +IRunConfigurationAspect *AnalyzerRunControlFactory::cloneRunConfigurationAspect(IRunConfigurationAspect *source) +{ + AnalyzerRunConfigurationAspect *s = dynamic_cast<AnalyzerRunConfigurationAspect *>(source); + if (!s) + return 0; + return new AnalyzerRunConfigurationAspect(s); +} + RunConfigWidget *AnalyzerRunControlFactory::createConfigurationWidget(RunConfiguration *runConfiguration) { AnalyzerRunConfigWidget *ret = new AnalyzerRunConfigWidget; diff --git a/src/plugins/analyzerbase/analyzerruncontrolfactory.h b/src/plugins/analyzerbase/analyzerruncontrolfactory.h index 31bcde9bb8..cfc09339b9 100644 --- a/src/plugins/analyzerbase/analyzerruncontrolfactory.h +++ b/src/plugins/analyzerbase/analyzerruncontrolfactory.h @@ -51,6 +51,7 @@ public: ProjectExplorer::RunMode mode, QString *errorMessage); ProjectExplorer::IRunConfigurationAspect *createRunConfigurationAspect(); + ProjectExplorer::IRunConfigurationAspect *cloneRunConfigurationAspect(ProjectExplorer::IRunConfigurationAspect *source); ProjectExplorer::RunConfigWidget *createConfigurationWidget(RunConfiguration *runConfiguration); }; diff --git a/src/plugins/analyzerbase/analyzersettings.cpp b/src/plugins/analyzerbase/analyzersettings.cpp index d612a6223e..c33077eeef 100644 --- a/src/plugins/analyzerbase/analyzersettings.cpp +++ b/src/plugins/analyzerbase/analyzersettings.cpp @@ -54,6 +54,11 @@ AnalyzerSettings::AnalyzerSettings(QObject *parent) { } +AnalyzerSettings::AnalyzerSettings(AnalyzerSettings *other) +{ + Q_UNUSED(other); +} + QVariantMap AnalyzerSettings::defaults() const { QVariantMap map; @@ -148,8 +153,8 @@ void AnalyzerGlobalSettings::registerTool(IAnalyzerTool *tool) } -AnalyzerRunConfigurationAspect::AnalyzerRunConfigurationAspect(QObject *parent) - : AnalyzerSettings(parent), m_useGlobalSettings(true) +AnalyzerRunConfigurationAspect::AnalyzerRunConfigurationAspect() + : AnalyzerSettings((QObject *)0), m_useGlobalSettings(true) { QList<IAnalyzerTool*> tools = AnalyzerManager::tools(); // add sub configs @@ -163,6 +168,19 @@ AnalyzerRunConfigurationAspect::AnalyzerRunConfigurationAspect(QObject *parent) resetCustomToGlobalSettings(); } +AnalyzerRunConfigurationAspect::AnalyzerRunConfigurationAspect(AnalyzerRunConfigurationAspect *other) + : AnalyzerSettings(other), m_useGlobalSettings(other->m_useGlobalSettings) +{ + + foreach (AbstractAnalyzerSubConfig *config, other->m_customConfigurations) + m_customConfigurations.append(config->clone()); + + if (m_useGlobalSettings) + m_subConfigs = AnalyzerGlobalSettings::instance()->subConfigs(); + else + m_subConfigs = m_customConfigurations; +} + AnalyzerRunConfigurationAspect::~AnalyzerRunConfigurationAspect() { qDeleteAll(m_customConfigurations); diff --git a/src/plugins/analyzerbase/analyzersettings.h b/src/plugins/analyzerbase/analyzersettings.h index 415c3e9cd2..1b7c3eb3c2 100644 --- a/src/plugins/analyzerbase/analyzersettings.h +++ b/src/plugins/analyzerbase/analyzersettings.h @@ -78,6 +78,8 @@ public: virtual QString displayName() const = 0; /// create a configuration widget for this configuration virtual QWidget *createConfigWidget(QWidget *parent) = 0; + /// clones s AbstractAnalyzerSubConfig + virtual AbstractAnalyzerSubConfig *clone() = 0; }; /** @@ -115,6 +117,7 @@ protected: void fromMap(const QVariantMap &map, QList<AbstractAnalyzerSubConfig *> *subConfigs); AnalyzerSettings(QObject *parent); + AnalyzerSettings(AnalyzerSettings *other); QList<AbstractAnalyzerSubConfig *> m_subConfigs; }; @@ -162,7 +165,8 @@ class ANALYZER_EXPORT AnalyzerRunConfigurationAspect Q_OBJECT public: - AnalyzerRunConfigurationAspect(QObject *parent = 0); + AnalyzerRunConfigurationAspect(); + AnalyzerRunConfigurationAspect(AnalyzerRunConfigurationAspect *other); ~AnalyzerRunConfigurationAspect(); QString displayName() const; diff --git a/src/plugins/analyzerbase/ianalyzertool.cpp b/src/plugins/analyzerbase/ianalyzertool.cpp index 8ce961c691..2f98593339 100644 --- a/src/plugins/analyzerbase/ianalyzertool.cpp +++ b/src/plugins/analyzerbase/ianalyzertool.cpp @@ -42,8 +42,8 @@ IAnalyzerTool::IAnalyzerTool(QObject *parent) Id IAnalyzerTool::defaultMenuGroup(StartMode mode) { if (mode == StartRemote) - return Constants::G_ANALYZER_REMOTE_TOOLS; - return Constants::G_ANALYZER_TOOLS; + return Id(Constants::G_ANALYZER_REMOTE_TOOLS); + return Id(Constants::G_ANALYZER_TOOLS); } Id IAnalyzerTool::defaultActionId(const IAnalyzerTool *tool, StartMode mode) @@ -51,11 +51,11 @@ Id IAnalyzerTool::defaultActionId(const IAnalyzerTool *tool, StartMode mode) Id id = tool->id(); switch (mode) { case StartLocal: - return Id(QByteArray("Analyzer." + id.name() + ".Local").data()); + return Id(QByteArray("Analyzer." + id.name() + ".Local")); case StartRemote: - return Id(QByteArray("Analyzer." + id.name() + ".Remote").data()); + return Id(QByteArray("Analyzer." + id.name() + ".Remote")); case StartQml: - return Id(QByteArray("Analyzer." + id.name() + ".Qml").data()); + return Id(QByteArray("Analyzer." + id.name() + ".Qml")); } return Id(); } diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs index d719b78309..bd2a2e83dd 100644 --- a/src/plugins/android/android.qbs +++ b/src/plugins/android/android.qbs @@ -15,15 +15,11 @@ QtcPlugin { property bool enable: false property var pluginspecreplacements: ({"ANDROID_EXPERIMENTAL_STR": (enable ? "false": "true")}) - cpp.includePaths: [ - "..", - buildDirectory, - "../../libs", - "../../shared" - ] + cpp.includePaths: base.concat("../../shared") files: [ "addnewavddialog.ui", + "android.qrc", "androidconfigurations.cpp", "androidconfigurations.h", "androidconstants.h", @@ -35,9 +31,9 @@ QtcPlugin { "androiddeployconfiguration.cpp", "androiddeployconfiguration.h", "androiddeploystep.cpp", + "androiddeploystep.h", "androiddeploystepfactory.cpp", "androiddeploystepfactory.h", - "androiddeploystep.h", "androiddeploystepwidget.cpp", "androiddeploystepwidget.h", "androiddeploystepwidget.ui", @@ -46,8 +42,8 @@ QtcPlugin { "androiddevicefactory.cpp", "androiddevicefactory.h", "androidglobal.h", - "androidmanager.h", "androidmanager.cpp", + "androidmanager.h", "androidpackagecreationfactory.cpp", "androidpackagecreationfactory.h", "androidpackagecreationstep.cpp", @@ -61,11 +57,10 @@ QtcPlugin { "androidpackageinstallationstep.h", "androidplugin.cpp", "androidplugin.h", - "android.qrc", "androidqtversion.cpp", + "androidqtversion.h", "androidqtversionfactory.cpp", "androidqtversionfactory.h", - "androidqtversion.h", "androidrunconfiguration.cpp", "androidrunconfiguration.h", "androidruncontrol.cpp", @@ -82,6 +77,6 @@ QtcPlugin { "androidtoolchain.cpp", "androidtoolchain.h", "javaparser.cpp", - "javaparser.h" + "javaparser.h", ] } diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 8f2bbe063f..57f75dc526 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -32,6 +32,7 @@ #include "ui_addnewavddialog.h" #include <coreplugin/icore.h> +#include <utils/hostosinfo.h> #include <utils/persistentsettings.h> #include <QDateTime> @@ -262,24 +263,24 @@ QStringList AndroidConfigurations::ndkToolchainVersions() const FileName AndroidConfigurations::adbToolPath() const { FileName path = m_config.sdkLocation; - return path.appendPath(QLatin1String("platform-tools/adb" ANDROID_EXE_SUFFIX)); + return path.appendPath(QLatin1String("platform-tools/adb" QTC_HOST_EXE_SUFFIX)); } FileName AndroidConfigurations::androidToolPath() const { -#ifdef Q_OS_WIN32 - // I want to switch from using android.bat to using an executable. All it really does is call - // Java and I've made some progress on it. So if android.exe exists, return that instead. - FileName path = m_config.sdkLocation; - path.appendPath(QLatin1String("tools/android"ANDROID_EXE_SUFFIX)); - if (path.toFileInfo().exists()) - return path; - path = m_config.sdkLocation; - return path.appendPath(QLatin1String("tools/android"ANDROID_BAT_SUFFIX)); -#else - FileName path = m_config.sdkLocation; - return path.appendPath(QLatin1String("tools/android")); -#endif + if (HostOsInfo::isWindowsHost()) { + // I want to switch from using android.bat to using an executable. All it really does is call + // Java and I've made some progress on it. So if android.exe exists, return that instead. + FileName path = m_config.sdkLocation; + path.appendPath(QLatin1String("tools/android" QTC_HOST_EXE_SUFFIX)); + if (path.toFileInfo().exists()) + return path; + path = m_config.sdkLocation; + return path.appendPath(QLatin1String("tools/android" ANDROID_BAT_SUFFIX)); + } else { + FileName path = m_config.sdkLocation; + return path.appendPath(QLatin1String("tools/android")); + } } FileName AndroidConfigurations::antToolPath() const @@ -293,7 +294,7 @@ FileName AndroidConfigurations::antToolPath() const FileName AndroidConfigurations::emulatorToolPath() const { FileName path = m_config.sdkLocation; - return path.appendPath(QLatin1String("tools/emulator" ANDROID_EXE_SUFFIX)); + return path.appendPath(QLatin1String("tools/emulator" QTC_HOST_EXE_SUFFIX)); } FileName AndroidConfigurations::toolPath(Abi::Architecture architecture) const @@ -308,17 +309,17 @@ FileName AndroidConfigurations::toolPath(Abi::Architecture architecture) const FileName AndroidConfigurations::stripPath(Abi::Architecture architecture) const { - return toolPath(architecture).append(QLatin1String("-strip" ANDROID_EXE_SUFFIX)); + return toolPath(architecture).append(QLatin1String("-strip" QTC_HOST_EXE_SUFFIX)); } FileName AndroidConfigurations::readelfPath(Abi::Architecture architecture) const { - return toolPath(architecture).append(QLatin1String("-readelf" ANDROID_EXE_SUFFIX)); + return toolPath(architecture).append(QLatin1String("-readelf" QTC_HOST_EXE_SUFFIX)); } FileName AndroidConfigurations::gccPath(Abi::Architecture architecture) const { - return toolPath(architecture).append(QLatin1String("-gcc" ANDROID_EXE_SUFFIX)); + return toolPath(architecture).append(QLatin1String("-gcc" QTC_HOST_EXE_SUFFIX)); } FileName AndroidConfigurations::gdbServerPath(Abi::Architecture architecture) const @@ -360,7 +361,7 @@ FileName AndroidConfigurations::gdbPath(Abi::Architecture architecture) const } if (!gdbPath.isEmpty()) return gdbPath; - return toolPath(architecture).append(QLatin1String("-gdb" ANDROID_EXE_SUFFIX)); + return toolPath(architecture).append(QLatin1String("-gdb" QTC_HOST_EXE_SUFFIX)); } FileName AndroidConfigurations::openJDKPath() const @@ -389,7 +390,7 @@ FileName AndroidConfigurations::jarsignerPath() const FileName AndroidConfigurations::zipalignPath() const { Utils::FileName path = m_config.sdkLocation; - return path.appendPath(QLatin1String("tools/zipalign" ANDROID_EXE_SUFFIX)); + return path.appendPath(QLatin1String("tools/zipalign" QTC_HOST_EXE_SUFFIX)); } QString AndroidConfigurations::getDeployDeviceSerialNumber(int *apiLevel) const diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h index ab80f48c7d..0d610bf352 100644 --- a/src/plugins/android/androidconstants.h +++ b/src/plugins/android/androidconstants.h @@ -44,10 +44,8 @@ enum AndroidQemuStatus { }; #ifdef Q_OS_WIN32 -#define ANDROID_EXE_SUFFIX ".exe" #define ANDROID_BAT_SUFFIX ".bat" #else -#define ANDROID_EXE_SUFFIX "" #define ANDROID_BAT_SUFFIX "" #endif diff --git a/src/plugins/android/androiddeployconfiguration.cpp b/src/plugins/android/androiddeployconfiguration.cpp index d93d1976e9..69f741c278 100644 --- a/src/plugins/android/androiddeployconfiguration.cpp +++ b/src/plugins/android/androiddeployconfiguration.cpp @@ -56,6 +56,7 @@ AndroidDeployConfiguration::AndroidDeployConfiguration(Target *parent, Core::Id AndroidDeployConfiguration::AndroidDeployConfiguration(Target *parent, DeployConfiguration *source) : DeployConfiguration(parent, source) { + cloneSteps(source); } AndroidDeployConfigurationFactory::AndroidDeployConfigurationFactory(QObject *parent) diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index e20af13e0f..926fa395f5 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -106,7 +106,7 @@ bool AndroidManager::setPackageName(ProjectExplorer::Target *target, const QStri QString AndroidManager::applicationName(ProjectExplorer::Target *target) { QDomDocument doc; - if (!openXmlFile(target, doc, stringsPath(target))) + if (!openXmlFile(doc, stringsPath(target))) return QString(); QDomElement metadataElem = doc.documentElement().firstChildElement(QLatin1String("string")); while (!metadataElem.isNull()) { @@ -121,7 +121,7 @@ bool AndroidManager::setApplicationName(ProjectExplorer::Target *target, const Q { QDomDocument doc; Utils::FileName path = stringsPath(target); - if (!openXmlFile(target, doc, path)) + if (!openXmlFile(doc, path)) return false; QDomElement metadataElem = doc.documentElement().firstChildElement(QLatin1String("string")); while (!metadataElem.isNull()) { @@ -403,11 +403,11 @@ bool AndroidManager::createAndroidTemplatesIfNecessary(ProjectExplorer::Target * QDomDocument srcVersionDoc; Utils::FileName srcVersionPath = javaSrcPath; srcVersionPath.appendPath(QLatin1String("version.xml")); - if (openXmlFile(target, srcVersionDoc, srcVersionPath, false)) { + if (openXmlFile(srcVersionDoc, srcVersionPath)) { QDomDocument dstVersionDoc; Utils::FileName dstVersionPath=androidPath; dstVersionPath.appendPath(QLatin1String("version.xml")); - if (openXmlFile(target, dstVersionDoc, dstVersionPath, false)) + if (openXmlFile(dstVersionDoc, dstVersionPath)) forceUpdate = (srcVersionDoc.documentElement().attribute(QLatin1String("value")).toDouble() > dstVersionDoc.documentElement().attribute(QLatin1String("value")).toDouble()); else @@ -674,7 +674,7 @@ bool AndroidManager::setPrebundledLibs(ProjectExplorer::Target *target, const QS bool AndroidManager::openLibsXml(ProjectExplorer::Target *target, QDomDocument &doc) { - return openXmlFile(target, doc, libsPath(target)); + return openXmlFile(doc, libsPath(target)); } bool AndroidManager::saveLibsXml(ProjectExplorer::Target *target, QDomDocument &doc) @@ -698,7 +698,7 @@ QString AndroidManager::loadLocal(ProjectExplorer::Target *target, int apiLevel, QString localLibs; QDomDocument doc; - if (!openXmlFile(target, doc, localLibsRulesFilePath(target))) + if (!openXmlFile(doc, localLibsRulesFilePath(target))) return localLibs; QStringList libs; @@ -733,12 +733,8 @@ QString AndroidManager::loadLocal(ProjectExplorer::Target *target, int apiLevel, return localLibs; } -bool AndroidManager::openXmlFile(ProjectExplorer::Target *target, QDomDocument &doc, - const Utils::FileName &fileName, bool createAndroidTemplates) +bool AndroidManager::openXmlFile(QDomDocument &doc, const Utils::FileName &fileName) { - if (createAndroidTemplates && !createAndroidTemplatesIfNecessary(target)) - return false; - QFile f(fileName.toString()); if (!f.open(QIODevice::ReadOnly)) return false; @@ -765,7 +761,7 @@ bool AndroidManager::saveXmlFile(ProjectExplorer::Target *target, QDomDocument & bool AndroidManager::openManifest(ProjectExplorer::Target *target, QDomDocument &doc) { - return openXmlFile(target, doc, manifestPath(target)); + return openXmlFile(doc, manifestPath(target)); } bool AndroidManager::saveManifest(ProjectExplorer::Target *target, QDomDocument &doc) diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index fca07ea35b..cd22b1d7fd 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -113,8 +113,7 @@ public: private: static void raiseError(const QString &reason); - static bool openXmlFile(ProjectExplorer::Target *target, QDomDocument &doc, - const Utils::FileName &fileName, bool createAndroidTemplates = false); + static bool openXmlFile(QDomDocument &doc, const Utils::FileName &fileName); static bool saveXmlFile(ProjectExplorer::Target *target, QDomDocument &doc, const Utils::FileName &fileName); static bool openManifest(ProjectExplorer::Target *target, QDomDocument &doc); static bool saveManifest(ProjectExplorer::Target *target, QDomDocument &doc); diff --git a/src/plugins/android/androidpackagecreationstep.h b/src/plugins/android/androidpackagecreationstep.h index 1201bdc981..d8cf6768c5 100644 --- a/src/plugins/android/androidpackagecreationstep.h +++ b/src/plugins/android/androidpackagecreationstep.h @@ -41,10 +41,6 @@ QT_BEGIN_NAMESPACE class QProcess; QT_END_NAMESPACE -namespace Qt4ProjectManager { -class Qt4BuildConfiguration; -} - namespace Android { namespace Internal { diff --git a/src/plugins/android/androidpackagecreationwidget.cpp b/src/plugins/android/androidpackagecreationwidget.cpp index badfe63d30..9b5aaf7b9f 100644 --- a/src/plugins/android/androidpackagecreationwidget.cpp +++ b/src/plugins/android/androidpackagecreationwidget.cpp @@ -147,8 +147,9 @@ PermissionsModel::PermissionsModel(QObject *parent) void PermissionsModel::setPermissions(const QStringList &permissions) { + beginResetModel(); m_permissions = permissions; - reset(); + endResetModel(); } const QStringList &PermissionsModel::permissions() diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index 57439c857d..6339386d1f 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -84,7 +84,7 @@ void AndroidRunner::checkPID() qint64 pid = -1; QList<QByteArray> procs = psProc.readAll().split('\n'); foreach (const QByteArray &proc, procs) { - if (proc.trimmed().endsWith(m_packageName.toAscii())) { + if (proc.trimmed().endsWith(m_packageName.toLatin1())) { QRegExp rx(QLatin1String("(\\d+)")); if (rx.indexIn(QLatin1String(proc), proc.indexOf(' ')) > 0) { pid = rx.cap(1).toLongLong(); @@ -258,7 +258,7 @@ void AndroidRunner::logcatReadStandardOutput() m_logcat += m_adbLogcatProcess.readAllStandardOutput(); bool keepLastLine = m_logcat.endsWith('\n'); QByteArray line; - QByteArray pid(QString::fromLatin1("%1):").arg(m_processPID).toAscii()); + QByteArray pid(QString::fromLatin1("%1):").arg(m_processPID).toLatin1()); foreach (line, m_logcat.split('\n')) { if (!line.contains(pid)) continue; diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index b77f821e96..4590fb894c 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -35,6 +35,8 @@ #include "androidconstants.h" +#include <utils/hostosinfo.h> + #include <QFile> #include <QTextStream> #include <QProcess> @@ -48,8 +50,9 @@ namespace Internal { void AvdModel::setAvdList(const QVector<AndroidDeviceInfo> &list) { + beginResetModel(); m_list = list; - reset(); + endResetModel(); } QString AvdModel::avdName(const QModelIndex &index) @@ -187,10 +190,10 @@ bool AndroidSettingsWidget::checkSDK(const Utils::FileName &location) Utils::FileName androidExe = location; Utils::FileName androidBat = location; Utils::FileName emulator = location; - if (!adb.appendPath(QLatin1String("platform-tools/adb" ANDROID_EXE_SUFFIX)).toFileInfo().exists() - || (!androidExe.appendPath(QLatin1String("/tools/android" ANDROID_EXE_SUFFIX)).toFileInfo().exists() + if (!adb.appendPath(QLatin1String("platform-tools/adb" QTC_HOST_EXE_SUFFIX)).toFileInfo().exists() + || (!androidExe.appendPath(QLatin1String("/tools/android" QTC_HOST_EXE_SUFFIX)).toFileInfo().exists() && !androidBat.appendPath(QLatin1String("/tools/android" ANDROID_BAT_SUFFIX)).toFileInfo().exists()) - || !emulator.appendPath(QLatin1String("/tools/emulator" ANDROID_EXE_SUFFIX)).toFileInfo().exists()) { + || !emulator.appendPath(QLatin1String("/tools/emulator" QTC_HOST_EXE_SUFFIX)).toFileInfo().exists()) { QMessageBox::critical(this, tr("Android SDK Folder"), tr("\"%1\" does not seem to be an Android SDK top folder.").arg(location.toUserOutput())); return false; } @@ -335,16 +338,15 @@ void AndroidSettingsWidget::browseNDKLocation() void AndroidSettingsWidget::browseAntLocation() { - QString dir = QDir::homePath(); -#if defined(Q_OS_LINUX) || defined(Q_OS_MAC) - dir = QLatin1String("/usr/bin/ant"); - QLatin1String antApp("ant"); -#elif defined(Q_OS_WIN) - QLatin1String antApp("ant.bat"); -#elif defined(Q_OS_DARWIN) - dir = QLatin1String("/opt/local/bin/ant"); - QLatin1String antApp("ant"); -#endif + QString dir; + QString antApp; + if (Utils::HostOsInfo::isWindowsHost()) { + dir = QDir::homePath(); + antApp = QLatin1String("ant.bat"); + } else { + dir = QLatin1String("/usr/bin/ant"); + antApp = QLatin1String("ant"); + } const QString file = QFileDialog::getOpenFileName(this, tr("Select ant Script"), dir, antApp); if (!file.length()) diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index 98022b5377..ecc83bb407 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -41,6 +41,7 @@ #include <qtsupport/qtversionmanager.h> #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <QDir> #include <QFormLayout> @@ -52,6 +53,7 @@ namespace Internal { using namespace ProjectExplorer; using namespace Qt4ProjectManager; +using namespace Utils; static const char ANDROID_QT_VERSION_KEY[] = "Qt4ProjectManager.Android.QtVersion"; @@ -84,7 +86,7 @@ bool AndroidToolChain::isValid() const return GccToolChain::isValid() && m_qtVersionId >= 0 && targetAbi().isValid(); } -void AndroidToolChain::addToEnvironment(Utils::Environment &env) const +void AndroidToolChain::addToEnvironment(Environment &env) const { // TODO this vars should be configurable in projects -> build tab @@ -95,18 +97,23 @@ void AndroidToolChain::addToEnvironment(Utils::Environment &env) const || QtSupport::QtKitInformation::qtVersion(qt4pro->activeTarget()->kit())->type() != QLatin1String(Constants::ANDROIDQT)) return; - QString ndk_host = QLatin1String( -#if defined(Q_OS_LINUX) - "linux-x86" -#elif defined(Q_OS_WIN) - "windows" -#elif defined(Q_OS_MAC) - "darwin-x86" -#endif - ); + QString ndkHost; + switch (HostOsInfo::hostOs()) { + case HostOsInfo::HostOsLinux: + ndkHost = QLatin1String("linux-x86"); + break; + case HostOsInfo::HostOsWindows: + ndkHost = QLatin1String("windows"); + break; + case HostOsInfo::HostOsMac: + ndkHost = QLatin1String("darwin-x86"); + break; + default: + break; + } // this env vars are used by qmake mkspecs to generate makefiles (check QTDIR/mkspecs/android-g++/qmake.conf for more info) - env.set(QLatin1String("ANDROID_NDK_HOST"), ndk_host); + env.set(QLatin1String("ANDROID_NDK_HOST"), ndkHost); env.set(QLatin1String("ANDROID_NDK_ROOT"), AndroidConfigurations::instance().config().ndkLocation.toUserOutput()); env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_PREFIX"), AndroidConfigurations::toolchainPrefix(targetAbi().architecture())); env.set(QLatin1String("ANDROID_NDK_TOOLS_PREFIX"), AndroidConfigurations::toolsPrefix(targetAbi().architecture())); @@ -146,18 +153,15 @@ bool AndroidToolChain::fromMap(const QVariantMap &data) return isValid(); } -QList<Utils::FileName> AndroidToolChain::suggestedMkspecList() const +QList<FileName> AndroidToolChain::suggestedMkspecList() const { - return QList<Utils::FileName>()<< Utils::FileName::fromString(QLatin1String("android-g++")); + return QList<FileName>()<< FileName::fromString(QLatin1String("android-g++")); } QString AndroidToolChain::makeCommand(const Utils::Environment &env) const { -#if defined(Q_OS_WIN) - QString make = QLatin1String("ma-make.exe"); -#else - QString make = QLatin1String("make"); -#endif + QString make = HostOsInfo::isWindowsHost() + ? QLatin1String("ma-make.exe") : QLatin1String("make"); QString tmp = env.searchInPath(make); return tmp.isEmpty() ? make : tmp; } diff --git a/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in b/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in index 46b437c7a0..015401690c 100644 --- a/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in +++ b/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in @@ -1,17 +1,15 @@ <plugin name=\"AutotoolsProjectManager\" version=\"$$QTCREATOR_VERSION\" compatVersion=\"$$QTCREATOR_VERSION\" experimental=\"true\"> <vendor>Openismus GmbH</vendor> <copyright>(C) 2012 Openismus GmbH</copyright> - <license>GNU Lesser General Public License Usage - This file may be used under the terms of the GNU Lesser General Public - License version 2.1 as published by the Free Software Foundation and - appearing in the file LICENSE.LGPL included in the packaging of this file. - Please review the following information to ensure the GNU Lesser General - Public License version 2.1 requirements will be met: - http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + <license> +Commercial Usage - In addition, as a special exception, Digia gives you certain additional - rights. These rights are described in the Digia Qt LGPL Exception - version 1.1, included in the file LGPL_EXCEPTION.txt in this package.</license> +Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and Digia. + +GNU Lesser General Public License Usage + +Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + </license> <category>Build Systems</category> <description>Autotools project integration.</description> <url>http://www.qt-project.org</url> diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.cpp b/src/plugins/autotoolsprojectmanager/autogenstep.cpp index 373660d3b5..cf0b03ff57 100644 --- a/src/plugins/autotoolsprojectmanager/autogenstep.cpp +++ b/src/plugins/autotoolsprojectmanager/autogenstep.cpp @@ -151,14 +151,9 @@ void AutogenStep::ctor() setDefaultDisplayName(tr("Autogen")); } -AutotoolsBuildConfiguration *AutogenStep::autotoolsBuildConfiguration() const -{ - return static_cast<AutotoolsBuildConfiguration *>(buildConfiguration()); -} - bool AutogenStep::init() { - AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + BuildConfiguration *bc = buildConfiguration(); ProcessParameters *pp = processParameters(); pp->setMacroExpander(bc->macroExpander()); @@ -172,7 +167,7 @@ bool AutogenStep::init() void AutogenStep::run(QFutureInterface<bool> &interface) { - AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + BuildConfiguration *bc = buildConfiguration(); // Check whether we need to run autogen.sh const QFileInfo configureInfo(bc->buildDirectory() + QLatin1String("/configure")); @@ -273,7 +268,7 @@ QString AutogenStepConfigWidget::summaryText() const void AutogenStepConfigWidget::updateDetails() { - AutotoolsBuildConfiguration *bc = m_autogenStep->autotoolsBuildConfiguration(); + BuildConfiguration *bc = m_autogenStep->buildConfiguration(); ProcessParameters param; param.setMacroExpander(bc->macroExpander()); diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.h b/src/plugins/autotoolsprojectmanager/autogenstep.h index eb9302b305..f95010eb56 100644 --- a/src/plugins/autotoolsprojectmanager/autogenstep.h +++ b/src/plugins/autotoolsprojectmanager/autogenstep.h @@ -42,7 +42,6 @@ namespace AutotoolsProjectManager { namespace Internal { class AutotoolsProject; -class AutotoolsBuildConfiguration; class AutogenStep; class AutogenStepConfigWidget; @@ -96,7 +95,6 @@ class AutogenStep : public ProjectExplorer::AbstractProcessStep public: AutogenStep(ProjectExplorer::BuildStepList *bsl); - AutotoolsBuildConfiguration *autotoolsBuildConfiguration() const; bool init(); void run(QFutureInterface<bool> &interface); ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp index 11e14c3d9d..421b60f979 100644 --- a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp +++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp @@ -150,14 +150,9 @@ void AutoreconfStep::ctor() setDefaultDisplayName(tr("Autoreconf")); } -AutotoolsBuildConfiguration *AutoreconfStep::autotoolsBuildConfiguration() const -{ - return static_cast<AutotoolsBuildConfiguration *>(buildConfiguration()); -} - bool AutoreconfStep::init() { - AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + BuildConfiguration *bc = buildConfiguration(); ProcessParameters *pp = processParameters(); pp->setMacroExpander(bc->macroExpander()); @@ -171,7 +166,7 @@ bool AutoreconfStep::init() void AutoreconfStep::run(QFutureInterface<bool> &interface) { - AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + BuildConfiguration *bc = buildConfiguration(); // Check whether we need to run autoreconf const QFileInfo configureInfo(bc->buildDirectory() + QLatin1String("/configure")); @@ -267,7 +262,7 @@ QString AutoreconfStepConfigWidget::summaryText() const void AutoreconfStepConfigWidget::updateDetails() { - AutotoolsBuildConfiguration *bc = m_autoreconfStep->autotoolsBuildConfiguration(); + BuildConfiguration *bc = m_autoreconfStep->buildConfiguration(); ProcessParameters param; param.setMacroExpander(bc->macroExpander()); diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.h b/src/plugins/autotoolsprojectmanager/autoreconfstep.h index d22d2dfabe..1675e78d24 100644 --- a/src/plugins/autotoolsprojectmanager/autoreconfstep.h +++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.h @@ -42,7 +42,6 @@ namespace AutotoolsProjectManager { namespace Internal { class AutotoolsProject; -class AutotoolsBuildConfiguration; class AutoreconfStep; //////////////////////////////// @@ -96,7 +95,6 @@ class AutoreconfStep : public ProjectExplorer::AbstractProcessStep public: AutoreconfStep(ProjectExplorer::BuildStepList *bsl); - AutotoolsBuildConfiguration *autotoolsBuildConfiguration() const; bool init(); void run(QFutureInterface<bool> &interface); ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp index 7508d9ddeb..e7194452e4 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp @@ -65,9 +65,9 @@ AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(ProjectExplorer::Target m_buildDirectory = project->defaultBuildDirectory(); } -BuildConfigWidget *AutotoolsBuildConfiguration::createConfigWidget() +NamedWidget *AutotoolsBuildConfiguration::createConfigWidget() { - return new AutotoolsBuildSettingsWidget; + return new AutotoolsBuildSettingsWidget(this); } AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(ProjectExplorer::Target *parent, const Core::Id id) @@ -112,14 +112,6 @@ void AutotoolsBuildConfiguration::setBuildDirectory(const QString &buildDirector emit buildDirectoryChanged(); } -IOutputParser *AutotoolsBuildConfiguration::createOutputParser() const -{ - ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(target()->kit()); - if (tc) - return tc->outputParser(); - return 0; -} - ////////////////////////////////////// // AutotoolsBuildConfiguration class ////////////////////////////////////// diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h index 2ef889d5f5..e7a622adb8 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h @@ -48,12 +48,11 @@ class AutotoolsBuildConfiguration : public ProjectExplorer::BuildConfiguration public: explicit AutotoolsBuildConfiguration(ProjectExplorer::Target *parent); - ProjectExplorer::BuildConfigWidget *createConfigWidget(); + ProjectExplorer::NamedWidget *createConfigWidget(); QString buildDirectory() const; void setBuildDirectory(const QString &buildDirectory); QVariantMap toMap() const; - ProjectExplorer::IOutputParser *createOutputParser() const; BuildType buildType() const; protected: diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.cpp index fa7c262e04..2d7c69053d 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.cpp @@ -49,7 +49,7 @@ using namespace AutotoolsProjectManager; using namespace AutotoolsProjectManager::Internal; using namespace ProjectExplorer; -AutotoolsBuildSettingsWidget::AutotoolsBuildSettingsWidget() : +AutotoolsBuildSettingsWidget::AutotoolsBuildSettingsWidget(AutotoolsBuildConfiguration *bc) : m_buildConfiguration(0) { QFormLayout *fl = new QFormLayout(this); @@ -61,18 +61,10 @@ AutotoolsBuildSettingsWidget::AutotoolsBuildSettingsWidget() : m_pathChooser->setExpectedKind(Utils::PathChooser::Directory); fl->addRow(tr("Build directory:"), m_pathChooser); connect(m_pathChooser, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged())); -} -QString AutotoolsBuildSettingsWidget::displayName() const -{ - return QLatin1String("Autotools Manager"); -} - -void AutotoolsBuildSettingsWidget::init(BuildConfiguration *bc) -{ - m_buildConfiguration = static_cast<AutotoolsBuildConfiguration *>(bc); m_pathChooser->setBaseDirectory(bc->target()->project()->projectDirectory()); m_pathChooser->setPath(m_buildConfiguration->buildDirectory()); + setDisplayName(tr("Autotools Manager")); } void AutotoolsBuildSettingsWidget::buildDirectoryChanged() diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.h index 6b4c0a3faf..d2c4dbcf22 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.h +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.h @@ -32,7 +32,7 @@ #ifndef AUTOTOOLSBUILDSETTINGSWIDGET_H #define AUTOTOOLSBUILDSETTINGSWIDGET_H -#include <projectexplorer/buildstep.h> +#include <projectexplorer/namedwidget.h> QT_BEGIN_NAMESPACE class QComboBox; @@ -52,15 +52,12 @@ class AutotoolsBuildConfiguration; * * Provides an editor to configure the build directory and build steps. */ -class AutotoolsBuildSettingsWidget : public ProjectExplorer::BuildConfigWidget +class AutotoolsBuildSettingsWidget : public ProjectExplorer::NamedWidget { Q_OBJECT public: - AutotoolsBuildSettingsWidget(); - - QString displayName() const; - void init(ProjectExplorer::BuildConfiguration *bc); + AutotoolsBuildSettingsWidget(AutotoolsBuildConfiguration *bc); private slots: void buildDirectoryChanged(); diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index b93d405c64..1080dc5636 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -40,7 +40,6 @@ #include "makefileparserthread.h" #include <projectexplorer/abi.h> -#include <projectexplorer/buildenvironmentwidget.h> #include <projectexplorer/kitmanager.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/buildconfiguration.h> @@ -126,11 +125,6 @@ QString AutotoolsProject::defaultBuildDirectory() const return projectDirectory(); } -QList<BuildConfigWidget *> AutotoolsProject::subConfigWidgets() -{ - return QList<BuildConfigWidget *>() << new BuildEnvironmentWidget; -} - ProjectNode *AutotoolsProject::rootProjectNode() const { return m_rootNode; @@ -414,18 +408,21 @@ void AutotoolsProject::updateCppCodeModel() QStringList allFrameworkPaths; QByteArray macros; + QStringList cxxflags; // FIXME: Autotools should be able to do better than this! + if (activeTarget()) { ProjectExplorer::Kit *k = activeTarget()->kit(); ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k); if (tc) { - const QList<HeaderPath> allHeaderPaths = tc->systemHeaderPaths(SysRootKitInformation::sysRoot(k)); + const QList<HeaderPath> allHeaderPaths = tc->systemHeaderPaths(cxxflags, + SysRootKitInformation::sysRoot(k)); foreach (const HeaderPath &headerPath, allHeaderPaths) { if (headerPath.kind() == HeaderPath::FrameworkHeaderPath) allFrameworkPaths.append(headerPath.path()); else allIncludePaths.append(headerPath.path()); } - macros = tc->predefinedMacros(QStringList()); + macros = tc->predefinedMacros(cxxflags); macros += '\n'; } } diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.h b/src/plugins/autotoolsprojectmanager/autotoolsproject.h index 1821e5f458..4800136a72 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.h +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.h @@ -74,7 +74,6 @@ public: Core::Id id() const; Core::IDocument *document() const; ProjectExplorer::IProjectManager *projectManager() const; - QList<ProjectExplorer::BuildConfigWidget*> subConfigWidgets(); ProjectExplorer::ProjectNode *rootProjectNode() const; QStringList files(FilesMode fileMode) const; QString defaultBuildDirectory() const; diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs index 78d4a6ab53..d5b9e0ebac 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs @@ -13,12 +13,6 @@ QtcPlugin { Depends { name: "cpp" } cpp.defines: base.concat(["QT_NO_CAST_FROM_ASCII"]) - cpp.includePaths: [ - ".", - "..", - "../../libs", - buildDirectory - ] files: [ "autogenstep.cpp", @@ -50,6 +44,6 @@ QtcPlugin { "makefileparserthread.cpp", "makefileparserthread.h", "makestep.cpp", - "makestep.h" + "makestep.h", ] } diff --git a/src/plugins/autotoolsprojectmanager/configurestep.cpp b/src/plugins/autotoolsprojectmanager/configurestep.cpp index 6f8bbe5dac..dc7a1b9569 100644 --- a/src/plugins/autotoolsprojectmanager/configurestep.cpp +++ b/src/plugins/autotoolsprojectmanager/configurestep.cpp @@ -151,14 +151,9 @@ void ConfigureStep::ctor() setDefaultDisplayName(tr("Configure")); } -AutotoolsBuildConfiguration *ConfigureStep::autotoolsBuildConfiguration() const -{ - return static_cast<AutotoolsBuildConfiguration *>(buildConfiguration()); -} - bool ConfigureStep::init() { - AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + BuildConfiguration *bc = buildConfiguration(); ProcessParameters *pp = processParameters(); pp->setMacroExpander(bc->macroExpander()); @@ -172,7 +167,7 @@ bool ConfigureStep::init() void ConfigureStep::run(QFutureInterface<bool>& interface) { - AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + BuildConfiguration *bc = buildConfiguration(); //Check whether we need to run configure const QFileInfo configureInfo(bc->buildDirectory() + QLatin1String("/configure")); @@ -271,7 +266,7 @@ QString ConfigureStepConfigWidget::summaryText() const void ConfigureStepConfigWidget::updateDetails() { - AutotoolsBuildConfiguration *bc = m_configureStep->autotoolsBuildConfiguration(); + BuildConfiguration *bc = m_configureStep->buildConfiguration(); ProcessParameters param; param.setMacroExpander(bc->macroExpander()); diff --git a/src/plugins/autotoolsprojectmanager/configurestep.h b/src/plugins/autotoolsprojectmanager/configurestep.h index 5eb351620e..27df52fdcc 100644 --- a/src/plugins/autotoolsprojectmanager/configurestep.h +++ b/src/plugins/autotoolsprojectmanager/configurestep.h @@ -42,7 +42,6 @@ namespace AutotoolsProjectManager { namespace Internal { class AutotoolsProject; -class AutotoolsBuildConfiguration; class ConfigureStepConfigWidget; ////////////////////////////////// @@ -95,7 +94,6 @@ class ConfigureStep : public ProjectExplorer::AbstractProcessStep public: ConfigureStep(ProjectExplorer::BuildStepList *bsl); - AutotoolsBuildConfiguration *autotoolsBuildConfiguration() const; bool init(); void run(QFutureInterface<bool> &interface); ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); diff --git a/src/plugins/autotoolsprojectmanager/makestep.cpp b/src/plugins/autotoolsprojectmanager/makestep.cpp index de9f1bf164..7716b5c0c2 100644 --- a/src/plugins/autotoolsprojectmanager/makestep.cpp +++ b/src/plugins/autotoolsprojectmanager/makestep.cpp @@ -154,11 +154,6 @@ void MakeStep::ctor() setDefaultDisplayName(tr("Make")); } -AutotoolsBuildConfiguration *MakeStep::autotoolsBuildConfiguration() const -{ - return static_cast<AutotoolsBuildConfiguration *>(buildConfiguration()); -} - void MakeStep::setClean(bool clean) { m_clean = clean; @@ -166,9 +161,9 @@ void MakeStep::setClean(bool clean) bool MakeStep::init() { - AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + BuildConfiguration *bc = buildConfiguration(); if (!bc) - bc = static_cast<AutotoolsBuildConfiguration *>(target()->activeBuildConfiguration()); + bc = target()->activeBuildConfiguration(); m_tasks.clear(); ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit()); @@ -196,11 +191,9 @@ bool MakeStep::init() pp->setArguments(arguments); setOutputParser(new GnuMakeParser()); - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); - if (version) - appendOutputParser(new QtSupport::QtParser); - if (tc) - appendOutputParser(tc->outputParser()); + IOutputParser *parser = target()->kit()->createOutputParser(); + if (parser) + appendOutputParser(parser); outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory()); return AbstractProcessStep::init(); @@ -316,7 +309,7 @@ QString MakeStepConfigWidget::summaryText() const void MakeStepConfigWidget::updateDetails() { - AutotoolsBuildConfiguration *bc = m_makeStep->autotoolsBuildConfiguration(); + BuildConfiguration *bc = m_makeStep->buildConfiguration(); ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_makeStep->target()->kit()); if (tc) { diff --git a/src/plugins/autotoolsprojectmanager/makestep.h b/src/plugins/autotoolsprojectmanager/makestep.h index 459a90d091..d4424bffd7 100644 --- a/src/plugins/autotoolsprojectmanager/makestep.h +++ b/src/plugins/autotoolsprojectmanager/makestep.h @@ -43,7 +43,6 @@ namespace AutotoolsProjectManager { namespace Internal { class AutotoolsProject; -class AutotoolsBuildConfiguration; class MakeStep; /////////////////////////// @@ -94,7 +93,6 @@ class MakeStep : public ProjectExplorer::AbstractProcessStep public: MakeStep(ProjectExplorer::BuildStepList *bsl); - AutotoolsBuildConfiguration *autotoolsBuildConfiguration() const; bool init(); void run(QFutureInterface<bool> &interface); ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); diff --git a/src/plugins/bazaar/bazaar.qbs b/src/plugins/bazaar/bazaar.qbs index 4271a0d0eb..b43ff69dd0 100644 --- a/src/plugins/bazaar/bazaar.qbs +++ b/src/plugins/bazaar/bazaar.qbs @@ -13,49 +13,44 @@ QtcPlugin { Depends { name: "Locator" } Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] files: [ - "bazaar.qrc", - "bazaarcommitpanel.ui", - "cloneoptionspanel.ui", - "pullorpushdialog.ui", - "revertdialog.ui", - "bazaarcommitwidget.cpp", - "bazaarcommitwidget.h", - "bazaarsettings.cpp", - "branchinfo.cpp", - "branchinfo.h", - "cloneoptionspanel.cpp", - "cloneoptionspanel.h", - "constants.h", - "optionspage.ui", - "pullorpushdialog.cpp", - "pullorpushdialog.h", "annotationhighlighter.cpp", "annotationhighlighter.h", + "bazaar.qrc", "bazaarclient.cpp", "bazaarclient.h", + "bazaarcommitpanel.ui", + "bazaarcommitwidget.cpp", + "bazaarcommitwidget.h", "bazaarcontrol.cpp", "bazaarcontrol.h", "bazaareditor.cpp", "bazaareditor.h", "bazaarplugin.cpp", "bazaarplugin.h", + "bazaarsettings.cpp", "bazaarsettings.h", + "branchinfo.cpp", + "branchinfo.h", + "cloneoptionspanel.cpp", + "cloneoptionspanel.h", + "cloneoptionspanel.ui", "clonewizard.cpp", "clonewizard.h", "clonewizardpage.cpp", "clonewizardpage.h", "commiteditor.cpp", "commiteditor.h", + "constants.h", "optionspage.cpp", "optionspage.h", - "images/bazaar.png" + "optionspage.ui", + "pullorpushdialog.cpp", + "pullorpushdialog.h", + "pullorpushdialog.ui", + "revertdialog.ui", + "images/bazaar.png", ] } diff --git a/src/plugins/bazaar/bazaarcontrol.cpp b/src/plugins/bazaar/bazaarcontrol.cpp index d726409cd1..628b4dfc48 100644 --- a/src/plugins/bazaar/bazaarcontrol.cpp +++ b/src/plugins/bazaar/bazaarcontrol.cpp @@ -51,7 +51,7 @@ QString BazaarControl::displayName() const Core::Id BazaarControl::id() const { - return VcsBase::Constants::VCS_ID_BAZAAR; + return Core::Id(VcsBase::Constants::VCS_ID_BAZAAR); } bool BazaarControl::managesDirectory(const QString &directory, QString *topLevel) const diff --git a/src/plugins/bineditor/bineditor.qbs b/src/plugins/bineditor/bineditor.qbs index b2fd675be8..638c13fb1d 100644 --- a/src/plugins/bineditor/bineditor.qbs +++ b/src/plugins/bineditor/bineditor.qbs @@ -11,19 +11,14 @@ QtcPlugin { Depends { name: "Find" } Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] files: [ - "bineditorplugin.h", + "bineditor.cpp", "bineditor.h", "bineditorconstants.h", - "markup.h", "bineditorplugin.cpp", - "bineditor.cpp" + "bineditorplugin.h", + "markup.h", ] } diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index 77b47bdeaa..3da2e89cbe 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -373,7 +373,7 @@ public: return m_file->open(errorString, fileName); } Core::IDocument *document() { return m_file; } - Core::Id id() const { return Core::Constants::K_DEFAULT_BINARY_EDITOR_ID; } + Core::Id id() const { return Core::Id(Core::Constants::K_DEFAULT_BINARY_EDITOR_ID); } QString displayName() const { return m_displayName; } void setDisplayName(const QString &title) { m_displayName = title; emit changed(); } @@ -417,7 +417,7 @@ BinEditorFactory::BinEditorFactory(BinEditorPlugin *owner) : Core::Id BinEditorFactory::id() const { - return Core::Constants::K_DEFAULT_BINARY_EDITOR_ID; + return Core::Id(Core::Constants::K_DEFAULT_BINARY_EDITOR_ID); } QString BinEditorFactory::displayName() const diff --git a/src/plugins/bookmarks/bookmark.cpp b/src/plugins/bookmarks/bookmark.cpp index 1e34776ac5..d8e8b32743 100644 --- a/src/plugins/bookmarks/bookmark.cpp +++ b/src/plugins/bookmarks/bookmark.cpp @@ -77,11 +77,27 @@ void Bookmark::updateFileName(const QString &fileName) BaseTextMark::updateFileName(fileName); } +void Bookmark::setNote(const QString ¬e) +{ + m_note = note; +} + +void Bookmark::updateNote(const QString ¬e) +{ + setNote(note); + m_manager->updateBookmark(this); +} + QString Bookmark::lineText() const { return m_lineText; } +QString Bookmark::note() const +{ + return m_note; +} + QString Bookmark::filePath() const { return m_fileName; diff --git a/src/plugins/bookmarks/bookmark.h b/src/plugins/bookmarks/bookmark.h index 23019e700a..265f884530 100644 --- a/src/plugins/bookmarks/bookmark.h +++ b/src/plugins/bookmarks/bookmark.h @@ -52,12 +52,15 @@ public: void updateLineNumber(int lineNumber); void updateBlock(const QTextBlock &block); void updateFileName(const QString &fileName); + void setNote(const QString ¬e); + void updateNote(const QString ¬e); void removedFromEditor(); QString filePath() const; QString fileName() const; QString path() const; QString lineText() const; + QString note() const; private: BookmarkManager *m_manager; @@ -65,6 +68,7 @@ private: QString m_onlyFile; QString m_path; QString m_lineText; + QString m_note; }; } // namespace Internal diff --git a/src/plugins/bookmarks/bookmarkmanager.cpp b/src/plugins/bookmarks/bookmarkmanager.cpp index 3bb59e8a6d..39957f2596 100644 --- a/src/plugins/bookmarks/bookmarkmanager.cpp +++ b/src/plugins/bookmarks/bookmarkmanager.cpp @@ -40,6 +40,8 @@ #include <projectexplorer/projectexplorer.h> #include <projectexplorer/session.h> #include <texteditor/basetexteditor.h> +#include <texteditor/tooltip/tooltip.h> +#include <texteditor/tooltip/tipcontents.h> #include <utils/qtcassert.h> #include <QDebug> @@ -50,6 +52,7 @@ #include <QContextMenuEvent> #include <QMenu> #include <QPainter> +#include <QInputDialog> Q_DECLARE_METATYPE(Bookmarks::Internal::Bookmark*) @@ -194,7 +197,10 @@ void BookmarkDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti // // painter->drawText(3, opt.rect.top() + fm.ascent() + fm.height() + 6, directory); - QString lineText = index.data(BookmarkManager::LineText).toString().trimmed(); + QString lineText = index.data(BookmarkManager::Note).toString().trimmed(); + if (lineText.isEmpty()) + lineText = index.data(BookmarkManager::LineText).toString().trimmed(); + painter->drawText(6, opt.rect.top() + fm.ascent() + fm.height() + 6, lineText); // Separator lines @@ -233,6 +239,8 @@ void BookmarkView::contextMenuEvent(QContextMenuEvent *event) QAction *moveDown = menu.addAction(tr("Move Down")); QAction *remove = menu.addAction(tr("&Remove")); QAction *removeAll = menu.addAction(tr("Remove All")); + QAction *editNote = menu.addAction(tr("Edit note")); + m_contextMenuIndex = indexAt(event->pos()); if (!m_contextMenuIndex.isValid()) { moveUp->setEnabled(false); @@ -251,6 +259,8 @@ void BookmarkView::contextMenuEvent(QContextMenuEvent *event) this, SLOT(removeFromContextMenu())); connect(removeAll, SIGNAL(triggered()), this, SLOT(removeAll())); + connect(editNote, SIGNAL(triggered()), + m_manager, SLOT(editNote())); menu.exec(mapToGlobal(event->pos())); } @@ -338,6 +348,12 @@ QItemSelectionModel *BookmarkManager::selectionModel() const return m_selectionModel; } +bool BookmarkManager::hasBookmarkInPosition(const QString &fileName, int lineNumber) +{ + QFileInfo fi(fileName); + return findBookmark(fi.path(), fi.fileName(), lineNumber); +} + QModelIndex BookmarkManager::index(int row, int column, const QModelIndex &parent) const { if (parent.isValid()) @@ -379,6 +395,8 @@ QVariant BookmarkManager::data(const QModelIndex &index, int role) const return m_bookmarksList.at(index.row())->path(); else if (role == BookmarkManager::LineText) return m_bookmarksList.at(index.row())->lineText(); + else if (role == BookmarkManager::Note) + return m_bookmarksList.at(index.row())->note(); else if (role == Qt::ToolTipRole) return QDir::toNativeSeparators(m_bookmarksList.at(index.row())->filePath()); @@ -643,6 +661,8 @@ void BookmarkManager::moveUp() QModelIndex bottomRight = current.sibling(current.row(), 2); emit dataChanged(topLeft, bottomRight); selectionModel()->setCurrentIndex(current.sibling(row, 0), QItemSelectionModel::Select | QItemSelectionModel::Clear); + + saveBookmarks(); } void BookmarkManager::moveDown() @@ -662,6 +682,35 @@ void BookmarkManager::moveDown() QModelIndex bottomRight = current.sibling(row, 2); emit dataChanged(topLeft, bottomRight); selectionModel()->setCurrentIndex(current.sibling(row, 0), QItemSelectionModel::Select | QItemSelectionModel::Clear); + + saveBookmarks(); +} + +void BookmarkManager::editNote(const QString &fileName, int lineNumber) +{ + QFileInfo fi(fileName); + Bookmark *b = findBookmark(fi.path(), fi.fileName(), lineNumber); + QModelIndex current = selectionModel()->currentIndex(); + selectionModel()->setCurrentIndex(current.sibling(m_bookmarksList.indexOf(b), 0), + QItemSelectionModel::Select | QItemSelectionModel::Clear); + + editNote(); +} + +void BookmarkManager::editNote() +{ + QModelIndex current = selectionModel()->currentIndex(); + Bookmark *b = m_bookmarksList.at(current.row()); + + bool inputOk = false; + QString noteText = QInputDialog::getText(0, tr("Edit note"), + tr("Note text:"), QLineEdit::Normal, + b->note(), &inputOk); + if (inputOk) { + b->updateNote(noteText.replace(QLatin1Char('\t'), QLatin1Char(' '))); + emit dataChanged(current, current); + saveBookmarks(); + } } /* Returns the bookmark at the given file and line number, or 0 if no such bookmark exists. */ @@ -703,15 +752,22 @@ void BookmarkManager::addBookmark(Bookmark *bookmark, bool userset) /* Adds a new bookmark based on information parsed from the string. */ void BookmarkManager::addBookmark(const QString &s) { - int index2 = s.lastIndexOf(':'); + // index3 is a frontier beetween note text and other bookmarks data + int index3 = s.lastIndexOf('\t'); + if (index3 < 0) + index3 = s.size(); + int index2 = s.lastIndexOf(':', index3 - 1); int index1 = s.indexOf(':'); - if (index2 != -1 || index1 != -1) { + + if (index3 != -1 || index2 != -1 || index1 != -1) { const QString &filePath = s.mid(index1+1, index2-index1-1); - const int lineNumber = s.mid(index2 + 1).toInt(); + const QString ¬e = s.mid(index3 + 1); + const int lineNumber = s.mid(index2 + 1, index3 - index2 - 1).toInt(); const QFileInfo fi(filePath); if (!filePath.isEmpty() && !findBookmark(fi.path(), fi.fileName(), lineNumber)) { Bookmark *b = new Bookmark(filePath, lineNumber, this); + b->setNote(note); b->init(); addBookmark(b, false); } @@ -724,21 +780,36 @@ void BookmarkManager::addBookmark(const QString &s) QString BookmarkManager::bookmarkToString(const Bookmark *b) { const QLatin1Char colon(':'); + // Using \t as delimiter because any another symbol can be a part of note. + const QLatin1Char noteDelimiter('\t'); // Empty string was the name of the bookmark, which now is always "" - return QLatin1String("") + colon + b->filePath() + colon + QString::number(b->lineNumber()); + return QLatin1String("") + colon + b->filePath() + + colon + QString::number(b->lineNumber()) + + noteDelimiter + b->note(); } /* Saves the bookmarks to the session settings. */ void BookmarkManager::saveBookmarks() { QStringList list; - foreach (const FileNameBookmarksMap *bookmarksMap, m_bookmarksMap) - foreach (const Bookmark *bookmark, *bookmarksMap) + foreach (const Bookmark *bookmark, m_bookmarksList) list << bookmarkToString(bookmark); sessionManager()->setValue("Bookmarks", list); } +void BookmarkManager::operateTooltip(TextEditor::ITextEditor *textEditor, const QPoint &pos, Bookmark *mark) +{ + if (!mark) + return; + + if (mark->note().isEmpty()) { + TextEditor::ToolTip::instance()->hide(); + } else { + TextEditor::ToolTip::instance()->show(pos, TextEditor::TextContent(mark->note()), textEditor->widget()); + } +} + /* Loads the bookmarks from the session settings. */ void BookmarkManager::loadBookmarks() { @@ -758,6 +829,16 @@ void BookmarkManager::handleBookmarkRequest(TextEditor::ITextEditor *textEditor, toggleBookmark(textEditor->document()->fileName(), line); } +void BookmarkManager::handleBookmarkTooltipRequest(TextEditor::ITextEditor *textEditor, const QPoint &pos, + int line) +{ + if (textEditor->document()) { + const QFileInfo fi(textEditor->document()->fileName()); + Bookmark *mark = findBookmark(fi.path(), fi.fileName(), line); + operateTooltip(textEditor, pos, mark); + } +} + // BookmarkViewFactory BookmarkViewFactory::BookmarkViewFactory(BookmarkManager *bm) diff --git a/src/plugins/bookmarks/bookmarkmanager.h b/src/plugins/bookmarks/bookmarkmanager.h index 2f5b21be65..d7b4112672 100644 --- a/src/plugins/bookmarks/bookmarkmanager.h +++ b/src/plugins/bookmarks/bookmarkmanager.h @@ -85,11 +85,14 @@ public: // this QItemSelectionModel is shared by all views QItemSelectionModel *selectionModel() const; + bool hasBookmarkInPosition(const QString &fileName, int lineNumber); + enum Roles { Filename = Qt::UserRole, LineNumber = Qt::UserRole + 1, Directory = Qt::UserRole + 2, - LineText = Qt::UserRole + 3 + LineText = Qt::UserRole + 3, + Note = Qt::UserRole + 4 }; public slots: @@ -101,6 +104,8 @@ public slots: void prev(); void moveUp(); void moveDown(); + void editNote(); + void editNote(const QString &fileName, int lineNumber); bool gotoBookmark(Bookmark *bookmark); signals: @@ -113,6 +118,9 @@ private slots: void handleBookmarkRequest(TextEditor::ITextEditor * textEditor, int line, TextEditor::ITextEditor::MarkRequestKind kind); + void handleBookmarkTooltipRequest(TextEditor::ITextEditor *textEditor, + const QPoint &pos, + int line); private: TextEditor::ITextEditor *currentTextEditor() const; @@ -125,6 +133,7 @@ private: void addBookmark(const QString &s); static QString bookmarkToString(const Bookmark *b); void saveBookmarks(); + void operateTooltip(TextEditor::ITextEditor *textEditor, const QPoint &pos, Bookmark *mark); typedef QMultiMap<QString, Bookmark *> FileNameBookmarksMap; typedef QMap<QString, FileNameBookmarksMap *> DirectoryFileBookmarksMap; diff --git a/src/plugins/bookmarks/bookmarks.qbs b/src/plugins/bookmarks/bookmarks.qbs index 0fa44b7194..c7d02f9e7d 100644 --- a/src/plugins/bookmarks/bookmarks.qbs +++ b/src/plugins/bookmarks/bookmarks.qbs @@ -13,21 +13,16 @@ QtcPlugin { Depends { name: "Locator" } Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] files: [ - "bookmarksplugin.h", + "bookmark.cpp", "bookmark.h", + "bookmarkmanager.cpp", "bookmarkmanager.h", + "bookmarks.qrc", "bookmarks_global.h", "bookmarksplugin.cpp", - "bookmark.cpp", - "bookmarkmanager.cpp", - "bookmarks.qrc", + "bookmarksplugin.h", ] } diff --git a/src/plugins/bookmarks/bookmarks_global.h b/src/plugins/bookmarks/bookmarks_global.h index 6ca53577a2..3e20208b8e 100644 --- a/src/plugins/bookmarks/bookmarks_global.h +++ b/src/plugins/bookmarks/bookmarks_global.h @@ -36,6 +36,7 @@ namespace Constants { const char BOOKMARKS_TOGGLE_ACTION[] = "Bookmarks.Toggle"; const char BOOKMARKS_MOVEUP_ACTION[] = "Bookmarks.MoveUp"; const char BOOKMARKS_MOVEDOWN_ACTION[] = "Bookmarks.MoveDown"; +const char BOOKMARKS_EDITNOTE_ACTION[] = "Bookmarks.EditNote"; const char BOOKMARKS_PREV_ACTION[] = "Bookmarks.Previous"; const char BOOKMARKS_NEXT_ACTION[] = "Bookmarks.Next"; const char BOOKMARKS_PREVDIR_ACTION[] = "Bookmarks.PreviousDirectory"; diff --git a/src/plugins/bookmarks/bookmarksplugin.cpp b/src/plugins/bookmarks/bookmarksplugin.cpp index d836024736..6bbcbd7669 100644 --- a/src/plugins/bookmarks/bookmarksplugin.cpp +++ b/src/plugins/bookmarks/bookmarksplugin.cpp @@ -108,6 +108,8 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *) cmd = Core::ActionManager::registerAction(m_docNextAction, BOOKMARKS_NEXTDOC_ACTION, globalcontext); mbm->addAction(cmd); + m_editNoteAction = new QAction(tr("Edit Bookmark Note"), this); + m_bookmarkManager = new BookmarkManager; connect(m_toggleAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(toggleBookmark())); @@ -115,6 +117,7 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *) connect(m_nextAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(next())); connect(m_docPrevAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(prevInDocument())); connect(m_docNextAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(nextInDocument())); + connect(m_editNoteAction, SIGNAL(triggered()), this, SLOT(bookmarkEditNoteActionTriggered())); connect(m_bookmarkManager, SIGNAL(updateActions(int)), this, SLOT(updateActions(int))); updateActions(m_bookmarkManager->state()); addAutoReleasedObject(new BookmarkViewFactory(m_bookmarkManager)); @@ -163,6 +166,10 @@ void BookmarksPlugin::editorOpened(Core::IEditor *editor) m_bookmarkManager, SLOT(handleBookmarkRequest(TextEditor::ITextEditor*,int, TextEditor::ITextEditor::MarkRequestKind))); + connect(editor, + SIGNAL(markTooltipRequested(TextEditor::ITextEditor*,QPoint,int)), + m_bookmarkManager, + SLOT(handleBookmarkTooltipRequest(TextEditor::ITextEditor*,QPoint,int))); } } @@ -179,15 +186,21 @@ void BookmarksPlugin::requestContextMenu(TextEditor::ITextEditor *editor, { m_bookmarkMarginActionLineNumber = lineNumber; m_bookmarkMarginActionFileName = editor->document()->fileName(); + menu->addAction(m_bookmarkMarginAction); + if (m_bookmarkManager->hasBookmarkInPosition(m_bookmarkMarginActionFileName, m_bookmarkMarginActionLineNumber)) + menu->addAction(m_editNoteAction); } void BookmarksPlugin::bookmarkMarginActionTriggered() { - m_bookmarkManager->toggleBookmark( - m_bookmarkMarginActionFileName, - m_bookmarkMarginActionLineNumber - ); + m_bookmarkManager->toggleBookmark(m_bookmarkMarginActionFileName, + m_bookmarkMarginActionLineNumber); +} + +void BookmarksPlugin::bookmarkEditNoteActionTriggered() +{ + m_bookmarkManager->editNote(m_bookmarkMarginActionFileName, m_bookmarkMarginActionLineNumber); } Q_EXPORT_PLUGIN(BookmarksPlugin) diff --git a/src/plugins/bookmarks/bookmarksplugin.h b/src/plugins/bookmarks/bookmarksplugin.h index b8280c3e35..df70a423cf 100644 --- a/src/plugins/bookmarks/bookmarksplugin.h +++ b/src/plugins/bookmarks/bookmarksplugin.h @@ -76,6 +76,7 @@ private slots: void requestContextMenu(TextEditor::ITextEditor *editor, int lineNumber, QMenu *menu); void bookmarkMarginActionTriggered(); + void bookmarkEditNoteActionTriggered(); private: static BookmarksPlugin *m_instance; @@ -86,6 +87,7 @@ private: QAction *m_nextAction; QAction *m_docPrevAction; QAction *m_docNextAction; + QAction *m_editNoteAction; QAction *m_bookmarkMarginAction; int m_bookmarkMarginActionLineNumber; diff --git a/src/plugins/classview/classview.qbs b/src/plugins/classview/classview.qbs index a7ad4a23c2..338cec83eb 100644 --- a/src/plugins/classview/classview.qbs +++ b/src/plugins/classview/classview.qbs @@ -13,36 +13,31 @@ QtcPlugin { Depends { name: "TextEditor" } Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] files: [ - "classviewplugin.h", - "classviewnavigationwidgetfactory.h", + "classview.qrc", "classviewconstants.h", + "classviewmanager.cpp", + "classviewmanager.h", + "classviewnavigationwidget.cpp", "classviewnavigationwidget.h", + "classviewnavigationwidget.ui", + "classviewnavigationwidgetfactory.cpp", + "classviewnavigationwidgetfactory.h", + "classviewparser.cpp", "classviewparser.h", - "classviewmanager.h", - "classviewsymbollocation.h", - "classviewsymbolinformation.h", + "classviewparsertreeitem.cpp", "classviewparsertreeitem.h", - "classviewutils.h", - "classviewtreeitemmodel.h", "classviewplugin.cpp", - "classviewnavigationwidgetfactory.cpp", - "classviewnavigationwidget.cpp", - "classviewparser.cpp", - "classviewmanager.cpp", - "classviewsymbollocation.cpp", + "classviewplugin.h", "classviewsymbolinformation.cpp", - "classviewparsertreeitem.cpp", - "classviewutils.cpp", + "classviewsymbolinformation.h", + "classviewsymbollocation.cpp", + "classviewsymbollocation.h", "classviewtreeitemmodel.cpp", - "classviewnavigationwidget.ui", - "classview.qrc", + "classviewtreeitemmodel.h", + "classviewutils.cpp", + "classviewutils.h", ] } diff --git a/src/plugins/clearcase/clearcase.qbs b/src/plugins/clearcase/clearcase.qbs index 2a3776d6d1..18a15de51a 100644 --- a/src/plugins/clearcase/clearcase.qbs +++ b/src/plugins/clearcase/clearcase.qbs @@ -18,12 +18,6 @@ QtcPlugin { Depends { name: "cpp" } cpp.defines: base.concat(["QT_NO_CAST_FROM_ASCII"]) - cpp.includePaths: [ - ".", - "..", - "../../libs", - buildDirectory - ] files: [ "activityselector.cpp", diff --git a/src/plugins/clearcase/clearcasecontrol.cpp b/src/plugins/clearcase/clearcasecontrol.cpp index 110e3e728b..8ee90b2fe2 100644 --- a/src/plugins/clearcase/clearcasecontrol.cpp +++ b/src/plugins/clearcase/clearcasecontrol.cpp @@ -52,7 +52,7 @@ QString ClearCaseControl::displayName() const Core::Id ClearCaseControl::id() const { - return ClearCase::Constants::VCS_ID_CLEARCASE; + return Core::Id(ClearCase::Constants::VCS_ID_CLEARCASE); } bool ClearCaseControl::isConfigured() const @@ -144,6 +144,11 @@ QString ClearCaseControl::vcsMakeWritableText() const return tr("&Hijack"); } +QString ClearCaseControl::vcsTopic(const QString &directory) +{ + return m_plugin->ccGetView(directory); +} + void ClearCaseControl::emitRepositoryChanged(const QString &s) { emit repositoryChanged(s); diff --git a/src/plugins/clearcase/clearcasecontrol.h b/src/plugins/clearcase/clearcasecontrol.h index e91476954b..eb279de329 100644 --- a/src/plugins/clearcase/clearcasecontrol.h +++ b/src/plugins/clearcase/clearcasecontrol.h @@ -70,6 +70,7 @@ public: QString vcsOpenText() const; QString vcsMakeWritableText() const; + QString vcsTopic(const QString &directory); void emitRepositoryChanged(const QString &); void emitFilesChanged(const QStringList &); diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp index b37aa68be0..e1159dcf85 100644 --- a/src/plugins/clearcase/clearcaseplugin.cpp +++ b/src/plugins/clearcase/clearcaseplugin.cpp @@ -58,6 +58,7 @@ #include <utils/synchronousprocess.h> #include <utils/parameteraction.h> #include <utils/fileutils.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/runextensions.h> #include <vcsbase/basevcseditorfactory.h> @@ -152,7 +153,7 @@ static inline const VcsBase::VcsBaseEditorParameters *findType(int ie) static inline QString debugCodec(const QTextCodec *c) { - return c ? QString::fromAscii(c->name()) : QString::fromAscii("Null codec"); + return c ? QString::fromLatin1(c->name()) : QString::fromLatin1("Null codec"); } // ------------- ClearCasePlugin @@ -714,11 +715,10 @@ bool ClearCasePlugin::vcsUndoHijack(const QString &workingDir, const QString &fi QStringList args(QLatin1String("update")); args << QLatin1String(keep ? "-rename" : "-overwrite"); args << QLatin1String("-log"); -#ifdef Q_OS_WIN32 - args << QLatin1String("NUL"); -#else + if (Utils::HostOsInfo::isWindowsHost()) + args << QLatin1String("NUL"); + else args << QLatin1String("/dev/null"); -#endif args << QDir::toNativeSeparators(fileName); const ClearCaseResponse response = @@ -1261,7 +1261,7 @@ Core::IEditor *ClearCasePlugin::showOutputInEditor(const QString& title, const Q { const VcsBase::VcsBaseEditorParameters *params = findType(editorType); QTC_ASSERT(params, return 0); - const Core::Id id = params->id; + const Core::Id id = Core::Id(QByteArray(params->id)); if (ClearCase::Constants::debug) qDebug() << "ClearCasePlugin::showOutputInEditor" << title << id.name() << "Size= " << output.size() << " Type=" << editorType << debugCodec(codec); @@ -1762,8 +1762,6 @@ void ClearCasePlugin::projectChanged(ProjectExplorer::Project *project) updateStreamAndView(); if (m_view.isEmpty()) return; - Core::EditorManager *editorManager = Core::ICore::editorManager(); - editorManager->setWindowTitleAddition(editorManager->windowTitleAddition() + QLatin1String(" - ") + m_view); updateIndex(); } if ( ClearCase::Constants::debug ) diff --git a/src/plugins/clearcase/clearcaseplugin.h b/src/plugins/clearcase/clearcaseplugin.h index 9c9a1a9159..c2fe94df12 100644 --- a/src/plugins/clearcase/clearcaseplugin.h +++ b/src/plugins/clearcase/clearcaseplugin.h @@ -141,6 +141,7 @@ public: QList<QStringPair> activities(int *current = 0) const; QString ccGetPredecessor(const QString &version) const; QStringList ccGetActiveVobs() const; + QString ccGetView(const QString &workingDir, bool *isDynamic = 0, bool *isUcm = 0) const; bool ccFileOp(const QString &workingDir, const QString &title, const QStringList &args, const QString &fileName, const QString &file2 = QString()); FileStatus vcsStatus(const QString &file) const; @@ -217,7 +218,6 @@ private: static void rmdir(const QString &path); QString runExtDiff(const QString &workingDir, const QStringList &arguments, int timeOut, QTextCodec *outputCodec = 0); - QString ccGetView(const QString &workingDir, bool *isDynamic = 0, bool *isUcm = 0) const; ClearCaseSettings m_settings; diff --git a/src/plugins/clearcase/clearcasesettings.cpp b/src/plugins/clearcase/clearcasesettings.cpp index 5cfb11ba11..11cae8f804 100644 --- a/src/plugins/clearcase/clearcasesettings.cpp +++ b/src/plugins/clearcase/clearcasesettings.cpp @@ -31,6 +31,7 @@ #include "clearcasesettings.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <QSettings> @@ -55,11 +56,7 @@ enum { defaultTimeOutS = 30, defaultHistoryCount = 50 }; static QString defaultCommand() { - QString rc(QLatin1String("cleartool")); -#if defined(Q_OS_WIN32) - rc.append(QLatin1String(".exe")); -#endif - return rc; + return QLatin1String("cleartool" QTC_HOST_EXE_SUFFIX); } using namespace ClearCase::Internal; diff --git a/src/plugins/clearcase/settingspage.cpp b/src/plugins/clearcase/settingspage.cpp index e8d4252eb5..3dd15b2113 100644 --- a/src/plugins/clearcase/settingspage.cpp +++ b/src/plugins/clearcase/settingspage.cpp @@ -36,6 +36,7 @@ #include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <utils/pathchooser.h> #include <QCoreApplication> @@ -84,11 +85,11 @@ void SettingsPageWidget::setSettings(const ClearCaseSettings &s) m_ui.diffWarningLabel->setVisible(false); } else { QString diffWarning = tr("In order to use External diff, 'diff' command needs to be accessible."); -#ifdef Q_OS_WIN - diffWarning.append(tr(" DiffUtils is available for free download " - "<a href=\"http://gnuwin32.sourceforge.net/packages/diffutils.htm\">here</a>. " - "Please extract it to a directory in your PATH.")); -#endif + if (HostOsInfo::isWindowsHost()) { + diffWarning.append(tr(" DiffUtils is available for free download " + "<a href=\"http://gnuwin32.sourceforge.net/packages/diffutils.htm\">here</a>. " + "Please extract it to a directory in your PATH.")); + } m_ui.diffWarningLabel->setText(diffWarning); m_ui.externalDiffRadioButton->setEnabled(false); } diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 7e0eea574d..b29e49334d 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -106,9 +106,9 @@ void CMakeBuildConfiguration::setUseNinja(bool useNninja) CMakeBuildConfiguration::~CMakeBuildConfiguration() { } -ProjectExplorer::BuildConfigWidget *CMakeBuildConfiguration::createConfigWidget() +ProjectExplorer::NamedWidget *CMakeBuildConfiguration::createConfigWidget() { - return new CMakeBuildSettingsWidget; + return new CMakeBuildSettingsWidget(this); } QString CMakeBuildConfiguration::buildDirectory() const @@ -125,26 +125,6 @@ void CMakeBuildConfiguration::setBuildDirectory(const QString &buildDirectory) emit environmentChanged(); } -ProjectExplorer::IOutputParser *CMakeBuildConfiguration::createOutputParser() const -{ - ProjectExplorer::IOutputParser *parserchain = new ProjectExplorer::GnuMakeParser; - - int versionId = QtSupport::QtKitInformation::qtVersionId(target()->kit()); - if (versionId >= 0) - parserchain->appendOutputParser(new QtSupport::QtParser); - - ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(target()->kit()); - if (tc) - parserchain->appendOutputParser(tc->outputParser()); - return parserchain; -} - -Utils::Environment CMakeBuildConfiguration::baseEnvironment() const -{ - Utils::Environment env = BuildConfiguration::baseEnvironment(); - return env; -} - /*! \class CMakeBuildConfigurationFactory */ @@ -223,15 +203,15 @@ CMakeBuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer: MakeStep *cleanMakeStep = new MakeStep(cleanSteps); cleanSteps->insertStep(0, cleanMakeStep); - cleanMakeStep->setAdditionalArguments("clean"); + cleanMakeStep->setAdditionalArguments(QLatin1String("clean")); cleanMakeStep->setClean(true); bc->setBuildDirectory(copw.buildDirectory()); bc->setUseNinja(copw.useNinja()); // Default to all - if (project->hasBuildTarget("all")) - makeStep->setBuildTarget("all", true); + if (project->hasBuildTarget(QLatin1String("all"))) + makeStep->setBuildTarget(QLatin1String("all"), true); return bc; } @@ -275,13 +255,13 @@ bool CMakeBuildConfigurationFactory::canHandle(const ProjectExplorer::Target *t) ProjectExplorer::BuildConfiguration::BuildType CMakeBuildConfiguration::buildType() const { QString cmakeBuildType; - QFile cmakeCache(buildDirectory() + "/CMakeCache.txt"); + QFile cmakeCache(buildDirectory() + QLatin1String("/CMakeCache.txt")); if (cmakeCache.open(QIODevice::ReadOnly)) { while (!cmakeCache.atEnd()) { - QString line = cmakeCache.readLine(); + QByteArray line = cmakeCache.readLine(); if (line.startsWith("CMAKE_BUILD_TYPE")) { if (int pos = line.indexOf('=')) { - cmakeBuildType = line.mid(pos + 1).trimmed(); + cmakeBuildType = QString::fromLocal8Bit(line.mid(pos + 1).trimmed()); } break; } @@ -290,13 +270,13 @@ ProjectExplorer::BuildConfiguration::BuildType CMakeBuildConfiguration::buildTyp } // Cover all common CMake build types - if (cmakeBuildType.compare("Release", Qt::CaseInsensitive) == 0 - || cmakeBuildType.compare("MinSizeRel", Qt::CaseInsensitive) == 0) + if (cmakeBuildType.compare(QLatin1String("Release"), Qt::CaseInsensitive) == 0 + || cmakeBuildType.compare(QLatin1String("MinSizeRel"), Qt::CaseInsensitive) == 0) { return Release; - } else if (cmakeBuildType.compare("Debug", Qt::CaseInsensitive) == 0 - || cmakeBuildType.compare("debugfull", Qt::CaseInsensitive) == 0 - || cmakeBuildType.compare("RelWithDebInfo", Qt::CaseInsensitive) == 0) + } else if (cmakeBuildType.compare(QLatin1String("Debug"), Qt::CaseInsensitive) == 0 + || cmakeBuildType.compare(QLatin1String("DebugFull"), Qt::CaseInsensitive) == 0 + || cmakeBuildType.compare(QLatin1String("RelWithDebInfo"), Qt::CaseInsensitive) == 0) { return Debug; } diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index 1a1c60a055..c46880aaa9 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -51,17 +51,13 @@ public: CMakeBuildConfiguration(ProjectExplorer::Target *parent); ~CMakeBuildConfiguration(); - ProjectExplorer::BuildConfigWidget *createConfigWidget(); + ProjectExplorer::NamedWidget *createConfigWidget(); QString buildDirectory() const; void setBuildDirectory(const QString &buildDirectory); QVariantMap toMap() const; - ProjectExplorer::IOutputParser *createOutputParser() const; - - Utils::Environment baseEnvironment() const; - BuildType buildType() const; bool useNinja() const; diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp index 685bdfd168..0149f08dc4 100644 --- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp @@ -74,7 +74,7 @@ Core::IEditor *CMakeEditor::duplicate(QWidget *parent) Core::Id CMakeEditor::id() const { - return CMakeProjectManager::Constants::CMAKE_EDITOR_ID; + return Core::Id(CMakeProjectManager::Constants::CMAKE_EDITOR_ID); } void CMakeEditor::markAsChanged() @@ -84,7 +84,7 @@ void CMakeEditor::markAsChanged() if (m_infoBarShown) return; m_infoBarShown = true; - Core::InfoBarEntry info(QLatin1String("CMakeEditor.RunCMake"), + Core::InfoBarEntry info(Core::Id("CMakeEditor.RunCMake"), tr("Changes to cmake files are shown in the project tree after building.")); info.setCustomButtonInfo(tr("Build now"), this, SLOT(build())); document()->infoBar()->addInfo(info); @@ -223,7 +223,7 @@ CMakeEditorWidget::Link CMakeEditorWidget::findLinkAt(const QTextCursor &cursor, if (fi.exists()) { if (fi.isDir()) { QDir subDir(fi.absoluteFilePath()); - QString subProject = subDir.filePath("CMakeLists.txt"); + QString subProject = subDir.filePath(QLatin1String("CMakeLists.txt")); if (QFileInfo(subProject).exists()) fileName = subProject; else diff --git a/src/plugins/cmakeprojectmanager/cmakeeditorfactory.cpp b/src/plugins/cmakeprojectmanager/cmakeeditorfactory.cpp index 97f62c1ae5..79d95c81c2 100644 --- a/src/plugins/cmakeprojectmanager/cmakeeditorfactory.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeeditorfactory.cpp @@ -69,7 +69,7 @@ CMakeEditorFactory::CMakeEditorFactory(CMakeManager *manager) Core::Id CMakeEditorFactory::id() const { - return CMakeProjectManager::Constants::CMAKE_EDITOR_ID; + return Core::Id(CMakeProjectManager::Constants::CMAKE_EDITOR_ID); } QString CMakeEditorFactory::displayName() const diff --git a/src/plugins/qmldesigner/meegoplugin/meegoplugin.cpp b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp index 476cd23487..a4ca8a87b9 100644 --- a/src/plugins/qmldesigner/meegoplugin/meegoplugin.cpp +++ b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp @@ -27,30 +27,31 @@ ** ****************************************************************************/ -#include "meegoplugin.h" -#include <widgetplugin_helper.h> -#include <QtPlugin> +#include "cmakefilecompletionassist.h" +#include "cmakeprojectconstants.h" +#include "cmakeprojectmanager.h" -namespace QmlDesigner { +#include <texteditor/codeassist/keywordscompletionassist.h> +using namespace CMakeProjectManager::Internal; +using namespace TextEditor; -MeegoPlugin::MeegoPlugin() -{ -} +// ------------------------------- +// CMakeFileCompletionAssistProvider +// ------------------------------- +CMakeFileCompletionAssistProvider::CMakeFileCompletionAssistProvider(CMakeSettingsPage *settingsPage) + : m_settingsPage(settingsPage) +{} -QString MeegoPlugin::pluginName() const -{ - return ("MeegoPlugin"); -} +CMakeFileCompletionAssistProvider::~CMakeFileCompletionAssistProvider() +{} -QString MeegoPlugin::metaInfo() const +bool CMakeFileCompletionAssistProvider::supportsEditor(const Core::Id &editorId) const { - return QString(":/meegoplugin/meego.metainfo"); + return editorId == CMakeProjectManager::Constants::CMAKE_EDITOR_ID; } +IAssistProcessor *CMakeFileCompletionAssistProvider::createProcessor() const +{ + return new KeywordsCompletionAssistProcessor(m_settingsPage->keywords()); } - -#if QT_VERSION < 0x050000 -Q_EXPORT_PLUGIN(QmlDesigner::MeegoPlugin) -#endif - diff --git a/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.h b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.h new file mode 100644 index 0000000000..75b7c4bf93 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CMAKEFILECOMPLETIONASSIST_H +#define CMAKEFILECOMPLETIONASSIST_H + +#include <texteditor/codeassist/completionassistprovider.h> + +namespace CMakeProjectManager { +namespace Internal { + +class CMakeSettingsPage; + +class CMakeFileCompletionAssistProvider : public TextEditor::CompletionAssistProvider +{ +public: + CMakeFileCompletionAssistProvider(CMakeSettingsPage *settingsPage); + ~CMakeFileCompletionAssistProvider(); + + bool supportsEditor(const Core::Id &editorId) const; + TextEditor::IAssistProcessor *createProcessor() const; + +private: + CMakeSettingsPage *m_settingsPage; +}; + +} // Internal +} // CMakeProjectManager + +#endif // CMAKEFILECOMPLETIONASSIST_H diff --git a/src/plugins/cmakeprojectmanager/cmakehighlighter.cpp b/src/plugins/cmakeprojectmanager/cmakehighlighter.cpp index 0c162f60a8..f577d4a28a 100644 --- a/src/plugins/cmakeprojectmanager/cmakehighlighter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakehighlighter.cpp @@ -37,7 +37,7 @@ using namespace CMakeProjectManager::Internal; -static bool isVariable(const QString &word) +static bool isVariable(const QByteArray &word) { if (word.length() < 4) // must be at least "${.}" return false; @@ -53,14 +53,14 @@ CMakeHighlighter::CMakeHighlighter(QTextDocument *document) : void CMakeHighlighter::highlightBlock(const QString &text) { - QString buf; + QByteArray buf; bool inCommentMode = false; bool inStringMode = (previousBlockState() == 1); QTextCharFormat emptyFormat; int i=0; for (i=0; i < text.length(); i++) { - const QChar c = text.at(i); + char c = text.at(i).toLatin1(); if (inCommentMode) { setFormat(i, 1, m_formats[CMakeCommentFormat]); } else { @@ -80,7 +80,7 @@ void CMakeHighlighter::highlightBlock(const QString &text) } else { buf += c; } - } else if (c.isSpace()) { + } else if (text.at(i).isSpace()) { if (!inStringMode) buf.clear(); else diff --git a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp index c683053457..16354946e4 100644 --- a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp @@ -36,10 +36,12 @@ #include <projectexplorer/target.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/buildsteplist.h> +#include <utils/fileutils.h> using namespace CMakeProjectManager; using namespace CMakeProjectManager::Internal; +using namespace Utils; CMakeLocatorFilter::CMakeLocatorFilter() { @@ -73,7 +75,8 @@ QList<Locator::FilterEntry> CMakeLocatorFilter::matchesFor(QFutureInterface<Loca foreach (CMakeBuildTarget ct, cmakeProject->buildTargets()) { if (ct.title.contains(entry)) { Locator::FilterEntry entry(this, ct.title, cmakeProject->document()->fileName()); - entry.extraInfo = cmakeProject->document()->fileName(); + entry.extraInfo = FileUtils::shortNativePath( + FileName::fromString(cmakeProject->document()->fileName())); result.append(entry); } } diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp index d72616b764..b4798ed35b 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp @@ -32,6 +32,7 @@ #include "cmakebuildconfiguration.h" #include <coreplugin/icore.h> +#include <utils/hostosinfo.h> #include <utils/pathchooser.h> #include <utils/fancylineedit.h> #include <projectexplorer/kitinformation.h> @@ -80,8 +81,8 @@ namespace Internal { bool isNinja() const; QString displayName() const; - QString generatorArgument() const; - QString generator() const; + QByteArray generatorArgument() const; + QByteArray generator() const; private: ProjectExplorer::Kit *m_kit; @@ -110,37 +111,36 @@ bool GeneratorInfo::isNinja() const { return m_isNinja; } -QString GeneratorInfo::generator() const +QByteArray GeneratorInfo::generator() const { if (!m_kit) - return QString(); + return QByteArray(); ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit); ProjectExplorer::Abi targetAbi = tc->targetAbi(); if (m_isNinja) { - return QLatin1String("Ninja"); + return "Ninja"; } else if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) { if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2005Flavor || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2008Flavor || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2010Flavor || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2012Flavor) { - return QLatin1String("NMake Makefiles"); + return "NMake Makefiles"; } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { -#ifdef Q_OS_WIN - return QLatin1String("MinGW Makefiles"); -#else - return QLatin1String("Unix Makefiles"); -#endif + if (Utils::HostOsInfo::isWindowsHost()) + return "MinGW Makefiles"; + else + return "Unix Makefiles"; } } - return QLatin1String("Unix Makefiles"); + return "Unix Makefiles"; } -QString GeneratorInfo::generatorArgument() const +QByteArray GeneratorInfo::generatorArgument() const { - QString tmp = generator(); + QByteArray tmp = generator(); if (tmp.isEmpty()) return tmp; - return QLatin1String("-GCodeBlocks - ") + tmp; + return QByteArray("-GCodeBlocks - ") + tmp; } QString GeneratorInfo::displayName() const @@ -158,11 +158,10 @@ QString GeneratorInfo::displayName() const || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2012Flavor) { return QApplication::tr("NMake Generator (%1)").arg(m_kit->displayName()); } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { -#ifdef Q_OS_WIN + if (Utils::HostOsInfo::isWindowsHost()) return QApplication::tr("MinGW Generator (%1)").arg(m_kit->displayName()); -#else + else return QApplication::tr("Unix Generator (%1)").arg(m_kit->displayName()); -#endif } } else { // Non windows @@ -268,7 +267,7 @@ CMakeManager *CMakeOpenProjectWizard::cmakeManager() const bool CMakeOpenProjectWizard::hasInSourceBuild() const { - QFileInfo fi(m_sourceDirectory + "/CMakeCache.txt"); + QFileInfo fi(m_sourceDirectory + QLatin1String("/CMakeCache.txt")); if (fi.exists()) return true; return false; @@ -280,7 +279,7 @@ bool CMakeOpenProjectWizard::existsUpToDateXmlFile() const if (!cbpFile.isEmpty()) { // We already have a cbp file QFileInfo cbpFileInfo(cbpFile); - QFileInfo cmakeListsFileInfo(sourceDirectory() + "/CMakeLists.txt"); + QFileInfo cmakeListsFileInfo(sourceDirectory() + QLatin1String("/CMakeLists.txt")); if (cbpFileInfo.lastModified() > cmakeListsFileInfo.lastModified()) return true; @@ -395,7 +394,7 @@ ChooseCMakePage::ChooseCMakePage(CMakeOpenProjectWizard *cmakeWizard) // Show a field for the user to enter m_cmakeExecutable = new Utils::PathChooser(this); m_cmakeExecutable->setExpectedKind(Utils::PathChooser::ExistingCommand); - fl->addRow("cmake Executable:", m_cmakeExecutable); + fl->addRow(tr("cmake Executable:"), m_cmakeExecutable); connect(m_cmakeExecutable, SIGNAL(editingFinished()), this, SLOT(cmakeExecutableChanged())); @@ -500,18 +499,18 @@ void CMakeRunPage::initWidgets() setMinimumSize(600, 400); } -QString CMakeRunPage::cachedGeneratorFromFile(const QString &cache) +QByteArray CMakeRunPage::cachedGeneratorFromFile(const QString &cache) { QFile fi(cache); if (fi.exists()) { // Cache exists, then read it... if (fi.open(QIODevice::ReadOnly | QIODevice::Text)) { while (!fi.atEnd()) { - QString line = fi.readLine(); + QByteArray line = fi.readLine(); if (line.startsWith("CMAKE_GENERATOR:INTERNAL=")) { int splitpos = line.indexOf('='); if (splitpos != -1) { - QString cachedGenerator = line.mid(splitpos + 1).trimmed(); + QByteArray cachedGenerator = line.mid(splitpos + 1).trimmed(); if (!cachedGenerator.isEmpty()) return cachedGenerator; } @@ -519,7 +518,7 @@ QString CMakeRunPage::cachedGeneratorFromFile(const QString &cache) } } } - return QString(); + return QByteArray(); } void CMakeRunPage::initializePage() @@ -570,7 +569,7 @@ void CMakeRunPage::initializePage() if (m_mode == Initial) { // Try figuring out generator and toolchain from CMakeCache.txt - QString cachedGenerator = cachedGeneratorFromFile(m_buildDirectory + "/CMakeCache.txt"); + QByteArray cachedGenerator = cachedGeneratorFromFile(m_buildDirectory + QLatin1String("/CMakeCache.txt")); m_generatorComboBox->show(); QList<ProjectExplorer::Kit *> kitList = @@ -602,7 +601,7 @@ void CMakeRunPage::initializePage() ninja, true); foreach (const GeneratorInfo &info, infos) - m_generatorComboBox->addItem(info.displayName(), qVariantFromValue(info)); + m_generatorComboBox->addItem(info.displayName(), qVariantFromValue(info)); } } @@ -653,7 +652,7 @@ void CMakeRunPage::runCMake() connect(m_cmakeProcess, SIGNAL(readyReadStandardError()), this, SLOT(cmakeReadyReadStandardError())); connect(m_cmakeProcess, SIGNAL(finished(int)), this, SLOT(cmakeFinished())); cmakeManager->createXmlFile(m_cmakeProcess, m_argumentsLineEdit->text(), m_cmakeWizard->sourceDirectory(), - m_buildDirectory, env, generatorInfo.generatorArgument()); + m_buildDirectory, env, QString::fromLatin1(generatorInfo.generatorArgument())); } else { m_runCMake->setEnabled(true); m_argumentsLineEdit->setEnabled(true); @@ -678,7 +677,7 @@ void CMakeRunPage::cmakeReadyReadStandardOutput() tf.setFont(font); tf.setForeground(m_output->palette().color(QPalette::Text)); - cursor.insertText(m_cmakeProcess->readAllStandardOutput(), tf); + cursor.insertText(QString::fromLocal8Bit(m_cmakeProcess->readAllStandardOutput()), tf); } void CMakeRunPage::cmakeReadyReadStandardError() @@ -692,7 +691,7 @@ void CMakeRunPage::cmakeReadyReadStandardError() tf.setFont(boldFont); tf.setForeground(mix_colors(m_output->palette().color(QPalette::Text), QColor(Qt::red))); - cursor.insertText(m_cmakeProcess->readAllStandardError(), tf); + cursor.insertText(QString::fromLocal8Bit(m_cmakeProcess->readAllStandardError()), tf); } void CMakeRunPage::cmakeFinished() diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h index 5a3c0cf84d..c034230ae3 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h @@ -179,7 +179,7 @@ private slots: void cmakeReadyReadStandardError(); private: void initWidgets(); - QString cachedGeneratorFromFile(const QString &cache); + QByteArray cachedGeneratorFromFile(const QString &cache); CMakeOpenProjectWizard *m_cmakeWizard; QPlainTextEdit *m_output; QPushButton *m_runCMake; diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 386c27cd65..63cc7ea4ab 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -41,7 +41,6 @@ #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorer.h> #include <projectexplorer/headerpath.h> -#include <projectexplorer/buildenvironmentwidget.h> #include <projectexplorer/buildsteplist.h> #include <projectexplorer/buildmanager.h> #include <projectexplorer/kitinformation.h> @@ -53,9 +52,12 @@ #include <cpptools/ModelManagerInterface.h> #include <extensionsystem/pluginmanager.h> #include <utils/qtcassert.h> +#include <utils/stringutils.h> #include <coreplugin/icore.h> #include <coreplugin/infobar.h> +#include <coreplugin/documentmanager.h> #include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/variablemanager.h> #include <QMap> #include <QDebug> @@ -195,7 +197,8 @@ void CMakeProject::changeBuildDirectory(CMakeBuildConfiguration *bc, const QStri QString CMakeProject::defaultBuildDirectory() const { - return projectDirectory() + QLatin1String("-build"); + return Utils::expandMacros(Core::DocumentManager::instance()->buildDirectory(), + Core::VariableManager::instance()->macroExpander()); } bool CMakeProject::parseCMakeLists() @@ -208,7 +211,7 @@ bool CMakeProject::parseCMakeLists() CMakeBuildConfiguration *activeBC = static_cast<CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration()); foreach (Core::IEditor *editor, Core::EditorManager::instance()->openedEditors()) if (isProjectFile(editor->document()->fileName())) - editor->document()->infoBar()->removeInfo(QLatin1String("CMakeEditor.RunCMake")); + editor->document()->infoBar()->removeInfo(Core::Id("CMakeEditor.RunCMake")); // Find cbp file QString cbpFile = CMakeManager::findCbpFile(activeBC->buildDirectory()); @@ -248,7 +251,7 @@ bool CMakeProject::parseCMakeLists() projectFiles.insert(node->path()); } else { // Manually add the CMakeLists.txt file - QString cmakeListTxt = projectDirectory() + "/CMakeLists.txt"; + QString cmakeListTxt = projectDirectory() + QLatin1String("/CMakeLists.txt"); bool generated = false; fileList.append(new ProjectExplorer::FileNode(cmakeListTxt, ProjectExplorer::ProjectFileType, generated)); projectFiles.insert(cmakeListTxt); @@ -276,13 +279,13 @@ bool CMakeProject::parseCMakeLists() // TOOD this code ain't very pretty ... m_uicCommand.clear(); - QFile cmakeCache(activeBC->buildDirectory() + "/CMakeCache.txt"); + QFile cmakeCache(activeBC->buildDirectory() + QLatin1String("/CMakeCache.txt")); cmakeCache.open(QIODevice::ReadOnly); while (!cmakeCache.atEnd()) { - QString line = cmakeCache.readLine(); + QByteArray line = cmakeCache.readLine(); if (line.startsWith("QT_UIC_EXECUTABLE")) { if (int pos = line.indexOf('=')) { - m_uicCommand = line.mid(pos + 1).trimmed(); + m_uicCommand = QString::fromLocal8Bit(line.mid(pos + 1).trimmed()); } break; } @@ -304,13 +307,15 @@ bool CMakeProject::parseCMakeLists() allIncludePaths.append(projectDirectory()); allIncludePaths.append(cbpparser.includeFiles()); + QStringList cxxflags; // FIXME: We should do better than this! + QByteArray allDefines; - allDefines.append(tc->predefinedMacros(QStringList())); + allDefines.append(tc->predefinedMacros(cxxflags)); allDefines.append(cbpparser.defines()); QStringList allFrameworkPaths; QList<ProjectExplorer::HeaderPath> allHeaderPaths; - allHeaderPaths = tc->systemHeaderPaths(SysRootKitInformation::sysRoot(k)); + allHeaderPaths = tc->systemHeaderPaths(cxxflags, SysRootKitInformation::sysRoot(k)); foreach (const ProjectExplorer::HeaderPath &headerPath, allHeaderPaths) { if (headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath) allFrameworkPaths.append(headerPath.path()); @@ -512,13 +517,6 @@ CMakeManager *CMakeProject::projectManager() const return m_manager; } -QList<ProjectExplorer::BuildConfigWidget*> CMakeProject::subConfigWidgets() -{ - QList<ProjectExplorer::BuildConfigWidget*> list; - list << new BuildEnvironmentWidget; - return list; -} - ProjectExplorer::ProjectNode *CMakeProject::rootProjectNode() const { return m_rootNode; @@ -544,7 +542,7 @@ bool CMakeProject::fromMap(const QVariantMap &map) Kit *k = copw.kit(); Target *t = new Target(this, k); CMakeBuildConfiguration *bc(new CMakeBuildConfiguration(t)); - bc->setDefaultDisplayName("all"); + bc->setDefaultDisplayName(QLatin1String("all")); bc->setUseNinja(copw.useNinja()); bc->setBuildDirectory(copw.buildDirectory()); ProjectExplorer::BuildStepList *buildSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); @@ -555,7 +553,7 @@ bool CMakeProject::fromMap(const QVariantMap &map) MakeStep *cleanMakeStep = new MakeStep(cleanSteps); cleanSteps->insertStep(0, cleanMakeStep); - cleanMakeStep->setAdditionalArguments("clean"); + cleanMakeStep->setAdditionalArguments(QLatin1String("clean")); cleanMakeStep->setClean(true); t->addBuildConfiguration(bc); @@ -596,11 +594,11 @@ bool CMakeProject::fromMap(const QVariantMap &map) parseCMakeLists(); - if (!hasUserFile && hasBuildTarget("all")) { + if (!hasUserFile && hasBuildTarget(QLatin1String("all"))) { MakeStep *makeStep = qobject_cast<MakeStep *>( activeTarget()->activeBuildConfiguration()->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD)->at(0)); Q_ASSERT(makeStep); - makeStep->setBuildTarget("all", true); + makeStep->setBuildTarget(QLatin1String("all"), true); } connect(Core::EditorManager::instance(), SIGNAL(editorAboutToClose(Core::IEditor*)), @@ -693,7 +691,7 @@ void CMakeProject::updateRunConfigurations(Target *t) continue; if (ct.executable.isEmpty()) continue; - if (ct.title.endsWith("/fast")) + if (ct.title.endsWith(QLatin1String("/fast"))) continue; QList<CMakeRunConfiguration *> list = existingRunConfigurations.values(ct.title); if (!list.isEmpty()) { @@ -745,7 +743,7 @@ void CMakeProject::createUiCodeModelSupport() // Find all ui files foreach (const QString &uiFile, m_files) { - if (uiFile.endsWith(".ui")) { + if (uiFile.endsWith(QLatin1String(".ui"))) { // UI file, not convert to QString uiHeaderFilePath = uiHeaderFile(uiFile); QMap<QString, CMakeUiCodeModelSupport *>::iterator it @@ -874,7 +872,7 @@ QString CMakeFile::suggestedFileName() const QString CMakeFile::mimeType() const { - return Constants::CMAKEMIMETYPE; + return QLatin1String(Constants::CMAKEMIMETYPE); } @@ -910,7 +908,7 @@ bool CMakeFile::reload(QString *errorString, ReloadFlag flag, ChangeType type) return true; } -CMakeBuildSettingsWidget::CMakeBuildSettingsWidget() : m_buildConfiguration(0) +CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) : m_buildConfiguration(0) { QFormLayout *fl = new QFormLayout(this); fl->setContentsMargins(20, -1, 0, -1); @@ -934,21 +932,15 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget() : m_buildConfiguration(0) hbox->addWidget(m_changeButton); fl->addRow(tr("Build directory:"), hbox); -} -QString CMakeBuildSettingsWidget::displayName() const -{ - return "CMake"; -} - -void CMakeBuildSettingsWidget::init(BuildConfiguration *bc) -{ - m_buildConfiguration = static_cast<CMakeBuildConfiguration *>(bc); + m_buildConfiguration = bc; m_pathLineEdit->setText(m_buildConfiguration->buildDirectory()); if (m_buildConfiguration->buildDirectory() == bc->target()->project()->projectDirectory()) m_changeButton->setEnabled(false); else m_changeButton->setEnabled(true); + + setDisplayName(tr("CMake")); } void CMakeBuildSettingsWidget::openChangeBuildDirectoryDialog() @@ -985,7 +977,7 @@ bool CMakeCbpParser::parseCbpFile(const QString &fileName) while (!atEnd()) { readNext(); - if (name() == "CodeBlocks_project_file") { + if (name() == QLatin1String("CodeBlocks_project_file")) { parseCodeBlocks_project_file(); } else if (isStartElement()) { parseUnknownElement(); @@ -1005,7 +997,7 @@ void CMakeCbpParser::parseCodeBlocks_project_file() readNext(); if (isEndElement()) { return; - } else if (name() == "Project") { + } else if (name() == QLatin1String("Project")) { parseProject(); } else if (isStartElement()) { parseUnknownElement(); @@ -1019,11 +1011,11 @@ void CMakeCbpParser::parseProject() readNext(); if (isEndElement()) { return; - } else if (name() == "Option") { + } else if (name() == QLatin1String("Option")) { parseOption(); - } else if (name() == "Unit") { + } else if (name() == QLatin1String("Unit")) { parseUnit(); - } else if (name() == "Build") { + } else if (name() == QLatin1String("Build")) { parseBuild(); } else if (isStartElement()) { parseUnknownElement(); @@ -1037,7 +1029,7 @@ void CMakeCbpParser::parseBuild() readNext(); if (isEndElement()) { return; - } else if (name() == "Target") { + } else if (name() == QLatin1String("Target")) { parseBuildTarget(); } else if (isStartElement()) { parseUnknownElement(); @@ -1050,18 +1042,18 @@ void CMakeCbpParser::parseBuildTarget() m_buildTargetType = false; m_buildTarget.clear(); - if (attributes().hasAttribute("title")) - m_buildTarget.title = attributes().value("title").toString(); + if (attributes().hasAttribute(QLatin1String("title"))) + m_buildTarget.title = attributes().value(QLatin1String("title")).toString(); while (!atEnd()) { readNext(); if (isEndElement()) { - if (m_buildTargetType || m_buildTarget.title == "all" || m_buildTarget.title == "install") { + if (m_buildTargetType || m_buildTarget.title == QLatin1String("all") || m_buildTarget.title == QLatin1String("install")) { m_buildTargets.append(m_buildTarget); } return; - } else if (name() == "Compiler") { + } else if (name() == QLatin1String("Compiler")) { parseCompiler(); - } else if (name() == "Option") { + } else if (name() == QLatin1String("Option")) { parseBuildTargetOption(); } else if (isStartElement()) { parseUnknownElement(); @@ -1071,21 +1063,25 @@ void CMakeCbpParser::parseBuildTarget() void CMakeCbpParser::parseBuildTargetOption() { - if (attributes().hasAttribute("output")) { - m_buildTarget.executable = attributes().value("output").toString(); - } else if (attributes().hasAttribute("type") && (attributes().value("type") == "1" || attributes().value("type") == "0")) { + if (attributes().hasAttribute(QLatin1String("output"))) { + m_buildTarget.executable = attributes().value(QLatin1String("output")).toString(); + } else if (attributes().hasAttribute(QLatin1String("type")) + && (attributes().value(QLatin1String("type")) == QLatin1String("1") + || attributes().value(QLatin1String("type")) == QLatin1String("0"))) { m_buildTargetType = true; - } else if (attributes().hasAttribute("type") && (attributes().value("type") == "3" || attributes().value("type") == "2")) { + } else if (attributes().hasAttribute(QLatin1String("type")) + && (attributes().value(QLatin1String("type")) == QLatin1String("3") + || attributes().value(QLatin1String("type")) == QLatin1String("2"))) { m_buildTargetType = true; m_buildTarget.library = true; - } else if (attributes().hasAttribute("working_dir")) { - m_buildTarget.workingDirectory = attributes().value("working_dir").toString(); + } else if (attributes().hasAttribute(QLatin1String("working_dir"))) { + m_buildTarget.workingDirectory = attributes().value(QLatin1String("working_dir")).toString(); } while (!atEnd()) { readNext(); if (isEndElement()) { return; - } else if (name() == "MakeCommand") { + } else if (name() == QLatin1String("MakeCommand")) { parseMakeCommand(); } else if (isStartElement()) { parseUnknownElement(); @@ -1100,11 +1096,11 @@ QString CMakeCbpParser::projectName() const void CMakeCbpParser::parseOption() { - if (attributes().hasAttribute("title")) - m_projectName = attributes().value("title").toString(); + if (attributes().hasAttribute(QLatin1String("title"))) + m_projectName = attributes().value(QLatin1String("title")).toString(); - if (attributes().hasAttribute("compiler")) - m_compiler = attributes().value("compiler").toString(); + if (attributes().hasAttribute(QLatin1String("compiler"))) + m_compiler = attributes().value(QLatin1String("compiler")).toString(); while (!atEnd()) { readNext(); @@ -1122,9 +1118,9 @@ void CMakeCbpParser::parseMakeCommand() readNext(); if (isEndElement()) { return; - } else if (name() == "Build") { + } else if (name() == QLatin1String("Build")) { parseBuildTargetBuild(); - } else if (name() == "Clean") { + } else if (name() == QLatin1String("Clean")) { parseBuildTargetClean(); } else if (isStartElement()) { parseUnknownElement(); @@ -1134,8 +1130,8 @@ void CMakeCbpParser::parseMakeCommand() void CMakeCbpParser::parseBuildTargetBuild() { - if (attributes().hasAttribute("command")) - m_buildTarget.makeCommand = attributes().value("command").toString(); + if (attributes().hasAttribute(QLatin1String("command"))) + m_buildTarget.makeCommand = attributes().value(QLatin1String("command")).toString(); while (!atEnd()) { readNext(); if (isEndElement()) { @@ -1148,8 +1144,8 @@ void CMakeCbpParser::parseBuildTargetBuild() void CMakeCbpParser::parseBuildTargetClean() { - if (attributes().hasAttribute("command")) - m_buildTarget.makeCleanCommand = attributes().value("command").toString(); + if (attributes().hasAttribute(QLatin1String("command"))) + m_buildTarget.makeCleanCommand = attributes().value(QLatin1String("command")).toString(); while (!atEnd()) { readNext(); if (isEndElement()) { @@ -1166,7 +1162,7 @@ void CMakeCbpParser::parseCompiler() readNext(); if (isEndElement()) { return; - } else if (name() == "Add") { + } else if (name() == QLatin1String("Add")) { parseAdd(); } else if (isStartElement()) { parseUnknownElement(); @@ -1179,24 +1175,24 @@ void CMakeCbpParser::parseAdd() // CMake only supports <Add option=\> and <Add directory=\> const QXmlStreamAttributes addAttributes = attributes(); - const QString includeDirectory = addAttributes.value("directory").toString(); + const QString includeDirectory = addAttributes.value(QLatin1String("directory")).toString(); // allow adding multiple times because order happens if (!includeDirectory.isEmpty()) { m_includeFiles.append(includeDirectory); } - QString compilerOption = addAttributes.value("option").toString(); + QString compilerOption = addAttributes.value(QLatin1String("option")).toString(); // defining multiple times a macro to the same value makes no sense if (!compilerOption.isEmpty() && !m_compilerOptions.contains(compilerOption)) { m_compilerOptions.append(compilerOption); - int macroNameIndex = compilerOption.indexOf("-D") + 2; + int macroNameIndex = compilerOption.indexOf(QLatin1String("-D")) + 2; if (macroNameIndex != 1) { - int assignIndex = compilerOption.indexOf('=', macroNameIndex); + int assignIndex = compilerOption.indexOf(QLatin1Char('='), macroNameIndex); if (assignIndex != -1) { compilerOption[assignIndex] = ' '; } m_defines.append("#define "); - m_defines.append(compilerOption.mid(macroNameIndex).toAscii()); + m_defines.append(compilerOption.mid(macroNameIndex).toLatin1()); m_defines.append('\n'); } } @@ -1214,7 +1210,7 @@ void CMakeCbpParser::parseAdd() void CMakeCbpParser::parseUnit() { //qDebug()<<stream.attributes().value("filename"); - QString fileName = attributes().value("filename").toString(); + QString fileName = attributes().value(QLatin1String("filename")).toString(); m_parsingCmakeUnit = false; while (!atEnd()) { readNext(); @@ -1226,9 +1222,9 @@ void CMakeCbpParser::parseUnit() } else { bool generated = false; QString onlyFileName = QFileInfo(fileName).fileName(); - if ( (onlyFileName.startsWith("moc_") && onlyFileName.endsWith(".cxx")) - || (onlyFileName.startsWith("ui_") && onlyFileName.endsWith(".h")) - || (onlyFileName.startsWith("qrc_") && onlyFileName.endsWith(".cxx"))) + if ( (onlyFileName.startsWith(QLatin1String("moc_")) && onlyFileName.endsWith(QLatin1String(".cxx"))) + || (onlyFileName.startsWith(QLatin1String("ui_")) && onlyFileName.endsWith(QLatin1String(".h"))) + || (onlyFileName.startsWith(QLatin1String("qrc_")) && onlyFileName.endsWith(QLatin1String(".cxx")))) generated = true; if (fileName.endsWith(QLatin1String(".qrc"))) @@ -1239,7 +1235,7 @@ void CMakeCbpParser::parseUnit() m_processedUnits.insert(fileName); } return; - } else if (name() == "Option") { + } else if (name() == QLatin1String("Option")) { parseUnitOption(); } else if (isStartElement()) { parseUnknownElement(); @@ -1249,7 +1245,7 @@ void CMakeCbpParser::parseUnit() void CMakeCbpParser::parseUnitOption() { - if (attributes().hasAttribute("virtualFolder")) + if (attributes().hasAttribute(QLatin1String("virtualFolder"))) m_parsingCmakeUnit = true; while (!atEnd()) { diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index a68596c170..8c8a74a869 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -37,8 +37,8 @@ #include <projectexplorer/project.h> #include <projectexplorer/projectnodes.h> -#include <projectexplorer/buildstep.h> #include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/namedwidget.h> #include <coreplugin/idocument.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/ieditor.h> @@ -85,8 +85,6 @@ public: Core::IDocument *document() const; CMakeManager *projectManager() const; - QList<ProjectExplorer::BuildConfigWidget*> subConfigWidgets(); - ProjectExplorer::ProjectNode *rootProjectNode() const; QStringList files(FilesMode fileMode) const; @@ -226,15 +224,11 @@ private: QString m_fileName; }; -class CMakeBuildSettingsWidget : public ProjectExplorer::BuildConfigWidget +class CMakeBuildSettingsWidget : public ProjectExplorer::NamedWidget { Q_OBJECT public: - CMakeBuildSettingsWidget(); - QString displayName() const; - - // This is called to set up the config widget before showing it - void init(ProjectExplorer::BuildConfiguration *bc); + CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc); private slots: void openChangeBuildDirectoryDialog(); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index db3e65d1bf..f29a649852 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -133,7 +133,7 @@ ProjectExplorer::Project *CMakeManager::openProject(const QString &fileName, QSt QString CMakeManager::mimeType() const { - return Constants::CMAKEMIMETYPE; + return QLatin1String(Constants::CMAKEMIMETYPE); } QString CMakeManager::cmakeExecutable() const @@ -224,7 +224,7 @@ QString CMakeManager::qtVersionForQMake(const QString &qmakePath) qWarning("Timeout running '%s'.", qPrintable(qmakePath)); return QString(); } - QString output = qmake.readAllStandardOutput(); + QString output = QString::fromLocal8Bit(qmake.readAllStandardOutput()); QRegExp regexp(QLatin1String("(QMake version|Qmake version:)[\\s]*([\\d.]*)")); regexp.indexIn(output); if (regexp.cap(2).startsWith(QLatin1String("2."))) { @@ -250,102 +250,26 @@ CMakeSettingsPage::CMakeSettingsPage() ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_TR_CATEGORY)); setCategoryIcon(QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY_ICON)); - m_userCmake.process = 0; - m_pathCmake.process = 0; - m_userCmake.hasCodeBlocksMsvcGenerator = false; - m_pathCmake.hasCodeBlocksMsvcGenerator = false; - m_userCmake.hasCodeBlocksNinjaGenerator = false; - m_pathCmake.hasCodeBlocksNinjaGenerator = false; QSettings *settings = Core::ICore::settings(); settings->beginGroup(QLatin1String("CMakeSettings")); - m_userCmake.executable = settings->value(QLatin1String("cmakeExecutable")).toString(); + m_cmakeValidatorForUser.setCMakeExecutable(settings->value(QLatin1String("cmakeExecutable")).toString()); settings->endGroup(); - updateInfo(&m_userCmake); - m_pathCmake.executable = findCmakeExecutable(); - updateInfo(&m_pathCmake); -} - -void CMakeSettingsPage::startProcess(CMakeValidator *cmakeValidator) -{ - cmakeValidator->process = new QProcess(); - - if (cmakeValidator == &m_pathCmake) // ugly - connect(cmakeValidator->process, SIGNAL(finished(int)), - this, SLOT(userCmakeFinished())); - else - connect(cmakeValidator->process, SIGNAL(finished(int)), - this, SLOT(pathCmakeFinished())); - - cmakeValidator->process->start(cmakeValidator->executable, QStringList(QLatin1String("--help"))); - cmakeValidator->process->waitForStarted(); -} - -void CMakeSettingsPage::userCmakeFinished() -{ - cmakeFinished(&m_userCmake); -} - -void CMakeSettingsPage::pathCmakeFinished() -{ - cmakeFinished(&m_pathCmake); -} - -void CMakeSettingsPage::cmakeFinished(CMakeValidator *cmakeValidator) const -{ - if (cmakeValidator->process) { - cmakeValidator->process->waitForFinished(); - QString response = cmakeValidator->process->readAll(); - QRegExp versionRegexp(QLatin1String("^cmake version ([\\d\\.]*)")); - versionRegexp.indexIn(response); - - //m_supportsQtCreator = response.contains(QLatin1String("QtCreator")); - cmakeValidator->hasCodeBlocksNinjaGenerator = response.contains(QLatin1String("CodeBlocks - Ninja")); - cmakeValidator->hasCodeBlocksMsvcGenerator = response.contains(QLatin1String("CodeBlocks - NMake Makefiles")); - cmakeValidator->version = versionRegexp.cap(1); - if (!(versionRegexp.capturedTexts().size() > 3)) - cmakeValidator->version += QLatin1Char('.') + versionRegexp.cap(3); - - if (cmakeValidator->version.isEmpty()) - cmakeValidator->state = CMakeValidator::INVALID; - else - cmakeValidator->state = CMakeValidator::VALID; - - cmakeValidator->process->deleteLater(); - cmakeValidator->process = 0; - } + m_cmakeValidatorForSystem.setCMakeExecutable(findCmakeExecutable()); } bool CMakeSettingsPage::isCMakeExecutableValid() const { - if (m_userCmake.state == CMakeValidator::RUNNING) { - disconnect(m_userCmake.process, SIGNAL(finished(int)), - this, SLOT(userCmakeFinished())); - m_userCmake.process->waitForFinished(); - // Parse the output now - cmakeFinished(&m_userCmake); - } - - if (m_userCmake.state == CMakeValidator::VALID) + if (m_cmakeValidatorForUser.isValid()) return true; - if (m_pathCmake.state == CMakeValidator::RUNNING) { - disconnect(m_userCmake.process, SIGNAL(finished(int)), - this, SLOT(pathCmakeFinished())); - m_pathCmake.process->waitForFinished(); - // Parse the output now - cmakeFinished(&m_pathCmake); - } - return m_pathCmake.state == CMakeValidator::VALID; + + return m_cmakeValidatorForSystem.isValid(); } CMakeSettingsPage::~CMakeSettingsPage() { - if (m_userCmake.process) - m_userCmake.process->waitForFinished(); - delete m_userCmake.process; - if (m_pathCmake.process) - m_pathCmake.process->waitForFinished(); - delete m_pathCmake.process; + m_cmakeValidatorForUser.cancel(); + m_cmakeValidatorForSystem.cancel(); } QString CMakeSettingsPage::findCmakeExecutable() const @@ -363,28 +287,15 @@ QWidget *CMakeSettingsPage::createPage(QWidget *parent) m_pathchooser->setExpectedKind(Utils::PathChooser::ExistingCommand); formLayout->addRow(tr("Executable:"), m_pathchooser); formLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding)); - m_pathchooser->setPath(m_userCmake.executable); + m_pathchooser->setPath(m_cmakeValidatorForUser.cmakeExecutable()); return outerWidget; } -void CMakeSettingsPage::updateInfo(CMakeValidator *cmakeValidator) -{ - QFileInfo fi(cmakeValidator->executable); - if (fi.exists() && fi.isExecutable()) { - // Run it to find out more - cmakeValidator->state = CMakeValidator::RUNNING; - startProcess(cmakeValidator); - } else { - cmakeValidator->state = CMakeValidator::INVALID; - } - saveSettings(); -} - void CMakeSettingsPage::saveSettings() const { QSettings *settings = Core::ICore::settings(); settings->beginGroup(QLatin1String("CMakeSettings")); - settings->setValue(QLatin1String("cmakeExecutable"), m_userCmake.executable); + settings->setValue(QLatin1String("cmakeExecutable"), m_cmakeValidatorForUser.cmakeExecutable()); settings->endGroup(); } @@ -392,10 +303,10 @@ void CMakeSettingsPage::apply() { if (!m_pathchooser) // page was never shown return; - if (m_userCmake.executable == m_pathchooser->path()) + if (m_cmakeValidatorForUser.cmakeExecutable() == m_pathchooser->path()) return; - m_userCmake.executable = m_pathchooser->path(); - updateInfo(&m_userCmake); + m_cmakeValidatorForUser.setCMakeExecutable(m_pathchooser->path()); + saveSettings(); } void CMakeSettingsPage::finish() @@ -407,36 +318,46 @@ QString CMakeSettingsPage::cmakeExecutable() const { if (!isCMakeExecutableValid()) return QString(); - if (m_userCmake.state == CMakeValidator::VALID) - return m_userCmake.executable; - else - return m_pathCmake.executable; + + if (m_cmakeValidatorForUser.isValid()) + return m_cmakeValidatorForUser.cmakeExecutable(); + if (m_cmakeValidatorForSystem.isValid()) + return m_cmakeValidatorForSystem.cmakeExecutable(); + return QString(); } void CMakeSettingsPage::setCMakeExecutable(const QString &executable) { - if (m_userCmake.executable == executable) + if (m_cmakeValidatorForUser.cmakeExecutable() == executable) return; - m_userCmake.executable = executable; - updateInfo(&m_userCmake); + m_cmakeValidatorForUser.setCMakeExecutable(executable); } bool CMakeSettingsPage::hasCodeBlocksMsvcGenerator() const { - if (!isCMakeExecutableValid()) - return false; - if (m_userCmake.state == CMakeValidator::VALID) - return m_userCmake.hasCodeBlocksMsvcGenerator; - else - return m_pathCmake.hasCodeBlocksMsvcGenerator; + if (m_cmakeValidatorForUser.isValid()) + return m_cmakeValidatorForUser.hasCodeBlocksMsvcGenerator(); + if (m_cmakeValidatorForSystem.isValid()) + return m_cmakeValidatorForSystem.hasCodeBlocksMsvcGenerator(); + return false; } bool CMakeSettingsPage::hasCodeBlocksNinjaGenerator() const { - if (!isCMakeExecutableValid()) - return false; - if (m_userCmake.state == CMakeValidator::VALID) - return m_userCmake.hasCodeBlocksNinjaGenerator; - else - return m_pathCmake.hasCodeBlocksNinjaGenerator; + if (m_cmakeValidatorForUser.isValid()) + return m_cmakeValidatorForUser.hasCodeBlocksNinjaGenerator(); + if (m_cmakeValidatorForSystem.isValid()) + return m_cmakeValidatorForSystem.hasCodeBlocksNinjaGenerator(); + return false; +} + +TextEditor::Keywords CMakeSettingsPage::keywords() +{ + if (m_cmakeValidatorForUser.isValid()) + return m_cmakeValidatorForUser.keywords(); + + if (m_cmakeValidatorForSystem.isValid()) + return m_cmakeValidatorForSystem.keywords(); + + return TextEditor::Keywords(QStringList(), QStringList(), QMap<QString, QStringList>()); } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h index e9665232ad..ef75fd74e9 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h @@ -35,6 +35,7 @@ #include <projectexplorer/project.h> #include <projectexplorer/projectnodes.h> #include <coreplugin/icontext.h> +#include <texteditor/codeassist/keywordscompletionassist.h> #include <utils/environment.h> #include <utils/pathchooser.h> @@ -42,9 +43,11 @@ #include <QFuture> #include <QStringList> #include <QDir> +#include <QVector> #include <QAction> -QT_FORWARD_DECLARE_CLASS(QProcess) +#include "cmakevalidator.h" + QT_FORWARD_DECLARE_CLASS(QLabel) namespace Utils { @@ -95,17 +98,6 @@ private: ProjectExplorer::Project *m_contextProject; }; -struct CMakeValidator -{ - enum STATE { VALID, INVALID, RUNNING }; - STATE state; - QProcess *process; - bool hasCodeBlocksMsvcGenerator; - bool hasCodeBlocksNinjaGenerator; - QString version; - QString executable; -}; - class CMakeSettingsPage : public Core::IOptionsPage { Q_OBJECT @@ -124,20 +116,15 @@ public: bool hasCodeBlocksMsvcGenerator() const; bool hasCodeBlocksNinjaGenerator() const; -private slots: - void userCmakeFinished(); - void pathCmakeFinished(); + TextEditor::Keywords keywords(); private: - void cmakeFinished(CMakeValidator *cmakeValidator) const; void saveSettings() const; QString findCmakeExecutable() const; - void startProcess(CMakeValidator *cmakeValidator); - void updateInfo(CMakeValidator *cmakeValidator); Utils::PathChooser *m_pathchooser; - mutable CMakeValidator m_userCmake; - mutable CMakeValidator m_pathCmake; + CMakeValidator m_cmakeValidatorForUser; + CMakeValidator m_cmakeValidatorForSystem; }; } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro index b0b516944d..95c490f230 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro @@ -4,6 +4,8 @@ TARGET = CMakeProjectManager include(../../qtcreatorplugin.pri) include(cmakeprojectmanager_dependencies.pri) +DEFINES += QT_NO_CAST_FROM_ASCII + HEADERS = cmakeproject.h \ cmakeprojectplugin.h \ cmakeprojectmanager.h \ @@ -17,7 +19,9 @@ HEADERS = cmakeproject.h \ cmakeeditor.h \ cmakehighlighter.h \ cmakeuicodemodelsupport.h \ - cmakelocatorfilter.h + cmakelocatorfilter.h \ + cmakefilecompletionassist.h \ + cmakevalidator.h SOURCES = cmakeproject.cpp \ cmakeprojectplugin.cpp \ @@ -31,7 +35,9 @@ SOURCES = cmakeproject.cpp \ cmakeeditor.cpp \ cmakehighlighter.cpp \ cmakeuicodemodelsupport.cpp \ - cmakelocatorfilter.cpp + cmakelocatorfilter.cpp \ + cmakefilecompletionassist.cpp \ + cmakevalidator.cpp RESOURCES += cmakeproject.qrc diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs index 541176d66a..6637e47ded 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs @@ -5,22 +5,16 @@ import "../QtcPlugin.qbs" as QtcPlugin QtcPlugin { name: "CMakeProjectManager" + Depends { name: "cpp" } Depends { name: "Qt.widgets" } Depends { name: "Core" } - Depends { name: "ProjectExplorer" } Depends { name: "CppTools" } Depends { name: "CPlusPlus" } - Depends { name: "TextEditor" } Depends { name: "Locator" } + Depends { name: "ProjectExplorer" } + Depends { name: "TextEditor" } Depends { name: "QtSupport" } - - Depends { name: "cpp" } - cpp.includePaths: [ - ".", - "..", - "../../libs", - buildDirectory - ] + cpp.defines: base.concat(["QT_NO_CAST_FROM_ASCII"]) files: [ "CMakeProject.mimetypes.xml", @@ -30,6 +24,8 @@ QtcPlugin { "cmakeeditor.h", "cmakeeditorfactory.cpp", "cmakeeditorfactory.h", + "cmakefilecompletionassist.cpp", + "cmakefilecompletionassist.h", "cmakehighlighter.cpp", "cmakehighlighter.h", "cmakelocatorfilter.cpp", @@ -50,8 +46,10 @@ QtcPlugin { "cmakerunconfiguration.h", "cmakeuicodemodelsupport.cpp", "cmakeuicodemodelsupport.h", + "cmakevalidator.cpp", + "cmakevalidator.h", "makestep.cpp", - "makestep.h" + "makestep.h", ] } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp index 619a594d35..23540b83bd 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp @@ -35,6 +35,7 @@ #include "makestep.h" #include "cmakeprojectconstants.h" #include "cmakelocatorfilter.h" +#include "cmakefilecompletionassist.h" #include <coreplugin/icore.h> #include <coreplugin/mimedatabase.h> @@ -68,7 +69,7 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString * addAutoReleasedObject(new CMakeEditorFactory(manager)); addAutoReleasedObject(new CMakeLocatorFilter); - + addAutoReleasedObject(new CMakeFileCompletionAssistProvider(cmp)); return true; } diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp index a0601d8476..a6927b18a4 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp @@ -200,7 +200,7 @@ QString CMakeRunConfiguration::defaultDisplayName() const { if (m_title.isEmpty()) return tr("Run CMake kit"); - return m_title + (m_enabled ? "" : tr(" (disabled)")); + return m_title + (m_enabled ? QString() : tr(" (disabled)")); } QWidget *CMakeRunConfiguration::createConfigurationWidget() @@ -565,5 +565,5 @@ QString CMakeRunConfigurationFactory::buildTargetFromId(Core::Id id) Core::Id CMakeRunConfigurationFactory::idFromBuildTarget(const QString &target) { QString id = QString::fromLatin1(CMAKE_RC_PREFIX) + target; - return Core::Id(id.toUtf8().constData()); + return Core::Id(id.toUtf8()); } diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h index a4d99dbabf..acc6eaf679 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h @@ -49,7 +49,6 @@ class EnvironmentWidget; namespace CMakeProjectManager { namespace Internal { -class CMakeBuildConfiguration; class CMakeTarget; class CMakeRunConfiguration : public ProjectExplorer::LocalApplicationRunConfiguration diff --git a/src/plugins/cmakeprojectmanager/cmakevalidator.cpp b/src/plugins/cmakeprojectmanager/cmakevalidator.cpp new file mode 100644 index 0000000000..39c05d0bb5 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/cmakevalidator.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "cmakevalidator.h" + +#include <QProcess> +#include <QFileInfo> +#include <QTextDocument> + +using namespace CMakeProjectManager::Internal; + +/////////////////////////// +// CMakeValidator +/////////////////////////// +CMakeValidator::CMakeValidator() + : m_state(Invalid), m_process(0), m_hasCodeBlocksMsvcGenerator(false), m_hasCodeBlocksNinjaGenerator(false) +{ + +} + +CMakeValidator::~CMakeValidator() +{ + cancel(); +} + +void CMakeValidator::cancel() +{ + if (m_process) { + disconnect(m_process, SIGNAL(finished(int))); + m_process->waitForFinished(); + delete m_process; + m_process = 0; + } +} + +void CMakeValidator::setCMakeExecutable(const QString &executable) +{ + cancel(); + m_process = new QProcess(); + connect(m_process, SIGNAL(finished(int)), + this, SLOT(finished(int))); + + m_executable = executable; + QFileInfo fi(m_executable); + if (fi.exists() && fi.isExecutable()) { + // Run it to find out more + m_state = CMakeValidator::RunningBasic; + if (!startProcess(QStringList(QLatin1String("--help")))) + m_state = CMakeValidator::Invalid; + } else { + m_state = CMakeValidator::Invalid; + } +} + +void CMakeValidator::finished(int exitCode) +{ + if (exitCode) { + m_state = CMakeValidator::Invalid; + return; + } + if (m_state == CMakeValidator::RunningBasic) { + QByteArray response = m_process->readAll(); + QRegExp versionRegexp(QLatin1String("^cmake version ([\\d\\.]*)")); + versionRegexp.indexIn(QString::fromLocal8Bit(response)); + + //m_supportsQtCreator = response.contains(QLatin1String("QtCreator")); + m_hasCodeBlocksMsvcGenerator = response.contains("CodeBlocks - NMake Makefiles"); + m_hasCodeBlocksNinjaGenerator = response.contains("CodeBlocks - Ninja"); + m_version = versionRegexp.cap(1); + if (!(versionRegexp.capturedTexts().size() > 3)) + m_version += QLatin1Char('.') + versionRegexp.cap(3); + + if (m_version.isEmpty()) { + m_state = CMakeValidator::Invalid; + } else { + m_state = CMakeValidator::RunningFunctionList; + if (!startProcess(QStringList(QLatin1String("--help-command-list")))) + finished(0); // shoud never happen, just continue + } + } else if (m_state == CMakeValidator::RunningFunctionList) { + parseFunctionOutput(m_process->readAll()); + m_state = CMakeValidator::RunningFunctionDetails; + if (!startProcess(QStringList(QLatin1String("--help-commands")))) + finished(0); // shoud never happen, just continue + } else if (m_state == CMakeValidator::RunningFunctionDetails) { + parseFunctionDetailsOutput(m_process->readAll()); + m_state = CMakeValidator::ValidFunctionDetails; + } +} + +bool CMakeValidator::isValid() const +{ + if (m_state == CMakeValidator::Invalid) + return false; + if (m_state == CMakeValidator::RunningBasic) + m_process->waitForFinished(); + return (m_state != CMakeValidator::Invalid); +} + +bool CMakeValidator::startProcess(const QStringList &args) +{ + m_process->start(m_executable, args); + return m_process->waitForStarted(2000); +} + +QString CMakeValidator::cmakeExecutable() const +{ + return m_executable; +} + +bool CMakeValidator::hasCodeBlocksMsvcGenerator() const +{ + if (!isValid()) + return false; + return m_hasCodeBlocksMsvcGenerator; +} + +bool CMakeValidator::hasCodeBlocksNinjaGenerator() const +{ + if (!isValid()) + return false; + return m_hasCodeBlocksNinjaGenerator; +} + + +TextEditor::Keywords CMakeValidator::keywords() +{ + while (m_state != ValidFunctionDetails && m_state != CMakeValidator::Invalid) { + m_process->waitForFinished(); + } + + if (m_state == CMakeValidator::Invalid) + return TextEditor::Keywords(QStringList(), QStringList(), QMap<QString, QStringList>()); + + return TextEditor::Keywords(m_variables, m_functions, m_functionArgs); +} + +static void extractKeywords(const QByteArray &input, QStringList *destination) +{ + if (!destination) + return; + + QString keyword; + int ignoreZone = 0; + for (int i = 0; i < input.count(); ++i) { + const QChar chr = QLatin1Char(input.at(i)); + if (chr == QLatin1Char('{')) + ++ignoreZone; + if (chr == QLatin1Char('}')) + --ignoreZone; + if (ignoreZone == 0) { + if ((chr.isLetterOrNumber() && chr.isUpper()) + || chr == QLatin1Char('_')) { + keyword += chr; + } else { + if (!keyword.isEmpty()) { + if (keyword.size() > 1) { + *destination << keyword; + } + keyword.clear(); + } + } + } + } + if (keyword.size() > 1) { + *destination << keyword; + } +} + +void CMakeValidator::parseFunctionOutput(const QByteArray &output) +{ + QList<QByteArray> cmakeFunctionsList = output.split('\n'); + m_functions.clear(); + if (!cmakeFunctionsList.isEmpty()) { + cmakeFunctionsList.removeFirst(); //remove version string + foreach (const QByteArray &function, cmakeFunctionsList) + m_functions << QString::fromLocal8Bit(function.trimmed()); + } +} + +QString CMakeValidator::formatFunctionDetails(const QString &command, const QString &args) +{ + return QString::fromLatin1("<table><tr><td><b>%1</b></td><td>%2</td></tr>") + .arg(Qt::escape(command)).arg(Qt::escape(args)); +} + +void CMakeValidator::parseFunctionDetailsOutput(const QByteArray &output) +{ + QStringList cmakeFunctionsList = m_functions; + QList<QByteArray> cmakeCommandsHelp = output.split('\n'); + for (int i = 0; i < cmakeCommandsHelp.count(); ++i) { + QByteArray lineTrimmed = cmakeCommandsHelp.at(i).trimmed(); + if (cmakeFunctionsList.first().toLatin1() == lineTrimmed) { + QStringList commandSyntaxes; + QString currentCommandSyntax; + QString currentCommand = cmakeFunctionsList.takeFirst(); + ++i; + for (; i < cmakeCommandsHelp.count(); ++i) { + lineTrimmed = cmakeCommandsHelp.at(i).trimmed(); + + if (cmakeFunctionsList.first().toLatin1() == lineTrimmed) { + //start of next function in output + if (!currentCommandSyntax.isEmpty()) + commandSyntaxes << currentCommandSyntax.append(QLatin1String("</table>")); + --i; + break; + } + if (lineTrimmed.startsWith(currentCommand.toLatin1() + "(")) { + if (!currentCommandSyntax.isEmpty()) + commandSyntaxes << currentCommandSyntax.append(QLatin1String("</table>")); + + QByteArray argLine = lineTrimmed.mid(currentCommand.length()); + extractKeywords(argLine, &m_variables); + currentCommandSyntax = formatFunctionDetails(currentCommand, QString::fromUtf8(argLine)); + } else { + if (!currentCommandSyntax.isEmpty()) { + if (lineTrimmed.isEmpty()) { + commandSyntaxes << currentCommandSyntax.append(QLatin1String("</table>")); + currentCommandSyntax.clear(); + } else { + extractKeywords(lineTrimmed, &m_variables); + currentCommandSyntax += QString::fromLatin1("<tr><td> </td><td>%1</td></tr>") + .arg(Qt::escape(QString::fromLocal8Bit(lineTrimmed))); + } + } + } + } + m_functionArgs[currentCommand] = commandSyntaxes; + } + } + m_functions = m_functionArgs.keys(); + m_variables.sort(); + m_variables.removeDuplicates(); +} diff --git a/src/plugins/madde/maemodeployconfigurationwidget.h b/src/plugins/cmakeprojectmanager/cmakevalidator.h index 1d848eff2e..e325c8d8ff 100644 --- a/src/plugins/madde/maemodeployconfigurationwidget.h +++ b/src/plugins/cmakeprojectmanager/cmakevalidator.h @@ -27,52 +27,59 @@ ** ****************************************************************************/ -#ifndef MAEMODEPLOYCONFIGURATIONWIDGET_H -#define MAEMODEPLOYCONFIGURATIONWIDGET_H +#ifndef CMAKEVALIDATOR_H +#define CMAKEVALIDATOR_H -#include <projectexplorer/deployconfiguration.h> +#include <QObject> +#include <QString> +#include <QStringList> +#include <texteditor/codeassist/keywordscompletionassist.h> -namespace RemoteLinux { -class DeployableFilesPerProFile; -class RemoteLinuxDeployConfigurationWidget; -} +QT_FORWARD_DECLARE_CLASS(QProcess) -namespace Madde { +namespace CMakeProjectManager { namespace Internal { -class Qt4MaemoDeployConfiguration; -namespace Ui { class MaemoDeployConfigurationWidget; } - - -class MaemoDeployConfigurationWidget : public ProjectExplorer::DeployConfigurationWidget +class CMakeValidator : public QObject { Q_OBJECT - public: - explicit MaemoDeployConfigurationWidget(QWidget *parent = 0); - ~MaemoDeployConfigurationWidget(); + CMakeValidator(); + ~CMakeValidator(); - void init(ProjectExplorer::DeployConfiguration *dc); - - Qt4MaemoDeployConfiguration *deployConfiguration() const; + enum State { Invalid, RunningBasic, RunningFunctionList, RunningFunctionDetails, ValidFunctionDetails }; + void cancel(); + bool isValid() const; + void setCMakeExecutable(const QString &executable); + QString cmakeExecutable() const; + bool hasCodeBlocksMsvcGenerator() const; + bool hasCodeBlocksNinjaGenerator() const; + TextEditor::Keywords keywords(); private slots: - void addDesktopFile(); - void addIcon(); - void handleDeploymentInfoToBeReset(); - void handleCurrentModelChanged(const RemoteLinux::DeployableFilesPerProFile *proFileInfo); + void finished(int exitCode); private: - bool canAddDesktopFile(const RemoteLinux::DeployableFilesPerProFile *proFileInfo) const; - bool canAddIcon(const RemoteLinux::DeployableFilesPerProFile *proFileInfo) const; - QString remoteIconFilePath(const RemoteLinux::DeployableFilesPerProFile *proFileInfo) const; - QString remoteIconDir() const; + void finishStep(); + void startNextStep(); + bool startProcess(const QStringList &args); + void parseFunctionOutput(const QByteArray &output); + void parseFunctionDetailsOutput(const QByteArray &output); + QString formatFunctionDetails(const QString &command, const QString &args); + + State m_state; + QProcess *m_process; + bool m_hasCodeBlocksMsvcGenerator; + bool m_hasCodeBlocksNinjaGenerator; + QString m_version; + QString m_executable; - Ui::MaemoDeployConfigurationWidget *ui; - RemoteLinux::RemoteLinuxDeployConfigurationWidget * const m_remoteLinuxWidget; + QMap<QString, QStringList> m_functionArgs; + QStringList m_variables; + QStringList m_functions; }; } // namespace Internal -} // namespace Madde +} // namespace CMakeProjectManager -#endif // MAEMODEPLOYCONFIGURATIONWIDGET_H +#endif // CMAKEVALIDATOR_H diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp index da32f5f50e..6ad3304d00 100644 --- a/src/plugins/cmakeprojectmanager/makestep.cpp +++ b/src/plugins/cmakeprojectmanager/makestep.cpp @@ -91,8 +91,8 @@ MakeStep::MakeStep(BuildStepList *bsl, MakeStep *bs) : void MakeStep::ctor() { - m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]"); - m_ninjaProgress = QRegExp ("^\\[\\s*(\\d*)/\\s*(\\d*)"); + m_percentProgress = QRegExp(QLatin1String("^\\[\\s*(\\d*)%\\]")); + m_ninjaProgress = QRegExp(QLatin1String("^\\[\\s*(\\d*)/\\s*(\\d*)")); m_ninjaProgressString = QLatin1String("[%s/%t "); // ninja: [33/100 //: Default display name for the cmake make step. setDefaultDisplayName(tr("Make")); @@ -200,12 +200,9 @@ bool MakeStep::init() pp->setArguments(arguments); setOutputParser(new ProjectExplorer::GnuMakeParser()); - - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); - if (version) - appendOutputParser(new QtSupport::QtParser); - if (tc) - appendOutputParser(tc->outputParser()); + IOutputParser *parser = target()->kit()->createOutputParser(); + if (parser) + appendOutputParser(parser); outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory()); return AbstractProcessStep::init(); @@ -398,9 +395,9 @@ void MakeStepConfigWidget::buildTargetsChanged() void MakeStepConfigWidget::updateDetails() { - CMakeBuildConfiguration *bc = m_makeStep->cmakeBuildConfiguration(); + BuildConfiguration *bc = m_makeStep->buildConfiguration(); if (!bc) - bc = static_cast<CMakeBuildConfiguration *>(m_makeStep->target()->activeBuildConfiguration()); + bc = m_makeStep->target()->activeBuildConfiguration(); if (!bc) { m_summaryText = tr("<b>No build configuration found on this kit.</b>"); updateSummary(); @@ -457,7 +454,7 @@ BuildStep *MakeStepFactory::create(BuildStepList *parent, const Core::Id id) MakeStep *step = new MakeStep(parent); if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) { step->setClean(true); - step->setAdditionalArguments("clean"); + step->setAdditionalArguments(QLatin1String("clean")); } return step; } diff --git a/src/plugins/coreplugin/actionmanager/command.cpp b/src/plugins/coreplugin/actionmanager/command.cpp index c4472d1eed..07a2f0d67a 100644 --- a/src/plugins/coreplugin/actionmanager/command.cpp +++ b/src/plugins/coreplugin/actionmanager/command.cpp @@ -33,6 +33,8 @@ #include "icontext.h" #include "id.h" +#include <utils/hostosinfo.h> + #include <QDebug> #include <QTextStream> @@ -437,9 +439,8 @@ static QString msgActionWarning(QAction *newAction, int k, QAction *oldAction) void Action::addOverrideAction(QAction *action, const Core::Context &context, bool scriptable) { -#ifdef Q_OS_MAC - action->setIconVisibleInMenu(false); -#endif + if (Utils::HostOsInfo::isMacHost()) + action->setIconVisibleInMenu(false); if (isEmpty()) m_action->initialize(action); if (context.isEmpty()) { diff --git a/src/plugins/coreplugin/actionmanager/commandmappings.cpp b/src/plugins/coreplugin/actionmanager/commandmappings.cpp index ab8c24707e..b287cf7fe2 100644 --- a/src/plugins/coreplugin/actionmanager/commandmappings.cpp +++ b/src/plugins/coreplugin/actionmanager/commandmappings.cpp @@ -36,6 +36,7 @@ #include "icore.h" #include "id.h" +#include <utils/hostosinfo.h> #include <utils/treewidgetcolumnstretcher.h> #include <QKeyEvent> @@ -165,18 +166,18 @@ bool CommandMappings::filter(const QString &filterString, QTreeWidgetItem *item) int columnCount = item->columnCount(); for (int i = 0; !visible && i < columnCount; ++i) { QString text = item->text(i); -#ifdef Q_OS_MAC - // accept e.g. Cmd+E in the filter. the text shows special fancy characters for Cmd - if (i == columnCount - 1) { - QKeySequence key = QKeySequence::fromString(text, QKeySequence::NativeText); - if (!key.isEmpty()) { - text = key.toString(QKeySequence::PortableText); - text.replace(QLatin1String("Ctrl"), QLatin1String("Cmd")); - text.replace(QLatin1String("Meta"), QLatin1String("Ctrl")); - text.replace(QLatin1String("Alt"), QLatin1String("Opt")); + if (Utils::HostOsInfo::isMacHost()) { + // accept e.g. Cmd+E in the filter. the text shows special fancy characters for Cmd + if (i == columnCount - 1) { + QKeySequence key = QKeySequence::fromString(text, QKeySequence::NativeText); + if (!key.isEmpty()) { + text = key.toString(QKeySequence::PortableText); + text.replace(QLatin1String("Ctrl"), QLatin1String("Cmd")); + text.replace(QLatin1String("Meta"), QLatin1String("Ctrl")); + text.replace(QLatin1String("Alt"), QLatin1String("Opt")); + } } } -#endif visible |= (bool)text.contains(filterString, Qt::CaseInsensitive); } diff --git a/src/plugins/coreplugin/actionmanager/commandsfile.cpp b/src/plugins/coreplugin/actionmanager/commandsfile.cpp index 23be856e58..c8ed630c1d 100644 --- a/src/plugins/coreplugin/actionmanager/commandsfile.cpp +++ b/src/plugins/coreplugin/actionmanager/commandsfile.cpp @@ -140,7 +140,7 @@ bool CommandsFile::exportCommands(const QList<ShortcutItem *> &items) w.setAutoFormattingIndent(1); // Historical, used to be QDom. w.writeStartDocument(); w.writeDTD(QLatin1String("<!DOCTYPE KeyboardMappingScheme>")); - w.writeComment(QString::fromAscii(" Written by Qt Creator %1, %2. "). + w.writeComment(QString::fromLatin1(" Written by Qt Creator %1, %2. "). arg(QLatin1String(Core::Constants::IDE_VERSION_LONG), QDateTime::currentDateTime().toString(Qt::ISODate))); w.writeStartElement(ctx.mappingElement); diff --git a/src/plugins/coreplugin/basefilewizard.cpp b/src/plugins/coreplugin/basefilewizard.cpp index 9591f5838a..67422da8ea 100644 --- a/src/plugins/coreplugin/basefilewizard.cpp +++ b/src/plugins/coreplugin/basefilewizard.cpp @@ -40,6 +40,7 @@ #include <utils/qtcassert.h> #include <utils/stringutils.h> #include <utils/fileutils.h> +#include <utils/hostosinfo.h> #include <QDir> #include <QFile> @@ -546,7 +547,8 @@ void BaseFileWizard::runWizard(const QString &path, QWidget *parent, const QStri // Post generation handler if (!postGenerateFiles(wizard.data(), files, &errorMessage)) - QMessageBox::critical(0, tr("File Generation Failure"), errorMessage); + if (!errorMessage.isEmpty()) + QMessageBox::critical(0, tr("File Generation Failure"), errorMessage); } @@ -603,15 +605,15 @@ void BaseFileWizard::setupWizard(QWizard *w) w->setOption(QWizard::NoBackButtonOnStartPage, true); w->setWindowFlags(w->windowFlags() & ~Qt::WindowContextHelpButtonHint); -#ifdef Q_OS_MAC - w->setButtonLayout(QList<QWizard::WizardButton>() - << QWizard::CancelButton - << QWizard::Stretch - << QWizard::BackButton - << QWizard::NextButton - << QWizard::CommitButton - << QWizard::FinishButton); -#endif + if (Utils::HostOsInfo::isMacHost()) { + w->setButtonLayout(QList<QWizard::WizardButton>() + << QWizard::CancelButton + << QWizard::Stretch + << QWizard::BackButton + << QWizard::NextButton + << QWizard::CommitButton + << QWizard::FinishButton); + } } /*! diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h index 7c6032cc0e..982a9f2d65 100644 --- a/src/plugins/coreplugin/coreconstants.h +++ b/src/plugins/coreplugin/coreconstants.h @@ -227,6 +227,8 @@ const char VARIABLE_SUPPORT_PROPERTY[] = "QtCreator.VariableSupport"; const char TR_CLEAR_MENU[] = QT_TRANSLATE_NOOP("Core", "Clear Menu"); +const char DEFAULT_BUILD_DIRECTORY[] = "../build-%{CurrentProject:Name}-%{CurrentKit:FileSystemName}-%{CurrentBuild:Name}"; + const int TARGET_ICON_SIZE = 32; } // namespace Constants diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro index 381f6a6e57..c939dc1ae3 100644 --- a/src/plugins/coreplugin/coreplugin.pro +++ b/src/plugins/coreplugin/coreplugin.pro @@ -1,6 +1,7 @@ TEMPLATE = lib TARGET = Core -DEFINES += CORE_LIBRARY +DEFINES += CORE_LIBRARY \ + QT_NO_CAST_FROM_ASCII QT += network \ script \ sql @@ -207,7 +208,6 @@ FORMS += dialogs/newdialog.ui \ actionmanager/commandmappings.ui \ dialogs/saveitemsdialog.ui \ dialogs/openwithdialog.ui \ - editormanager/openeditorsview.ui \ generalsettings.ui \ dialogs/externaltoolconfig.ui \ variablechooser.ui \ diff --git a/src/plugins/coreplugin/coreplugin.qbs b/src/plugins/coreplugin/coreplugin.qbs index cf50a57299..758eb0a439 100644 --- a/src/plugins/coreplugin/coreplugin.qbs +++ b/src/plugins/coreplugin/coreplugin.qbs @@ -13,20 +13,17 @@ QtcPlugin { Depends { name: "Utils" } Depends { name: "ExtensionSystem" } Depends { name: "Aggregation" } + Depends { name: "app_version_header" } - cpp.includePaths: [ - ".", - "..", + cpp.includePaths: base.concat([ "../..", - "../../libs", - "../../../src/shared/scriptwrapper/", + "../../shared/scriptwrapper", "dialogs", "editormanager", "progressmanager", "scriptmanager", - "actionmanager", - buildDirectory - ] + "actionmanager" + ]) cpp.dynamicLibraries: { if (qbs.targetOS == "windows") return [ @@ -35,9 +32,8 @@ QtcPlugin { ] } + cpp.defines: base.concat([ "QT_NO_CAST_FROM_ASCII" ]) files: [ - "fancyactionbar.qrc", - "generalsettings.ui", "basefilewizard.cpp", "basefilewizard.h", "core.qrc", @@ -47,6 +43,8 @@ QtcPlugin { "coreplugin.h", "designmode.cpp", "designmode.h", + "documentmanager.cpp", + "documentmanager.h", "editmode.cpp", "editmode.h", "editortoolbar.cpp", @@ -56,10 +54,11 @@ QtcPlugin { "externaltoolmanager.h", "fancyactionbar.cpp", "fancyactionbar.h", + "fancyactionbar.qrc", "fancytabwidget.cpp", "fancytabwidget.h", - "featureprovider.h", "featureprovider.cpp", + "featureprovider.h", "fileiconprovider.cpp", "fileiconprovider.h", "fileutils.cpp", @@ -68,6 +67,7 @@ QtcPlugin { "findplaceholder.h", "generalsettings.cpp", "generalsettings.h", + "generalsettings.ui", "generatedfile.cpp", "generatedfile.h", "helpmanager.cpp", @@ -77,20 +77,21 @@ QtcPlugin { "icore.cpp", "icore.h", "icorelistener.h", + "id.cpp", "id.h", - "ifilewizardextension.h", - "imode.cpp", - "imode.h", - "documentmanager.cpp", - "documentmanager.h", "idocument.cpp", "idocument.h", "idocumentfactory.h", + "ifilewizardextension.h", + "imode.cpp", + "imode.h", "inavigationwidgetfactory.cpp", "inavigationwidgetfactory.h", "infobar.cpp", "infobar.h", "ioutputpane.h", + "iversioncontrol.cpp", + "iversioncontrol.h", "mainwindow.cpp", "mainwindow.h", "manhattanstyle.cpp", @@ -146,18 +147,15 @@ QtcPlugin { "textdocument.h", "toolsettings.cpp", "toolsettings.h", + "variablechooser.cpp", "variablechooser.h", "variablechooser.ui", - "vcsmanager.h", - "versiondialog.cpp", - "versiondialog.h", - "id.cpp", - "iversioncontrol.cpp", - "iversioncontrol.h", - "variablechooser.cpp", "variablemanager.cpp", "variablemanager.h", "vcsmanager.cpp", + "vcsmanager.h", + "versiondialog.cpp", + "versiondialog.h", "actionmanager/actioncontainer.cpp", "actionmanager/actioncontainer.h", "actionmanager/actioncontainer_p.h", @@ -167,23 +165,23 @@ QtcPlugin { "actionmanager/command.cpp", "actionmanager/command.h", "actionmanager/command_p.h", - "actionmanager/commandbutton.h", "actionmanager/commandbutton.cpp", + "actionmanager/commandbutton.h", "actionmanager/commandmappings.cpp", "actionmanager/commandmappings.h", "actionmanager/commandmappings.ui", "actionmanager/commandsfile.cpp", "actionmanager/commandsfile.h", - "dialogs/externaltoolconfig.ui", - "dialogs/newdialog.ui", "dialogs/externaltoolconfig.cpp", "dialogs/externaltoolconfig.h", + "dialogs/externaltoolconfig.ui", "dialogs/ioptionspage.cpp", "dialogs/ioptionspage.h", "dialogs/iwizard.cpp", "dialogs/iwizard.h", "dialogs/newdialog.cpp", "dialogs/newdialog.h", + "dialogs/newdialog.ui", "dialogs/openwithdialog.cpp", "dialogs/openwithdialog.h", "dialogs/openwithdialog.ui", @@ -197,25 +195,24 @@ QtcPlugin { "dialogs/shortcutsettings.cpp", "dialogs/shortcutsettings.h", "editormanager/BinFiles.mimetypes.xml", + "editormanager/editormanager.cpp", + "editormanager/editormanager.h", "editormanager/editorview.cpp", "editormanager/editorview.h", "editormanager/ieditor.cpp", "editormanager/ieditor.h", - "editormanager/ieditorfactory.h", "editormanager/ieditorfactory.cpp", + "editormanager/ieditorfactory.h", "editormanager/iexternaleditor.cpp", "editormanager/iexternaleditor.h", "editormanager/openeditorsmodel.cpp", "editormanager/openeditorsmodel.h", "editormanager/openeditorsview.cpp", "editormanager/openeditorsview.h", - "editormanager/openeditorsview.ui", "editormanager/openeditorswindow.cpp", "editormanager/openeditorswindow.h", "editormanager/systemeditor.cpp", "editormanager/systemeditor.h", - "editormanager/editormanager.cpp", - "editormanager/editormanager.h", "progressmanager/futureprogress.cpp", "progressmanager/futureprogress.h", "progressmanager/progressbar.cpp", @@ -228,27 +225,27 @@ QtcPlugin { "scriptmanager/metatypedeclarations.h", "scriptmanager/scriptmanager.cpp", "scriptmanager/scriptmanager.h", - "scriptmanager/scriptmanager_p.h" + "scriptmanager/scriptmanager_p.h", ] Group { condition: qbs.targetOS == "windows" files: [ - "progressmanager/progressmanager_win.cpp" + "progressmanager/progressmanager_win.cpp", ] } Group { condition: qbs.targetOS == "macx" files: [ - "progressmanager/progressmanager_mac.mm" + "progressmanager/progressmanager_mac.mm", ] } Group { condition: qbs.targetOS == "linux" files: [ - "progressmanager/progressmanager_x11.cpp" + "progressmanager/progressmanager_x11.cpp", ] } @@ -257,11 +254,5 @@ QtcPlugin { Depends { name: "Aggregation" } Depends { name: "ExtensionSystem" } Depends { name: "Utils" } - cpp.includePaths: [ - "../..", - "../../libs", - product.buildDirectory + "/.obj/Core/actionmanager" - ] } } - diff --git a/src/plugins/coreplugin/designmode.cpp b/src/plugins/coreplugin/designmode.cpp index 3e8dd7fc73..318805bec2 100644 --- a/src/plugins/coreplugin/designmode.cpp +++ b/src/plugins/coreplugin/designmode.cpp @@ -44,6 +44,7 @@ #include <QPair> #include <QFileInfo> +#include <QPointer> #include <QStringList> #include <QDebug> @@ -100,7 +101,7 @@ public: public: Internal::DesignModeCoreListener *m_coreListener; - QWeakPointer<Core::IEditor> m_currentEditor; + QPointer<Core::IEditor> m_currentEditor; bool m_isActive; bool m_isRequired; QList<DesignEditorInfo*> m_editors; @@ -236,10 +237,10 @@ void DesignMode::currentEditorChanged(Core::IEditor *editor) if (ModeManager::currentMode() == this) ModeManager::activateMode(Core::Constants::MODE_EDIT); setEnabled(false); - d->m_currentEditor = QWeakPointer<Core::IEditor>(); + d->m_currentEditor = 0; emit actionsUpdated(d->m_currentEditor.data()); } else { - d->m_currentEditor = QWeakPointer<Core::IEditor>(editor); + d->m_currentEditor = editor; if (d->m_currentEditor) connect(d->m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions())); diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp index 44ee4c7b05..bf5d8db822 100644 --- a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp +++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp @@ -30,6 +30,7 @@ #include "externaltoolconfig.h" #include "ui_externaltoolconfig.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <coreplugin/coreconstants.h> @@ -350,13 +351,13 @@ QModelIndex ExternalToolModel::addTool(const QModelIndex &atIndex) tool->setDescription(tr("This tool prints a line of useful text")); //: Sample external tool text const QString text = tr("Useful text"); -#ifdef Q_OS_WIN - tool->setExecutables(QStringList(QLatin1String("cmd"))); - tool->setArguments(QLatin1String("/c echo ") + text); -#else - tool->setExecutables(QStringList(QLatin1String("echo"))); - tool->setArguments(text); -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + tool->setExecutables(QStringList(QLatin1String("cmd"))); + tool->setArguments(QLatin1String("/c echo ") + text); + } else { + tool->setExecutables(QStringList(QLatin1String("echo"))); + tool->setArguments(text); + } int pos; QModelIndex parent; diff --git a/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp b/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp index 5b0c24c285..5363812de7 100644 --- a/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp @@ -33,6 +33,7 @@ #include <coreplugin/fileiconprovider.h> #include <coreplugin/idocument.h> +#include <utils/hostosinfo.h> #include <QDir> #include <QFileInfo> @@ -53,12 +54,10 @@ SaveItemsDialog::SaveItemsDialog(QWidget *parent, { m_ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); -#ifdef Q_OS_MAC + // QDialogButtonBox's behavior for "destructive" is wrong, the "do not save" should be left-aligned - QDialogButtonBox::ButtonRole discardButtonRole = QDialogButtonBox::ResetRole; -#else - QDialogButtonBox::ButtonRole discardButtonRole = QDialogButtonBox::DestructiveRole; -#endif + const QDialogButtonBox::ButtonRole discardButtonRole = Utils::HostOsInfo::isMacHost() + ? QDialogButtonBox::ResetRole : QDialogButtonBox::DestructiveRole; QPushButton *discardButton = m_ui.buttonBox->addButton(tr("Do not Save"), discardButtonRole); m_ui.buttonBox->button(QDialogButtonBox::Save)->setDefault(true); m_ui.treeWidget->setFocus(); @@ -85,9 +84,8 @@ SaveItemsDialog::SaveItemsDialog(QWidget *parent, m_ui.treeWidget->resizeColumnToContents(0); m_ui.treeWidget->selectAll(); -#ifdef Q_OS_MAC - m_ui.treeWidget->setAlternatingRowColors(true); -#endif + if (Utils::HostOsInfo::isMacHost()) + m_ui.treeWidget->setAlternatingRowColors(true); adjustButtonWidths(); updateSaveButton(); @@ -134,13 +132,13 @@ void SaveItemsDialog::adjustButtonWidths() if (hint > maxTextWidth) maxTextWidth = hint; } -#ifdef Q_OS_MAC - QPushButton *cancelButton = m_ui.buttonBox->button(QDialogButtonBox::Cancel); - int cancelButtonWidth = cancelButton->sizeHint().width(); - if (cancelButtonWidth > maxTextWidth) - maxTextWidth = cancelButtonWidth; - cancelButton->setMinimumWidth(maxTextWidth); -#endif + if (Utils::HostOsInfo::isMacHost()) { + QPushButton *cancelButton = m_ui.buttonBox->button(QDialogButtonBox::Cancel); + int cancelButtonWidth = cancelButton->sizeHint().width(); + if (cancelButtonWidth > maxTextWidth) + maxTextWidth = cancelButtonWidth; + cancelButton->setMinimumWidth(maxTextWidth); + } saveButton->setMinimumWidth(maxTextWidth); } diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index 6827880e0a..d87488ac3f 100644 --- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -32,6 +32,7 @@ #include <extensionsystem/pluginmanager.h> #include "icore.h" +#include <utils/hostosinfo.h> #include <utils/filterlineedit.h> #include <QSettings> @@ -135,6 +136,8 @@ QVariant CategoryModel::data(const QModelIndex &index, int role) const void CategoryModel::setPages(const QList<IOptionsPage*> &pages, const QList<IOptionsPageProvider *> &providers) { + beginResetModel(); + // Clear any previous categories qDeleteAll(m_categories); m_categories.clear(); @@ -174,7 +177,7 @@ void CategoryModel::setPages(const QList<IOptionsPage*> &pages, category->providers.append(provider); } - reset(); + endResetModel(); } Category *CategoryModel::findCategoryById(const QString &id) @@ -294,11 +297,10 @@ SettingsDialog::SettingsDialog(QWidget *parent) : createGui(); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); -#ifdef Q_OS_MAC - setWindowTitle(tr("Preferences")); -#else - setWindowTitle(tr("Options")); -#endif + if (Utils::HostOsInfo::isMacHost()) + setWindowTitle(tr("Preferences")); + else + setWindowTitle(tr("Options")); m_model->setPages(m_pages, ExtensionSystem::PluginManager::getObjects<IOptionsPageProvider>()); diff --git a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp index d9c00677c4..5c0d97f325 100644 --- a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp +++ b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp @@ -141,7 +141,7 @@ void ShortcutSettings::commandChanged(QTreeWidgetItem *current) CommandMappings::commandChanged(current); if (!current || !current->data(0, Qt::UserRole).isValid()) return; - ShortcutItem *scitem = qVariantValue<ShortcutItem *>(current->data(0, Qt::UserRole)); + ShortcutItem *scitem = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole)); setKeySequence(scitem->m_key); } @@ -149,13 +149,13 @@ void ShortcutSettings::targetIdentifierChanged() { QTreeWidgetItem *current = commandList()->currentItem(); if (current && current->data(0, Qt::UserRole).isValid()) { - ShortcutItem *scitem = qVariantValue<ShortcutItem *>(current->data(0, Qt::UserRole)); + ShortcutItem *scitem = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole)); scitem->m_key = QKeySequence(m_key[0], m_key[1], m_key[2], m_key[3]); if (scitem->m_cmd->defaultKeySequence() != scitem->m_key) setModified(current, true); else setModified(current, false); - current->setText(2, scitem->m_key); + current->setText(2, scitem->m_key.toString(QKeySequence::NativeText)); resetCollisionMarker(scitem); markPossibleCollisions(scitem); } @@ -168,14 +168,14 @@ void ShortcutSettings::setKeySequence(const QKeySequence &key) for (int i = 0; i < m_keyNum; ++i) { m_key[i] = key[i]; } - targetEdit()->setText(key); + targetEdit()->setText(key.toString(QKeySequence::NativeText)); } void ShortcutSettings::resetTargetIdentifier() { QTreeWidgetItem *current = commandList()->currentItem(); if (current && current->data(0, Qt::UserRole).isValid()) { - ShortcutItem *scitem = qVariantValue<ShortcutItem *>(current->data(0, Qt::UserRole)); + ShortcutItem *scitem = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole)); setKeySequence(scitem->m_cmd->defaultKeySequence()); } } @@ -200,7 +200,7 @@ void ShortcutSettings::importAction() QString sid = item->m_cmd->id().toString(); if (mapping.contains(sid)) { item->m_key = mapping.value(sid); - item->m_item->setText(2, item->m_key); + item->m_item->setText(2, item->m_key.toString(QKeySequence::NativeText)); if (item->m_item == commandList()->currentItem()) commandChanged(item->m_item); @@ -222,7 +222,7 @@ void ShortcutSettings::defaultAction() { foreach (ShortcutItem *item, m_scitems) { item->m_key = item->m_cmd->defaultKeySequence(); - item->m_item->setText(2, item->m_key); + item->m_item->setText(2, item->m_key.toString(QKeySequence::NativeText)); setModified(item->m_item, false); if (item->m_item == commandList()->currentItem()) commandChanged(item->m_item); @@ -293,7 +293,7 @@ void ShortcutSettings::initialize() s->m_key = c->keySequence(); item->setText(0, subId); item->setText(1, c->description()); - item->setText(2, s->m_key); + item->setText(2, s->m_key.toString(QKeySequence::NativeText)); if (s->m_cmd->defaultKeySequence() != s->m_key) setModified(item, true); @@ -333,7 +333,7 @@ void ShortcutSettings::handleKeyEvent(QKeyEvent *e) } m_keyNum++; QKeySequence ks(m_key[0], m_key[1], m_key[2], m_key[3]); - targetEdit()->setText(ks); + targetEdit()->setText(ks.toString(QKeySequence::NativeText)); e->accept(); } diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 837759c7c9..42d8787a6d 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -41,6 +41,7 @@ #include "vcsmanager.h" #include "coreconstants.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/pathchooser.h> #include <utils/reloadpromptutils.h> @@ -96,7 +97,7 @@ static const char editorsKeyC[] = "EditorIds"; static const char directoryGroupC[] = "Directories"; static const char projectDirectoryKeyC[] = "Projects"; static const char useProjectDirectoryKeyC[] = "UseProjectsDirectory"; - +static const char buildDirectoryKeyC[] = "BuildDirectory"; namespace Core { @@ -155,6 +156,7 @@ struct DocumentManagerPrivate QString m_lastVisitedDirectory; QString m_projectsDirectory; bool m_useProjectsDirectory; + QString m_buildDirectory; // When we are callling into a IDocument // we don't want to receive a changed() // signal @@ -177,17 +179,17 @@ QFileSystemWatcher *DocumentManagerPrivate::fileWatcher() QFileSystemWatcher *DocumentManagerPrivate::linkWatcher() { -#ifdef Q_OS_UNIX - if (!m_linkWatcher) { - m_linkWatcher = new QFileSystemWatcher(m_instance); - m_linkWatcher->setObjectName(QLatin1String("_qt_autotest_force_engine_poller")); - QObject::connect(m_linkWatcher, SIGNAL(fileChanged(QString)), - m_instance, SLOT(changedFile(QString))); + if (Utils::HostOsInfo::isAnyUnixHost()) { + if (!m_linkWatcher) { + m_linkWatcher = new QFileSystemWatcher(m_instance); + m_linkWatcher->setObjectName(QLatin1String("_qt_autotest_force_engine_poller")); + QObject::connect(m_linkWatcher, SIGNAL(fileChanged(QString)), + m_instance, SLOT(changedFile(QString))); + } + return m_linkWatcher; } - return m_linkWatcher; -#else + return fileWatcher(); -#endif } DocumentManagerPrivate::DocumentManagerPrivate(QMainWindow *mw) : @@ -196,11 +198,7 @@ DocumentManagerPrivate::DocumentManagerPrivate(QMainWindow *mw) : m_linkWatcher(0), m_blockActivated(false), m_lastVisitedDirectory(QDir::currentPath()), -#ifdef Q_OS_MAC // Creator is in bizarre places when launched via finder. - m_useProjectsDirectory(true), -#else - m_useProjectsDirectory(false), -#endif + m_useProjectsDirectory(Utils::HostOsInfo::isMacHost()), // Creator is in bizarre places when launched via finder. m_blockedIDocument(0) { } @@ -488,9 +486,8 @@ QString DocumentManager::fixFileName(const QString &fileName, FixMode fixmode) s = QDir::cleanPath(s); } s = QDir::toNativeSeparators(s); -#ifdef Q_OS_WIN - s = s.toLower(); -#endif + if (Utils::HostOsInfo::isWindowsHost()) + s = s.toLower(); return s; } @@ -1169,6 +1166,7 @@ void DocumentManager::saveSettings() s->beginGroup(QLatin1String(directoryGroupC)); s->setValue(QLatin1String(projectDirectoryKeyC), d->m_projectsDirectory); s->setValue(QLatin1String(useProjectDirectoryKeyC), d->m_useProjectsDirectory); + s->setValue(QLatin1String(buildDirectoryKeyC), d->m_buildDirectory); s->endGroup(); } @@ -1194,13 +1192,20 @@ void readSettings() s->beginGroup(QLatin1String(directoryGroupC)); const QString settingsProjectDir = s->value(QLatin1String(projectDirectoryKeyC), QString()).toString(); - if (!settingsProjectDir.isEmpty() && QFileInfo(settingsProjectDir).isDir()) { + if (!settingsProjectDir.isEmpty() && QFileInfo(settingsProjectDir).isDir()) d->m_projectsDirectory = settingsProjectDir; - } else { + else d->m_projectsDirectory = Utils::PathChooser::homePath(); - } d->m_useProjectsDirectory = s->value(QLatin1String(useProjectDirectoryKeyC), d->m_useProjectsDirectory).toBool(); + + const QString settingsShadowDir = s->value(QLatin1String(buildDirectoryKeyC), + QString()).toString(); + if (!settingsShadowDir.isEmpty()) + d->m_buildDirectory = settingsShadowDir; + else + d->m_buildDirectory = QLatin1String(Constants::DEFAULT_BUILD_DIRECTORY); + s->endGroup(); } @@ -1272,6 +1277,26 @@ void DocumentManager::setProjectsDirectory(const QString &dir) } /*! + Returns the default build directory. + + \sa setBuildDirectory +*/ +QString DocumentManager::buildDirectory() +{ + return d->m_buildDirectory; +} + +/*! + Sets the shadow build directory to \a directory. + + \sa buildDirectory +*/ +void DocumentManager::setBuildDirectory(const QString &directory) +{ + d->m_buildDirectory = directory; +} + +/*! Returns whether the directory for projects is to be used or the user wants the current directory. @@ -1369,7 +1394,7 @@ void DocumentManager::executeOpenWithMenuAction(QAction *action) { QTC_ASSERT(action, return); const QVariant data = action->data(); - OpenWithEntry entry = qVariantValue<OpenWithEntry>(data); + OpenWithEntry entry = qvariant_cast<OpenWithEntry>(data); if (entry.editorFactory) { // close any open editors that have this file open, but have a different type. EditorManager *em = EditorManager::instance(); diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h index 939f1bfdc5..31893224ac 100644 --- a/src/plugins/coreplugin/documentmanager.h +++ b/src/plugins/coreplugin/documentmanager.h @@ -129,6 +129,9 @@ public: static QString projectsDirectory(); static void setProjectsDirectory(const QString &); + static QString buildDirectory(); + static void setBuildDirectory(const QString &directory); + static void populateOpenWithMenu(QMenu *menu, const QString &fileName); /* Used to notify e.g. the code model to update the given files. Does *not* diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 8fb4c13a01..7fb9569e57 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -60,6 +60,7 @@ #include <extensionsystem/pluginmanager.h> #include <utils/consoleprocess.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDateTime> @@ -89,6 +90,7 @@ static const char kCurrentDocumentFilePath[] = "CurrentDocument:FilePath"; static const char kCurrentDocumentPath[] = "CurrentDocument:Path"; static const char kCurrentDocumentXPos[] = "CurrentDocument:XPos"; static const char kCurrentDocumentYPos[] = "CurrentDocument:YPos"; +static const char kMakeWritableWarning[] = "Core.EditorManager.MakeWritable"; //===================EditorClosingCoreListener====================== @@ -1685,6 +1687,47 @@ void EditorManager::handleEditorStateChange() } } +void EditorManager::updateMakeWritableWarning() +{ + IEditor *curEditor = currentEditor(); + bool ww = curEditor->document()->isModified() && curEditor->document()->isFileReadOnly(); + if (ww != curEditor->document()->hasWriteWarning()) { + curEditor->document()->setWriteWarning(ww); + + // Do this after setWriteWarning so we don't re-evaluate this part even + // if we do not really show a warning. + bool promptVCS = false; + const QString directory = QFileInfo(curEditor->document()->fileName()).absolutePath(); + IVersionControl *versionControl = ICore::vcsManager()->findVersionControlForDirectory(directory); + if (versionControl && versionControl->supportsOperation(IVersionControl::OpenOperation)) { + if (versionControl->settingsFlags() & IVersionControl::AutoOpen) { + vcsOpenCurrentEditor(); + ww = false; + } else { + promptVCS = true; + } + } + + if (ww) { + // we are about to change a read-only file, warn user + if (promptVCS) { + InfoBarEntry info(Id(kMakeWritableWarning), + tr("<b>Warning:</b> This file was not opened in %1 yet.") + .arg(versionControl->displayName())); + info.setCustomButtonInfo(tr("Open"), this, SLOT(vcsOpenCurrentEditor())); + curEditor->document()->infoBar()->addInfo(info); + } else { + InfoBarEntry info(Id(kMakeWritableWarning), + tr("<b>Warning:</b> You are changing a read-only file.")); + info.setCustomButtonInfo(tr("Make Writable"), this, SLOT(makeCurrentEditorWritable())); + curEditor->document()->infoBar()->addInfo(info); + } + } else { + curEditor->document()->infoBar()->removeInfo(Id(kMakeWritableWarning)); + } + } +} + void EditorManager::updateActions() { QString fName; @@ -1700,49 +1743,11 @@ void EditorManager::updateActions() fName = curEditor->displayName(); } -#ifdef Q_OS_MAC - window()->setWindowModified(curEditor->document()->isModified()); -#endif - bool ww = curEditor->document()->isModified() && curEditor->document()->isFileReadOnly(); - if (ww != curEditor->document()->hasWriteWarning()) { - curEditor->document()->setWriteWarning(ww); - - // Do this after setWriteWarning so we don't re-evaluate this part even - // if we do not really show a warning. - bool promptVCS = false; - const QString directory = QFileInfo(curEditor->document()->fileName()).absolutePath(); - IVersionControl *versionControl = ICore::vcsManager()->findVersionControlForDirectory(directory); - if (versionControl && versionControl->supportsOperation(IVersionControl::OpenOperation)) { - if (versionControl->settingsFlags() & IVersionControl::AutoOpen) { - vcsOpenCurrentEditor(); - ww = false; - } else { - promptVCS = true; - } - } - - if (ww) { - // we are about to change a read-only file, warn user - if (promptVCS) { - InfoBarEntry info(QLatin1String("Core.EditorManager.MakeWritable"), - tr("<b>Warning:</b> This file was not opened in %1 yet.") - .arg(versionControl->displayName())); - info.setCustomButtonInfo(tr("Open"), this, SLOT(vcsOpenCurrentEditor())); - curEditor->document()->infoBar()->addInfo(info); - } else { - InfoBarEntry info(QLatin1String("Core.EditorManager.MakeWritable"), - tr("<b>Warning:</b> You are changing a read-only file.")); - info.setCustomButtonInfo(tr("Make Writable"), this, SLOT(makeCurrentEditorWritable())); - curEditor->document()->infoBar()->addInfo(info); - } - } else { - curEditor->document()->infoBar()->removeInfo(QLatin1String("Core.EditorManager.MakeWritable")); - } - } -#ifdef Q_OS_MAC - } else { // curEditor + if (HostOsInfo::isMacHost()) + window()->setWindowModified(curEditor->document()->isModified()); + updateMakeWritableWarning(); + } else /* curEditor */ if (HostOsInfo::isMacHost()) { window()->setWindowModified(false); -#endif } setCloseSplitEnabled(d->m_splitter, d->m_splitter->isSplitter()); diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index 3dca199892..55e7b44af8 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -263,6 +263,7 @@ private: void switchToPreferedMode(); void updateAutoSave(); void setCloseSplitEnabled(Internal::SplitterOrView *splitterOrView, bool enable); + void updateMakeWritableWarning(); EditorManagerPrivate *d; diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp index a3eaab0a5b..eb4cdcdba1 100644 --- a/src/plugins/coreplugin/editormanager/editorview.cpp +++ b/src/plugins/coreplugin/editormanager/editorview.cpp @@ -766,14 +766,14 @@ void SplitterOrView::unsplit() if (parentSplitter) { // not the toplevel splitterOrView if (parentSplitter->orientation() == Qt::Horizontal) { if (parentSplitter->widget(0) == this) - m_view->setCloseSplitIcon(QIcon(Constants::ICON_CLOSE_SPLIT_LEFT)); + m_view->setCloseSplitIcon(QIcon(QLatin1String(Constants::ICON_CLOSE_SPLIT_LEFT))); else - m_view->setCloseSplitIcon(QIcon(Constants::ICON_CLOSE_SPLIT_RIGHT)); + m_view->setCloseSplitIcon(QIcon(QLatin1String(Constants::ICON_CLOSE_SPLIT_RIGHT))); } else { if (parentSplitter->widget(0) == this) - m_view->setCloseSplitIcon(QIcon(Constants::ICON_CLOSE_SPLIT_TOP)); + m_view->setCloseSplitIcon(QIcon(QLatin1String(Constants::ICON_CLOSE_SPLIT_TOP))); else - m_view->setCloseSplitIcon(QIcon(Constants::ICON_CLOSE_SPLIT_BOTTOM)); + m_view->setCloseSplitIcon(QIcon(QLatin1String(Constants::ICON_CLOSE_SPLIT_BOTTOM))); } } } diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.cpp b/src/plugins/coreplugin/editormanager/openeditorsview.cpp index 096a3b163f..2721fe0298 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsview.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorsview.cpp @@ -41,6 +41,8 @@ #include <coreplugin/actionmanager/command.h> #include <utils/qtcassert.h> +#include <QApplication> +#include <QGridLayout> #include <QTimer> #include <QMenu> #include <QPainter> @@ -48,6 +50,7 @@ #include <QStyleOption> #include <QHeaderView> #include <QKeyEvent> +#include <QTreeView> #ifdef Q_OS_MAC #include <qmacstyle_mac.h> #endif @@ -96,36 +99,36 @@ void OpenEditorsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o OpenEditorsWidget::OpenEditorsWidget() { - m_ui.setupUi(this); setWindowTitle(tr("Open Documents")); setWindowIcon(QIcon(QLatin1String(Constants::ICON_DIR))); - setFocusProxy(m_ui.editorList); - m_ui.editorList->viewport()->setAttribute(Qt::WA_Hover); - m_ui.editorList->setItemDelegate((m_delegate = new OpenEditorsDelegate(this))); - m_ui.editorList->header()->hide(); - m_ui.editorList->setIndentation(0); - m_ui.editorList->setTextElideMode(Qt::ElideMiddle); - m_ui.editorList->setFrameStyle(QFrame::NoFrame); - m_ui.editorList->setAttribute(Qt::WA_MacShowFocusRect, false); + setUniformRowHeights(true); + viewport()->setAttribute(Qt::WA_Hover); + setItemDelegate((m_delegate = new OpenEditorsDelegate(this))); + header()->hide(); + setIndentation(0); + setTextElideMode(Qt::ElideMiddle); + setFrameStyle(QFrame::NoFrame); + setAttribute(Qt::WA_MacShowFocusRect, false); EditorManager *em = EditorManager::instance(); - m_ui.editorList->setModel(em->openedEditorsModel()); - m_ui.editorList->setSelectionMode(QAbstractItemView::SingleSelection); - m_ui.editorList->setSelectionBehavior(QAbstractItemView::SelectRows); - m_ui.editorList->header()->setStretchLastSection(false); - m_ui.editorList->header()->setResizeMode(0, QHeaderView::Stretch); - m_ui.editorList->header()->setResizeMode(1, QHeaderView::Fixed); - m_ui.editorList->header()->resizeSection(1, 16); - m_ui.editorList->setContextMenuPolicy(Qt::CustomContextMenu); - m_ui.editorList->installEventFilter(this); + setModel(em->openedEditorsModel()); + setSelectionMode(QAbstractItemView::SingleSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); + header()->setStretchLastSection(false); + header()->setResizeMode(0, QHeaderView::Stretch); + header()->setResizeMode(1, QHeaderView::Fixed); + header()->resizeSection(1, 16); + setContextMenuPolicy(Qt::CustomContextMenu); + installEventFilter(this); + viewport()->installEventFilter(this); connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)), this, SLOT(updateCurrentItem(Core::IEditor*))); - connect(m_ui.editorList, SIGNAL(clicked(QModelIndex)), + connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(handleClicked(QModelIndex))); - connect(m_ui.editorList, SIGNAL(pressed(QModelIndex)), + connect(this, SIGNAL(pressed(QModelIndex)), this, SLOT(handlePressed(QModelIndex))); - connect(m_ui.editorList, SIGNAL(customContextMenuRequested(QPoint)), + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint))); } @@ -136,30 +139,41 @@ OpenEditorsWidget::~OpenEditorsWidget() void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor) { if (!editor) { - m_ui.editorList->clearSelection(); + clearSelection(); return; } EditorManager *em = EditorManager::instance(); - m_ui.editorList->setCurrentIndex(em->openedEditorsModel()->indexOf(editor)); - m_ui.editorList->selectionModel()->select(m_ui.editorList->currentIndex(), + setCurrentIndex(em->openedEditorsModel()->indexOf(editor)); + selectionModel()->select(currentIndex(), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); - m_ui.editorList->scrollTo(m_ui.editorList->currentIndex()); + scrollTo(currentIndex()); } bool OpenEditorsWidget::eventFilter(QObject *obj, QEvent *event) { - if (obj == m_ui.editorList && event->type() == QEvent::KeyPress - && m_ui.editorList->currentIndex().isValid()) { + if (obj == this && event->type() == QEvent::KeyPress + && currentIndex().isValid()) { QKeyEvent *ke = static_cast<QKeyEvent*>(event); if ((ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter) && ke->modifiers() == 0) { - activateEditor(m_ui.editorList->currentIndex()); + activateEditor(currentIndex()); return true; } else if ((ke->key() == Qt::Key_Delete || ke->key() == Qt::Key_Backspace) && ke->modifiers() == 0) { - closeEditor(m_ui.editorList->currentIndex()); + closeEditor(currentIndex()); + } + } else if (obj == viewport() + && event->type() == QEvent::MouseButtonRelease) { + QMouseEvent * me = static_cast<QMouseEvent*>(event); + if (me->button() == Qt::MiddleButton + && me->modifiers() == Qt::NoModifier) { + QModelIndex index = indexAt(me->pos()); + if (index.isValid()) { + closeEditor(index); + return true; + } } } return false; @@ -181,7 +195,7 @@ void OpenEditorsWidget::handleClicked(const QModelIndex &index) // work around a bug in itemviews where the delegate wouldn't get the QStyle::State_MouseOver QPoint cursorPos = QCursor::pos(); - QWidget *vp = m_ui.editorList->viewport(); + QWidget *vp = viewport(); QMouseEvent e(QEvent::MouseMove, vp->mapFromGlobal(cursorPos), cursorPos, Qt::NoButton, 0, 0); QCoreApplication::sendEvent(vp, &e); } @@ -189,7 +203,7 @@ void OpenEditorsWidget::handleClicked(const QModelIndex &index) void OpenEditorsWidget::activateEditor(const QModelIndex &index) { - m_ui.editorList->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); EditorManager::instance()->activateEditorForIndex(index, EditorManager::ModeSwitch); } @@ -203,11 +217,11 @@ void OpenEditorsWidget::closeEditor(const QModelIndex &index) void OpenEditorsWidget::contextMenuRequested(QPoint pos) { QMenu contextMenu; - QModelIndex editorIndex = m_ui.editorList->indexAt(pos); + QModelIndex editorIndex = indexAt(pos); EditorManager::instance()->addCloseEditorActions(&contextMenu, editorIndex); contextMenu.addSeparator(); EditorManager::instance()->addNativeDirActions(&contextMenu, editorIndex); - contextMenu.exec(m_ui.editorList->mapToGlobal(pos)); + contextMenu.exec(mapToGlobal(pos)); } /// diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.h b/src/plugins/coreplugin/editormanager/openeditorsview.h index 628f4bfcc3..e33469f578 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsview.h +++ b/src/plugins/coreplugin/editormanager/openeditorsview.h @@ -30,11 +30,10 @@ #ifndef OPENEDITORSVIEW_H #define OPENEDITORSVIEW_H -#include "ui_openeditorsview.h" - #include <coreplugin/inavigationwidgetfactory.h> #include <QStyledItemDelegate> +#include <QTreeView> namespace Core { class IEditor; @@ -43,8 +42,6 @@ namespace Internal { class OpenEditorsDelegate : public QStyledItemDelegate { - Q_OBJECT - public: explicit OpenEditorsDelegate(QObject *parent = 0); @@ -54,7 +51,7 @@ public: mutable QModelIndex pressedIndex; }; -class OpenEditorsWidget : public QWidget +class OpenEditorsWidget : public QTreeView { Q_OBJECT @@ -74,8 +71,6 @@ private: void activateEditor(const QModelIndex &index); void closeEditor(const QModelIndex &index); - Ui::OpenEditorsView m_ui; - QWidget *m_widget; OpenEditorsDelegate *m_delegate; }; diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.ui b/src/plugins/coreplugin/editormanager/openeditorsview.ui deleted file mode 100644 index 299538e66a..0000000000 --- a/src/plugins/coreplugin/editormanager/openeditorsview.ui +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>Core::Internal::OpenEditorsView</class> - <widget class="QWidget" name="Core::Internal::OpenEditorsView"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>263</width> - <height>217</height> - </rect> - </property> - <layout class="QGridLayout"> - <property name="margin"> - <number>0</number> - </property> - <property name="spacing"> - <number>0</number> - </property> - <item row="0" column="0"> - <widget class="QTreeView" name="editorList"> - <property name="uniformRowHeights"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp index bc5623953e..c583f974e4 100644 --- a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp @@ -33,6 +33,7 @@ #include "editorview.h" #include "idocument.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QFocusEvent> @@ -60,16 +61,14 @@ OpenEditorsWindow::OpenEditorsWindow(QWidget *parent) : m_editorList->setIndentation(0); m_editorList->setSelectionMode(QAbstractItemView::SingleSelection); m_editorList->setTextElideMode(Qt::ElideMiddle); -#ifdef Q_OS_MAC - m_editorList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); -#endif + if (Utils::HostOsInfo::isMacHost()) + m_editorList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); m_editorList->installEventFilter(this); // We disable the frame on this list view and use a QFrame around it instead. // This improves the look with QGTKStyle. -#ifndef Q_OS_MAC - setFrameStyle(m_editorList->frameStyle()); -#endif + if (!Utils::HostOsInfo::isMacHost()) + setFrameStyle(m_editorList->frameStyle()); m_editorList->setFrameStyle(QFrame::NoFrame); QVBoxLayout *layout = new QVBoxLayout(this); diff --git a/src/plugins/coreplugin/editortoolbar.cpp b/src/plugins/coreplugin/editortoolbar.cpp index a159771ab3..7dafb93e0c 100644 --- a/src/plugins/coreplugin/editortoolbar.cpp +++ b/src/plugins/coreplugin/editortoolbar.cpp @@ -43,6 +43,7 @@ #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/command.h> +#include <utils/hostosinfo.h> #include <utils/parameteraction.h> #include <utils/qtcassert.h> #include <utils/styledbar.h> @@ -133,6 +134,7 @@ EditorToolBar::EditorToolBar(QWidget *parent) : connect(d->m_goForwardAction, SIGNAL(triggered()), this, SIGNAL(goForwardClicked())); d->m_editorList->setProperty("hideicon", true); + d->m_editorList->setProperty("notelideasterisk", true); d->m_editorList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); d->m_editorList->setMinimumContentsLength(20); d->m_editorList->setModel(d->m_editorsListModel); @@ -151,10 +153,10 @@ EditorToolBar::EditorToolBar(QWidget *parent) : d->m_forwardButton= new QToolButton(this); d->m_forwardButton->setDefaultAction(d->m_goForwardAction); -#ifdef Q_OS_MAC - d->m_horizontalSplitAction->setIconVisibleInMenu(false); - d->m_verticalSplitAction->setIconVisibleInMenu(false); -#endif + if (Utils::HostOsInfo::isMacHost()) { + d->m_horizontalSplitAction->setIconVisibleInMenu(false); + d->m_verticalSplitAction->setIconVisibleInMenu(false); + } d->m_splitButton->setIcon(QIcon(QLatin1String(Constants::ICON_SPLIT_HORIZONTAL))); d->m_splitButton->setToolTip(tr("Split")); diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp index aa92b93bbc..4ca58779ed 100644 --- a/src/plugins/coreplugin/fancytabwidget.cpp +++ b/src/plugins/coreplugin/fancytabwidget.cpp @@ -28,6 +28,7 @@ ****************************************************************************/ #include "fancytabwidget.h" +#include <utils/hostosinfo.h> #include <utils/stylehelper.h> #include <utils/styledbar.h> @@ -273,23 +274,23 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const } QString tabText(this->tabText(tabIndex)); - QRect tabTextRect(tabRect(tabIndex)); + QRect tabTextRect(rect); + const bool drawIcon = rect.height() > 36; QRect tabIconRect(tabTextRect); - tabTextRect.translate(0, -2); + tabTextRect.translate(0, drawIcon ? -2 : 1); QFont boldFont(painter->font()); boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); boldFont.setBold(true); painter->setFont(boldFont); painter->setPen(selected ? QColor(255, 255, 255, 160) : QColor(0, 0, 0, 110)); - int textFlags = Qt::AlignCenter | Qt::AlignBottom | Qt::TextWordWrap; + const int textFlags = Qt::AlignCenter | (drawIcon ? Qt::AlignBottom : Qt::AlignVCenter) | Qt::TextWordWrap; if (enabled) { painter->drawText(tabTextRect, textFlags, tabText); painter->setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor()); } else { painter->setPen(selected ? Utils::StyleHelper::panelTextColor() : QColor(255, 255, 255, 120)); } -#ifndef Q_OS_MAC - if (!selected && enabled) { + if (!Utils::HostOsInfo::isMacHost() && !selected && enabled) { painter->save(); int fader = int(m_tabs[tabIndex]->fader()); QLinearGradient grad(rect.topLeft(), rect.topRight()); @@ -302,14 +303,15 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const painter->drawLine(rect.bottomLeft(), rect.bottomRight()); painter->restore(); } -#endif if (!enabled) painter->setOpacity(0.7); - int textHeight = painter->fontMetrics().boundingRect(QRect(0, 0, width(), height()), Qt::TextWordWrap, tabText).height(); - tabIconRect.adjust(0, 4, 0, -textHeight); - Utils::StyleHelper::drawIconWithShadow(tabIcon(tabIndex), tabIconRect, painter, enabled ? QIcon::Normal : QIcon::Disabled); + if (drawIcon) { + int textHeight = painter->fontMetrics().boundingRect(QRect(0, 0, width(), height()), Qt::TextWordWrap, tabText).height(); + tabIconRect.adjust(0, 4, 0, -textHeight); + Utils::StyleHelper::drawIconWithShadow(tabIcon(tabIndex), tabIconRect, painter, enabled ? QIcon::Normal : QIcon::Disabled); + } painter->translate(0, -1); painter->drawText(tabTextRect, textFlags, tabText); diff --git a/src/plugins/coreplugin/featureprovider.h b/src/plugins/coreplugin/featureprovider.h index a408ea8cfc..7313bbf969 100644 --- a/src/plugins/coreplugin/featureprovider.h +++ b/src/plugins/coreplugin/featureprovider.h @@ -63,7 +63,7 @@ class CORE_EXPORT Feature : public Id { friend class FeatureSet; public: - Feature(const char *name) : Id(name) {} + Feature(const char *name) : Id(QByteArray(name)) {} explicit Feature(const QString &name) : Id(name) {} }; diff --git a/src/plugins/coreplugin/fileiconprovider.cpp b/src/plugins/coreplugin/fileiconprovider.cpp index 48f84706f0..e77b32c63a 100644 --- a/src/plugins/coreplugin/fileiconprovider.cpp +++ b/src/plugins/coreplugin/fileiconprovider.cpp @@ -30,6 +30,7 @@ #include "fileiconprovider.h" #include "mimedatabase.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QApplication> @@ -43,6 +44,8 @@ #include <QIcon> #include <QStyle> +using namespace Utils; + /*! \class Core::FileIconProvider @@ -138,14 +141,13 @@ QIcon FileIconProvider::icon(const QFileInfo &fileInfo) const } } // Get icon from OS. -#if defined(Q_OS_WIN) || defined(Q_OS_MAC) - return QFileIconProvider::icon(fileInfo); -#else + if (HostOsInfo::isWindowsHost() || HostOsInfo::isMacHost()) + return QFileIconProvider::icon(fileInfo); + // File icons are unknown on linux systems. return (fileInfo.isDir()) ? QFileIconProvider::icon(fileInfo) : d->m_unknownFileIcon; -#endif } /*! diff --git a/src/plugins/coreplugin/fileutils.cpp b/src/plugins/coreplugin/fileutils.cpp index ee76d2c023..7eb5431653 100644 --- a/src/plugins/coreplugin/fileutils.cpp +++ b/src/plugins/coreplugin/fileutils.cpp @@ -110,7 +110,7 @@ void FileUtils::showInGraphicalShell(QWidget *parent, const QString &pathIn) scriptArgs.clear(); scriptArgs << QLatin1String("-e") << QLatin1String("tell application \"Finder\" to activate"); - QProcess::execute("/usr/bin/osascript", scriptArgs); + QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs); #else // we cannot select a file here, because no file browser really supports it... const QFileInfo fileInfo(pathIn); diff --git a/src/plugins/coreplugin/icontext.cpp b/src/plugins/coreplugin/icontext.cpp index 9a6fcd227d..80472d2fcc 100644 --- a/src/plugins/coreplugin/icontext.cpp +++ b/src/plugins/coreplugin/icontext.cpp @@ -42,12 +42,12 @@ Context::Context(const char *id, int offset) void Context::add(const char *id) { - d.append(Id(id).uniqueIdentifier()); + d.append(Id(QByteArray(id)).uniqueIdentifier()); } bool Context::contains(const char *id) const { - return d.contains(Id(id).uniqueIdentifier()); + return d.contains(Id(QByteArray(id)).uniqueIdentifier()); } } // namespace Core diff --git a/src/plugins/coreplugin/id.cpp b/src/plugins/coreplugin/id.cpp index aa98d4db01..cebc36830b 100644 --- a/src/plugins/coreplugin/id.cpp +++ b/src/plugins/coreplugin/id.cpp @@ -52,13 +52,13 @@ namespace Core { class StringHolder { public: - explicit StringHolder(const char *s) - : str(s) + StringHolder(const char *s, int length) + : n(length), str(s) { - n = strlen(s); - int m = n; + if (!n) + length = n = strlen(s); h = 0; - while (m--) { + while (length--) { h = (h << 4) + *s++; h ^= (h & 0xf0000000) >> 23; h &= 0x0fffffff; @@ -97,10 +97,10 @@ static int lastUid = 0; static QVector<QByteArray> stringFromId; static IdCache idFromString; -static int theId(const char *str) +static int theId(const char *str, int n = 0) { QTC_ASSERT(str && *str, return 0); - StringHolder sh(str); + StringHolder sh(str, n); int res = idFromString.value(sh, 0); if (res == 0) { if (lastUid == 0) @@ -113,8 +113,17 @@ static int theId(const char *str) return res; } +static int theId(const QByteArray &ba) +{ + return theId(ba.constData(), ba.size()); +} + Id::Id(const char *name) - : m_id(theId(name)) + : m_id(theId(name, 0)) +{} + +Id::Id(const QByteArray &name) + : m_id(theId(name)) {} Id::Id(const QString &name) diff --git a/src/plugins/coreplugin/id.h b/src/plugins/coreplugin/id.h index c5f485a0de..eae2aa68ed 100644 --- a/src/plugins/coreplugin/id.h +++ b/src/plugins/coreplugin/id.h @@ -43,7 +43,8 @@ class CORE_EXPORT Id public: Id() : m_id(0) {} Id(const char *name); - // FIXME: Replace with QByteArray + explicit Id(const QByteArray &name); + // FIXME: Remove explicit Id(const QString &name); QByteArray name() const; QString toString() const; diff --git a/src/plugins/coreplugin/idocument.cpp b/src/plugins/coreplugin/idocument.cpp index 6c1a57d56a..a55c1599ac 100644 --- a/src/plugins/coreplugin/idocument.cpp +++ b/src/plugins/coreplugin/idocument.cpp @@ -85,7 +85,7 @@ void IDocument::setRestoredFrom(const QString &name) { m_autoSaveName = name; m_restored = true; - InfoBarEntry info(QLatin1String(kRestoredAutoSave), + InfoBarEntry info(Id(kRestoredAutoSave), tr("File was restored from auto-saved copy. " "Select Save to confirm or Revert to Saved to discard changes.")); infoBar()->addInfo(info); @@ -98,7 +98,7 @@ void IDocument::removeAutoSaveFile() m_autoSaveName.clear(); if (m_restored) { m_restored = false; - infoBar()->removeInfo(QLatin1String(kRestoredAutoSave)); + infoBar()->removeInfo(Id(kRestoredAutoSave)); } } } diff --git a/src/plugins/coreplugin/inavigationwidgetfactory.h b/src/plugins/coreplugin/inavigationwidgetfactory.h index 95b9b5880c..1a3d1aa163 100644 --- a/src/plugins/coreplugin/inavigationwidgetfactory.h +++ b/src/plugins/coreplugin/inavigationwidgetfactory.h @@ -30,7 +30,7 @@ #ifndef INAVIGATIONWIDGET_H #define INAVIGATIONWIDGET_H -#include <coreplugin/id.h> +#include "id.h" #include <QObject> #include <QList> diff --git a/src/plugins/coreplugin/infobar.cpp b/src/plugins/coreplugin/infobar.cpp index d2b9c4b3f7..a2eb2d9310 100644 --- a/src/plugins/coreplugin/infobar.cpp +++ b/src/plugins/coreplugin/infobar.cpp @@ -40,7 +40,7 @@ namespace Core { -InfoBarEntry::InfoBarEntry(const QString &_id, const QString &_infoText) +InfoBarEntry::InfoBarEntry(Id _id, const QString &_infoText) : id(_id) , infoText(_infoText) , object(0) @@ -77,7 +77,7 @@ void InfoBar::addInfo(const InfoBarEntry &info) emit changed(); } -void InfoBar::removeInfo(const QString &id) +void InfoBar::removeInfo(Id id) { QMutableListIterator<InfoBarEntry> it(m_infoBarEntries); while (it.hasNext()) @@ -88,7 +88,7 @@ void InfoBar::removeInfo(const QString &id) } } -bool InfoBar::containsInfo(const QString &id) const +bool InfoBar::containsInfo(Id id) const { QListIterator<InfoBarEntry> it(m_infoBarEntries); while (it.hasNext()) @@ -183,7 +183,7 @@ void InfoBarDisplay::update() } QToolButton *infoWidgetCloseButton = new QToolButton; - infoWidgetCloseButton->setProperty("infoId", info.id); + infoWidgetCloseButton->setProperty("infoId", info.id.uniqueIdentifier()); // need to connect to cancelObjectbefore connecting to cancelButtonClicked, // because the latter removes the button and with it any connect @@ -210,13 +210,12 @@ void InfoBarDisplay::update() void InfoBarDisplay::widgetDestroyed() { - // This means that the parent is being deleted - m_infoWidgets.clear(); + m_infoWidgets.removeOne(static_cast<QWidget *>(sender())); } void InfoBarDisplay::cancelButtonClicked() { - m_infoBar->removeInfo(sender()->property("infoId").toString()); + m_infoBar->removeInfo(Id::fromUniqueIdentifier(sender()->property("infoId").toInt())); } } // namespace Core diff --git a/src/plugins/coreplugin/infobar.h b/src/plugins/coreplugin/infobar.h index fe74197664..b1993d8aa0 100644 --- a/src/plugins/coreplugin/infobar.h +++ b/src/plugins/coreplugin/infobar.h @@ -31,6 +31,7 @@ #define INFOBAR_H #include "core_global.h" +#include <coreplugin/id.h> #include <QObject> @@ -46,14 +47,14 @@ class InfoBarDisplay; class CORE_EXPORT InfoBarEntry { public: - InfoBarEntry(const QString &_id, const QString &_infoText); + InfoBarEntry(Id _id, const QString &_infoText); InfoBarEntry(const InfoBarEntry &other) { *this = other; } void setCustomButtonInfo(const QString &_buttonText, QObject *_object, const char *_member); void setCancelButtonInfo(QObject *_object, const char *_member); void setCancelButtonInfo(const QString &_cancelButtonText, QObject *_object, const char *_member); private: - QString id; + Id id; QString infoText; QString buttonText; QObject *object; @@ -71,8 +72,8 @@ class CORE_EXPORT InfoBar : public QObject public: void addInfo(const InfoBarEntry &info); - void removeInfo(const QString &id); - bool containsInfo(const QString &id) const; + void removeInfo(Id id); + bool containsInfo(Id id) const; void clear(); signals: diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp index cfb2537897..e92052c656 100644 --- a/src/plugins/coreplugin/iversioncontrol.cpp +++ b/src/plugins/coreplugin/iversioncontrol.cpp @@ -41,4 +41,9 @@ QString IVersionControl::vcsMakeWritableText() const return QString(); } +QString IVersionControl::vcsTopic(const QString &) +{ + return QString(); +} + } diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index f77c133ee5..e150fedcf6 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -137,6 +137,11 @@ public: virtual QString vcsGetRepositoryURL(const QString &director) = 0; /*! + * Topic (e.g. name of the current branch) + */ + virtual QString vcsTopic(const QString &directory); + + /*! * Create a snapshot of the current state and return an identifier or * an empty string in case of failure. */ diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index a8e9160de1..526a4ea06c 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -82,6 +82,7 @@ #include <coreplugin/inavigationwidgetfactory.h> #include <coreplugin/settingsdatabase.h> #include <utils/historycompleter.h> +#include <utils/hostosinfo.h> #include <utils/pathchooser.h> #include <utils/stylehelper.h> #include <utils/stringutils.h> @@ -179,28 +180,27 @@ MainWindow::MainWindow() : Utils::HistoryCompleter::setSettings(m_settings); setWindowTitle(tr("Qt Creator")); -#ifndef Q_OS_MAC - QApplication::setWindowIcon(QIcon(QLatin1String(Constants::ICON_QTLOGO_128))); -#endif + if (!Utils::HostOsInfo::isMacHost()) + QApplication::setWindowIcon(QIcon(QLatin1String(Constants::ICON_QTLOGO_128))); QCoreApplication::setApplicationName(QLatin1String("QtCreator")); QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::IDE_VERSION_LONG)); QCoreApplication::setOrganizationName(QLatin1String(Constants::IDE_SETTINGSVARIANT_STR)); QString baseName = QApplication::style()->objectName(); -#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) - if (baseName == QLatin1String("windows")) { - // Sometimes we get the standard windows 95 style as a fallback - if (QStyleFactory::keys().contains("Fusion")) - baseName = QLatin1String("fusion"); // Qt5 - else { // Qt4 - // e.g. if we are running on a KDE4 desktop - QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION"); - if (desktopEnvironment == "kde") - baseName = QLatin1String("plastique"); - else - baseName = QLatin1String("cleanlooks"); + if (Utils::HostOsInfo::isAnyUnixHost() && !Utils::HostOsInfo::isMacHost()) { + if (baseName == QLatin1String("windows")) { + // Sometimes we get the standard windows 95 style as a fallback + if (QStyleFactory::keys().contains(QLatin1String("Fusion"))) + baseName = QLatin1String("fusion"); // Qt5 + else { // Qt4 + // e.g. if we are running on a KDE4 desktop + QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION"); + if (desktopEnvironment == "kde") + baseName = QLatin1String("plastique"); + else + baseName = QLatin1String("cleanlooks"); + } } } -#endif qApp->setStyle(new ManhattanStyle(baseName)); setDockNestingEnabled(true); @@ -485,9 +485,8 @@ void MainWindow::registerDefaultContainers() { ActionContainer *menubar = ActionManager::createMenuBar(Constants::MENU_BAR); -#ifndef Q_OS_MAC // System menu bar on Mac - setMenuBar(menubar->menuBar()); -#endif + if (!Utils::HostOsInfo::isMacHost()) // System menu bar on Mac + setMenuBar(menubar->menuBar()); menubar->appendGroup(Constants::G_FILE); menubar->appendGroup(Constants::G_EDIT); menubar->appendGroup(Constants::G_VIEW); @@ -745,19 +744,18 @@ void MainWindow::registerDefaultActions() mwindow->addAction(cmd, Constants::G_WINDOW_VIEWS); m_toggleSideBarAction->setEnabled(false); + #if defined(Q_OS_MAC) - bool fullScreenCheckable = false; const QString fullScreenActionText(tr("Enter Full Screen")); bool supportsFullScreen = MacFullScreen::supportsFullScreen(); #else - bool fullScreenCheckable = true; const QString fullScreenActionText(tr("Full Screen")); bool supportsFullScreen = true; #endif if (supportsFullScreen) { // Full Screen Action m_toggleFullScreenAction = new QAction(fullScreenActionText, this); - m_toggleFullScreenAction->setCheckable(fullScreenCheckable); + m_toggleFullScreenAction->setCheckable(!Utils::HostOsInfo::isMacHost()); cmd = ActionManager::registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, globalContext); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Meta+F") : tr("Ctrl+Shift+F11"))); cmd->setAttribute(Command::CA_UpdateText); /* for Mac */ @@ -772,17 +770,15 @@ void MainWindow::registerDefaultActions() // About IDE Action icon = QIcon::fromTheme(QLatin1String("help-about")); -#ifdef Q_OS_MAC - tmpaction = new QAction(icon, tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu -#else - tmpaction = new QAction(icon, tr("About &Qt Creator..."), this); -#endif + if (Utils::HostOsInfo::isMacHost()) + tmpaction = new QAction(icon, tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu + else + tmpaction = new QAction(icon, tr("About &Qt Creator..."), this); cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_QTCREATOR, globalContext); mhelp->addAction(cmd, Constants::G_HELP_ABOUT); tmpaction->setEnabled(true); -#ifdef Q_OS_MAC - cmd->action()->setMenuRole(QAction::ApplicationSpecificRole); -#endif + if (Utils::HostOsInfo::isMacHost()) + cmd->action()->setMenuRole(QAction::ApplicationSpecificRole); connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutQtCreator())); //About Plugins Action @@ -790,9 +786,8 @@ void MainWindow::registerDefaultActions() cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_PLUGINS, globalContext); mhelp->addAction(cmd, Constants::G_HELP_ABOUT); tmpaction->setEnabled(true); -#ifdef Q_OS_MAC - cmd->action()->setMenuRole(QAction::ApplicationSpecificRole); -#endif + if (Utils::HostOsInfo::isMacHost()) + cmd->action()->setMenuRole(QAction::ApplicationSpecificRole); connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutPlugins())); // About Qt Action // tmpaction = new QAction(tr("About &Qt..."), this); @@ -801,12 +796,12 @@ void MainWindow::registerDefaultActions() // tmpaction->setEnabled(true); // connect(tmpaction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); // About sep -#ifndef Q_OS_MAC // doesn't have the "About" actions in the Help menu - tmpaction = new QAction(this); - tmpaction->setSeparator(true); - cmd = ActionManager::registerAction(tmpaction, "QtCreator.Help.Sep.About", globalContext); - mhelp->addAction(cmd, Constants::G_HELP_ABOUT); -#endif + if (!Utils::HostOsInfo::isMacHost()) { // doesn't have the "About" actions in the Help menu + tmpaction = new QAction(this); + tmpaction->setSeparator(true); + cmd = ActionManager::registerAction(tmpaction, "QtCreator.Help.Sep.About", globalContext); + mhelp->addAction(cmd, Constants::G_HELP_ABOUT); + } } void MainWindow::newFile() diff --git a/src/plugins/coreplugin/manhattanstyle.cpp b/src/plugins/coreplugin/manhattanstyle.cpp index 3b0163217a..330f6576d3 100644 --- a/src/plugins/coreplugin/manhattanstyle.cpp +++ b/src/plugins/coreplugin/manhattanstyle.cpp @@ -718,7 +718,20 @@ void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *opt editRect.adjust(0, 0, -13, 0); } - QString text = option->fontMetrics.elidedText(cb->currentText, Qt::ElideRight, editRect.width()); + QLatin1Char asterisk('*'); + int elideWidth = editRect.width(); + + bool notElideAsterisk = widget && widget->property("notelideasterisk").toBool() + && cb->currentText.endsWith(asterisk) + && option->fontMetrics.width(cb->currentText) > elideWidth; + + QString text; + if (notElideAsterisk) { + elideWidth -= option->fontMetrics.width(asterisk); + text = asterisk; + } + text.prepend(option->fontMetrics.elidedText(cb->currentText, Qt::ElideRight, elideWidth)); + if ((option->state & State_Enabled)) { painter->setPen(QColor(0, 0, 0, 70)); painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text); diff --git a/src/plugins/coreplugin/mimedatabase.cpp b/src/plugins/coreplugin/mimedatabase.cpp index 5a99c3fbae..95ddaf091d 100644 --- a/src/plugins/coreplugin/mimedatabase.cpp +++ b/src/plugins/coreplugin/mimedatabase.cpp @@ -1093,7 +1093,7 @@ bool BaseMimeTypeParser::parse(QIODevice *dev, const QString &fileName, QString case ParseComment: { // comments have locale attributes. We want the default, English one QString locale = atts.value(QLatin1String(localeAttributeC)).toString(); - const QString comment = QCoreApplication::translate("MimeType", reader.readElementText().toAscii()); + const QString comment = QCoreApplication::translate("MimeType", reader.readElementText().toLatin1()); if (locale.isEmpty()) { data.comment = comment; } else { @@ -1357,14 +1357,13 @@ bool MimeDatabasePrivate::addMimeType(MimeType mt) } // insert the type. m_typeMimeTypeMap.insert(type, MimeMapEntry(mt)); - // Register the children, resolved via alias map. Note that it is still - // possible that aliases end up in the map if the parent classes are not inserted - // at this point (thus their aliases not known). + // Register the children + // Aliases will be resolved later once all mime types are known. const QStringList subClassesOf = mt.subClassesOf(); if (!subClassesOf.empty()) { const QStringList::const_iterator socend = subClassesOf.constEnd(); for (QStringList::const_iterator soit = subClassesOf.constBegin(); soit != socend; ++soit) - m_parentChildrenMap.insert(resolveAlias(*soit), type); + m_parentChildrenMap.insert(*soit, type); } // register aliasses const QStringList aliases = mt.aliases(); @@ -1391,7 +1390,9 @@ void MimeDatabasePrivate::raiseLevelRecursion(MimeMapEntry &e, int level) m_maxLevel = level; // At all events recurse over children since nodes might have been // added. - const QStringList childTypes = m_parentChildrenMap.values(e.type.type()); + QStringList childTypes = m_parentChildrenMap.values(e.type.type()); + foreach (const QString &alias, e.type.aliases()) + childTypes.append(m_parentChildrenMap.values(alias)); if (childTypes.empty()) return; // look them up in the type->mime type map @@ -1495,8 +1496,8 @@ MimeType MimeDatabasePrivate::findByFile(const QFileInfo &f, unsigned *priorityP // Pass 1) Try to match on suffix const TypeMimeTypeMap::const_iterator cend = m_typeMimeTypeMap.constEnd(); - for (int level = m_maxLevel; level >= 0 && candidate.isNull(); level--) - for (TypeMimeTypeMap::const_iterator it = m_typeMimeTypeMap.constBegin(); it != cend; ++it) + for (int level = m_maxLevel; level >= 0 && candidate.isNull(); level--) { + for (TypeMimeTypeMap::const_iterator it = m_typeMimeTypeMap.constBegin(); it != cend; ++it) { if (it.value().level == level) { const unsigned suffixPriority = it.value().type.matchesFileBySuffix(context); if (suffixPriority && suffixPriority > *priorityPtr) { @@ -1506,12 +1507,14 @@ MimeType MimeDatabasePrivate::findByFile(const QFileInfo &f, unsigned *priorityP return candidate; } } + } + } // Pass 2) Match on content if (!f.isReadable()) return candidate; - for (int level = m_maxLevel; level >= 0; level--) - for (TypeMimeTypeMap::const_iterator it = m_typeMimeTypeMap.constBegin(); it != cend; ++it) + for (int level = m_maxLevel; level >= 0; level--) { + for (TypeMimeTypeMap::const_iterator it = m_typeMimeTypeMap.constBegin(); it != cend; ++it) { if (it.value().level == level) { const unsigned contentPriority = it.value().type.matchesFileByContent(context); if (contentPriority && contentPriority > *priorityPtr) { @@ -1519,6 +1522,8 @@ MimeType MimeDatabasePrivate::findByFile(const QFileInfo &f, unsigned *priorityP candidate = it.value().type; } } + } + } return candidate; } @@ -1672,11 +1677,11 @@ QList<MimeType> MimeDatabasePrivate::readUserModifiedMimeTypes() switch (reader.readNext()) { case QXmlStreamReader::StartElement: atts = reader.attributes(); - if (reader.name() == mimeTypeTagC) { + if (reader.name() == QLatin1String(mimeTypeTagC)) { mimeType.setType(atts.value(mimeTypeAttribute).toString()); const QString &patterns = atts.value(patternAttribute).toString(); mimeType.setGlobPatterns(toGlobPatterns(patterns.split(kSemiColon))); - } else if (reader.name() == matchTagC) { + } else if (reader.name() == QLatin1String(matchTagC)) { const QString &value = atts.value(matchValueAttribute).toString(); const QString &type = atts.value(matchTypeAttribute).toString(); const QString &offset = atts.value(matchOffsetAttribute).toString(); @@ -1692,7 +1697,7 @@ QList<MimeType> MimeDatabasePrivate::readUserModifiedMimeTypes() } break; case QXmlStreamReader::EndElement: - if (reader.name() == mimeTypeTagC) { + if (reader.name() == QLatin1String(mimeTypeTagC)) { mimeType.setMagicRuleMatchers(MagicRuleMatcher::createMatchers(rules)); mimeTypes.append(mimeType); mimeType.clear(); diff --git a/src/plugins/coreplugin/mimetypesettings.cpp b/src/plugins/coreplugin/mimetypesettings.cpp index 0e94ce750c..2e0fb7b911 100644 --- a/src/plugins/coreplugin/mimetypesettings.cpp +++ b/src/plugins/coreplugin/mimetypesettings.cpp @@ -232,6 +232,7 @@ public slots: void removeMagicHeader(); void editMagicHeader(); void resetMimeTypes(); + void updateMagicHeaderButtons(); public: static const QChar kSemiColon; @@ -281,6 +282,11 @@ void MimeTypeSettingsPrivate::configureUi(QWidget *w) connect(m_ui.removeMagicButton, SIGNAL(clicked()), this, SLOT(removeMagicHeader())); connect(m_ui.editMagicButton, SIGNAL(clicked()), this, SLOT(editMagicHeader())); connect(m_ui.resetButton, SIGNAL(clicked()), this, SLOT(resetMimeTypes())); + connect(m_ui.magicHeadersTableWidget->selectionModel(), + SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, + SLOT(updateMagicHeaderButtons())); + updateMagicHeaderButtons(); } void MimeTypeSettingsPrivate::configureTable(QTableView *tableView) @@ -538,6 +544,15 @@ void MimeTypeSettingsPrivate::resetMimeTypes() m_reset = true; } +void MimeTypeSettingsPrivate::updateMagicHeaderButtons() +{ + const QModelIndex &modelIndex = m_ui.magicHeadersTableWidget->selectionModel()->currentIndex(); + const bool enabled(modelIndex.isValid()); + + m_ui.removeMagicButton->setEnabled(enabled); + m_ui.editMagicButton->setEnabled(enabled); +} + // MimeTypeSettingsPage MimeTypeSettings::MimeTypeSettings(QObject *parent) : IOptionsPage(parent) diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp index 393b2b3b61..07b36544bd 100644 --- a/src/plugins/coreplugin/outputpanemanager.cpp +++ b/src/plugins/coreplugin/outputpanemanager.cpp @@ -47,6 +47,7 @@ #include <extensionsystem/pluginmanager.h> +#include <utils/hostosinfo.h> #include <utils/styledbar.h> #include <utils/qtcassert.h> @@ -197,11 +198,7 @@ QWidget *OutputPaneManager::buttonsWidget() // Return shortcut as Ctrl+<number> static inline int paneShortCut(int number) { -#ifdef Q_OS_MAC - int modifier = Qt::CTRL; -#else - int modifier = Qt::ALT; -#endif + const int modifier = Utils::HostOsInfo::isMacHost() ? Qt::CTRL : Qt::ALT; return modifier | (Qt::Key_0 + number); } @@ -636,7 +633,7 @@ OutputPaneToggleButton::OutputPaneToggleButton(int number, const QString &text, fnt.setPixelSize(11); m_label->setFont(fnt); m_label->setAlignment(Qt::AlignCenter); - m_label->setStyleSheet("background-color: #818181; color: white; border-radius: 6; padding-left: 4; padding-right: 4;"); + m_label->setStyleSheet(QLatin1String("background-color: #818181; color: white; border-radius: 6; padding-left: 4; padding-right: 4;")); m_label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); m_label->hide(); } @@ -703,9 +700,11 @@ void OutputPaneToggleButton::checkStateSet() m_flashTimer->stop(); if (isChecked()) - m_label->setStyleSheet("background-color: #e1e1e1; color: #606060; border-radius: 6; padding-left: 4; padding-right: 4;"); + m_label->setStyleSheet(QLatin1String("background-color: #e1e1e1; color: #606060; " + "border-radius: 6; padding-left: 4; padding-right: 4;")); else - m_label->setStyleSheet("background-color: #818181; color: white; border-radius: 6; padding-left: 4; padding-right: 4;"); + m_label->setStyleSheet(QLatin1String("background-color: #818181; color: white; border-radius: 6; " + "padding-left: 4; padding-right: 4;")); } void OutputPaneToggleButton::flash(int count) diff --git a/src/plugins/coreplugin/progressmanager/progressmanager.cpp b/src/plugins/coreplugin/progressmanager/progressmanager.cpp index 33a340cef9..5ba52283fd 100644 --- a/src/plugins/coreplugin/progressmanager/progressmanager.cpp +++ b/src/plugins/coreplugin/progressmanager/progressmanager.cpp @@ -29,8 +29,8 @@ #include "progressmanager_p.h" #include "progressview.h" -#include "coreconstants.h" -#include "icore.h" +#include "../coreconstants.h" +#include "../icore.h" #include <utils/qtcassert.h> diff --git a/src/plugins/coreplugin/scriptmanager/scriptmanager.cpp b/src/plugins/coreplugin/scriptmanager/scriptmanager.cpp index 553d105628..635dd3ebd7 100644 --- a/src/plugins/coreplugin/scriptmanager/scriptmanager.cpp +++ b/src/plugins/coreplugin/scriptmanager/scriptmanager.cpp @@ -95,7 +95,7 @@ static QScriptValue inputDialogGetInteger(QScriptContext *context, QScriptEngine const int maxValue = argumentCount > 5 ? context->argument(5).toInt32() : INT_MAX; bool ok; - const int rc = QInputDialog::getInteger(parent, title, label, defaultValue, minValue, maxValue, 1, &ok); + const int rc = QInputDialog::getInt(parent, title, label, defaultValue, minValue, maxValue, 1, &ok); if (!ok) return QScriptValue(engine, QScriptValue::NullValue); return QScriptValue(engine, rc); diff --git a/src/plugins/coreplugin/sidebar.cpp b/src/plugins/coreplugin/sidebar.cpp index ae61528dac..8b6d7c0689 100644 --- a/src/plugins/coreplugin/sidebar.cpp +++ b/src/plugins/coreplugin/sidebar.cpp @@ -41,6 +41,7 @@ #include <QLayout> #include <QToolBar> #include <QAction> +#include <QPointer> #include <QToolButton> namespace Core { @@ -79,7 +80,7 @@ struct SideBarPrivate { SideBarPrivate() :m_closeWhenEmpty(false) {} QList<Internal::SideBarWidget*> m_widgets; - QMap<QString, QWeakPointer<SideBarItem> > m_itemMap; + QMap<QString, QPointer<SideBarItem> > m_itemMap; QStringList m_availableItemIds; QStringList m_availableItemTitles; QStringList m_unavailableItemIds; @@ -108,7 +109,7 @@ SideBar::SideBar(QList<SideBarItem*> itemList, SideBar::~SideBar() { - foreach (const QWeakPointer<SideBarItem> &i, d->m_itemMap) + foreach (const QPointer<SideBarItem> &i, d->m_itemMap) if (!i.isNull()) delete i.data(); delete d; @@ -116,7 +117,7 @@ SideBar::~SideBar() QString SideBar::idForTitle(const QString &title) const { - QMapIterator<QString, QWeakPointer<SideBarItem> > iter(d->m_itemMap); + QMapIterator<QString, QPointer<SideBarItem> > iter(d->m_itemMap); while(iter.hasNext()) { iter.next(); if (iter.value().data()->title() == title) @@ -151,7 +152,7 @@ void SideBar::setCloseWhenEmpty(bool value) void SideBar::makeItemAvailable(SideBarItem *item) { - typedef QMap<QString, QWeakPointer<SideBarItem> >::const_iterator Iterator; + typedef QMap<QString, QPointer<SideBarItem> >::const_iterator Iterator; const Iterator cend = d->m_itemMap.constEnd(); for (Iterator it = d->m_itemMap.constBegin(); it != cend ; ++it) { @@ -265,7 +266,7 @@ void SideBar::saveSettings(QSettings *settings, const QString &name) views.append(currentItemId); } if (views.isEmpty() && d->m_itemMap.size()) { - QMapIterator<QString, QWeakPointer<SideBarItem> > iter(d->m_itemMap); + QMapIterator<QString, QPointer<SideBarItem> > iter(d->m_itemMap); iter.next(); views.append(iter.key()); } @@ -321,7 +322,7 @@ void SideBar::readSettings(QSettings *settings, const QString &name) void SideBar::activateItem(SideBarItem *item) { - typedef QMap<QString, QWeakPointer<SideBarItem> >::const_iterator Iterator; + typedef QMap<QString, QPointer<SideBarItem> >::const_iterator Iterator; QString id; const Iterator cend = d->m_itemMap.constEnd(); diff --git a/src/plugins/coreplugin/variablechooser.cpp b/src/plugins/coreplugin/variablechooser.cpp index 6800f11a17..bfe806fcd0 100644 --- a/src/plugins/coreplugin/variablechooser.cpp +++ b/src/plugins/coreplugin/variablechooser.cpp @@ -60,7 +60,7 @@ VariableChooser::VariableChooser(QWidget *parent) : VariableManager *vm = VariableManager::instance(); foreach (const QByteArray &variable, vm->variables()) - ui->variableList->addItem(variable); + ui->variableList->addItem(QString::fromLatin1(variable)); connect(ui->variableList, SIGNAL(currentTextChanged(QString)), this, SLOT(updateDescription(QString))); diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp index ec9cda5e6c..0418014f27 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -209,7 +209,7 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const QString &input return 0; // Make sure we a clean absolute path: - const QString directory = QDir(inputDirectory).absolutePath(); + const QString directory = QDir(inputDirectory).canonicalPath(); VcsManagerPrivate::VcsInfo *cachedData = d->findInCache(directory); if (cachedData) { @@ -242,7 +242,7 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const QString &input } // Register Vcs(s) with the cache - QString tmpDir = directory; + QString tmpDir = QFileInfo(directory).canonicalFilePath(); const QChar slash = QLatin1Char('/'); const StringVersionControlPairs::const_iterator cend = allThatCanManage.constEnd(); for (StringVersionControlPairs::const_iterator i = allThatCanManage.constBegin(); i != cend; ++i) { diff --git a/src/plugins/cpaster/codepasterprotocol.cpp b/src/plugins/cpaster/codepasterprotocol.cpp index 7be3a769ae..7d0048cc77 100644 --- a/src/plugins/cpaster/codepasterprotocol.cpp +++ b/src/plugins/cpaster/codepasterprotocol.cpp @@ -37,6 +37,7 @@ #include <coreplugin/messagemanager.h> #include <coreplugin/messageoutputwindow.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QListWidget> @@ -76,12 +77,9 @@ bool CodePasterProtocol::checkConfiguration(QString *errorMessage) const QString hostName = m_page->hostName(); if (hostName.isEmpty()) { if (errorMessage) { - *errorMessage = -#ifdef Q_OS_MAC - tr("No Server defined in the CodePaster preferences."); -#else - tr("No Server defined in the CodePaster options."); -#endif + *errorMessage = Utils::HostOsInfo::isMacHost() + ? tr("No Server defined in the CodePaster preferences.") + : tr("No Server defined in the CodePaster options."); } return false; } @@ -159,7 +157,7 @@ void CodePasterProtocol::pasteFinished() qWarning("Error pasting: %s", qPrintable(m_pasteReply->errorString())); } else { // Cut out the href-attribute - QString contents = QString::fromAscii(m_pasteReply->readAll()); + QString contents = QString::fromLatin1(m_pasteReply->readAll()); int hrefPos = contents.indexOf(QLatin1String("href=\"")); if (hrefPos != -1) { hrefPos += 6; @@ -190,7 +188,7 @@ void CodePasterProtocol::fetchFinished() if (error) { content = m_fetchReply->errorString(); } else { - content = QString::fromAscii(m_fetchReply->readAll()); // Codepaster does not support special characters. + content = QString::fromLatin1(m_fetchReply->readAll()); // Codepaster does not support special characters. if (debug) qDebug() << content; if (content.contains(QLatin1String("<B>No such paste!</B>"))) { @@ -210,7 +208,7 @@ void CodePasterProtocol::listFinished() Core::ICore::messageManager()->printToOutputPane(m_listReply->errorString(), true); } else { const QByteArray data = m_listReply->readAll(); - const QStringList lines = QString::fromAscii(data).split(QLatin1Char('\n')); + const QStringList lines = QString::fromLatin1(data).split(QLatin1Char('\n')); emit listDone(name(), lines); } m_listReply->deleteLater(); diff --git a/src/plugins/cpaster/cpaster.qbs b/src/plugins/cpaster/cpaster.qbs index 30208fe477..14cf63b416 100644 --- a/src/plugins/cpaster/cpaster.qbs +++ b/src/plugins/cpaster/cpaster.qbs @@ -10,13 +10,7 @@ QtcPlugin { Depends { name: "TextEditor" } Depends { name: "cpp" } - cpp.includePaths: [ - ".", - "../../shared/cpaster", - "..", - "../../libs", - buildDirectory - ] + cpp.includePaths: base.concat("../../shared/cpaster") files: [ "codepasterprotocol.cpp", @@ -54,7 +48,7 @@ QtcPlugin { "settingspage.h", "settingspage.ui", "urlopenprotocol.cpp", - "urlopenprotocol.h" + "urlopenprotocol.h", ] Group { @@ -63,7 +57,7 @@ QtcPlugin { "cgi.cpp", "cgi.h", "splitter.cpp", - "splitter.h" + "splitter.h", ] } } diff --git a/src/plugins/cpaster/frontend/argumentscollector.cpp b/src/plugins/cpaster/frontend/argumentscollector.cpp new file mode 100644 index 0000000000..5295268a59 --- /dev/null +++ b/src/plugins/cpaster/frontend/argumentscollector.cpp @@ -0,0 +1,134 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "argumentscollector.h" + +#include <QFileInfo> + +static QString pasteRequestString() { return QLatin1String("paste"); } +static QString listProtocolsRequestString() { return QLatin1String("list-protocols"); } +static QString helpRequestString() { return QLatin1String("help"); } +static QString pasteFileOptionString() { return QLatin1String("-file"); } +static QString pasteProtocolOptionString() { return QLatin1String("-protocol"); } + +namespace { +struct ArgumentErrorException +{ + ArgumentErrorException(const QString &error) : error(error) {} + const QString error; +}; +} + +ArgumentsCollector::ArgumentsCollector(const QStringList &availableProtocols) + : m_availableProtocols(availableProtocols) +{ +} + +bool ArgumentsCollector::collect(const QStringList &args) +{ + m_arguments = args; + m_errorString.clear(); + m_inputFilePath.clear(); + m_protocol.clear(); + try { + setRequest(); + if (m_requestType == RequestTypePaste) + setPasteOptions(); + return true; + } catch (const ArgumentErrorException &ex) { + m_errorString = ex.error; + return false; + } +} + +QString ArgumentsCollector::usageString() const +{ + QString usage = tr("Usage:"); + usage += QLatin1String("\n\t"); + usage += tr("%1 <request> [ <request options>]") + .arg(QFileInfo(QCoreApplication::applicationFilePath()).fileName()); + usage += QLatin1String("\n\t"); + usage += tr("Possible requests: \"%1\", \"%2\", \"%3\"") + .arg(pasteRequestString(), listProtocolsRequestString(), helpRequestString()); + usage += QLatin1String("\n\t"); + usage += tr("Possible options for request \"%1\": \"%2 <file>\" (default: stdin), " + "\"%3 <protocol>\"") + .arg(pasteRequestString(), pasteFileOptionString(), pasteProtocolOptionString()); + usage += QLatin1Char('\n'); + return usage; +} + +void ArgumentsCollector::setRequest() +{ + if (m_arguments.isEmpty()) + throw ArgumentErrorException(tr("No request given")); + const QString requestString = m_arguments.takeFirst(); + if (requestString == pasteRequestString()) + m_requestType = RequestTypePaste; + else if (requestString == listProtocolsRequestString()) + m_requestType = RequestTypeListProtocols; + else if (requestString == helpRequestString()) + m_requestType = RequestTypeHelp; + else + throw ArgumentErrorException(tr("Unknown request \"%1\"").arg(requestString)); +} + +void ArgumentsCollector::setPasteOptions() +{ + while (!m_arguments.isEmpty()) { + if (checkAndSetOption(pasteFileOptionString(), m_inputFilePath)) + continue; + if (checkAndSetOption(pasteProtocolOptionString(), m_protocol)) { + if (!m_availableProtocols.contains(m_protocol)) + throw ArgumentErrorException(tr("Unknown protocol \"%1\"").arg(m_protocol)); + continue; + } + throw ArgumentErrorException(tr("Invalid option \"%1\" for request \"%2\"") + .arg(m_arguments.first(), pasteRequestString())); + } + + if (m_protocol.isEmpty()) + throw ArgumentErrorException(tr("No protocol given")); +} + +bool ArgumentsCollector::checkAndSetOption(const QString &optionString, QString &optionValue) +{ + if (m_arguments.first() != optionString) + return false; + + if (!optionValue.isEmpty()) + throw ArgumentErrorException(tr("option \"%1\" was given twice").arg(optionString)); + m_arguments.removeFirst(); + if (m_arguments.isEmpty()) { + throw ArgumentErrorException(tr("Option \"%1\" requires an argument") + .arg(optionString)); + } + optionValue = m_arguments.takeFirst(); + return true; +} diff --git a/tests/auto/icheckbuild/ichecklib.h b/src/plugins/cpaster/frontend/argumentscollector.h index 439b9ba3f7..60f674467d 100644 --- a/tests/auto/icheckbuild/ichecklib.h +++ b/src/plugins/cpaster/frontend/argumentscollector.h @@ -1,4 +1,4 @@ -/**************************************************************************** +/************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal @@ -27,23 +27,40 @@ ** ****************************************************************************/ -#ifndef ICHECKLIB_H -#define ICHECKLIB_H +#ifndef ARGUMENTSCOLLECTOR_H +#define ARGUMENTSCOLLECTOR_H +#include <QCoreApplication> #include <QStringList> -#include "ichecklib_global.h" -namespace CPlusPlus{ - class ParseManager; -} -class ICHECKLIBSHARED_EXPORT ICheckLib { +class ArgumentsCollector +{ + Q_DECLARE_TR_FUNCTIONS(ArgumentsCollector) public: - ICheckLib(); - void ParseHeader(const QStringList& includePath, const QStringList& filelist); - bool check(const ICheckLib& ichecklib /*ICheckLib from interface header*/, QString outputfile); - QStringList getErrorMsg(); + ArgumentsCollector(const QStringList &availableProtocols); + bool collect(const QStringList &args); // Application is already removed. + + enum RequestType { RequestTypeHelp, RequestTypeListProtocols, RequestTypePaste }; + RequestType requestType() const { return m_requestType; } + + QString errorString() const { return m_errorString; } + QString usageString() const; + + // These are valid <=> requestType() == RequestTypePaste + QString inputFilePath() const { return m_inputFilePath; } + QString protocol() const { return m_protocol; } + private: - CPlusPlus::ParseManager* pParseManager; + void setRequest(); + void setPasteOptions(); + bool checkAndSetOption(const QString &optionString, QString &optionValue); + + const QStringList m_availableProtocols; + QStringList m_arguments; + RequestType m_requestType; + QString m_inputFilePath; + QString m_protocol; + QString m_errorString; }; -#endif // ICHECKLIB_H +#endif // ARGUMENTSCOLLECTOR_H diff --git a/src/plugins/cpaster/frontend/frontend.pro b/src/plugins/cpaster/frontend/frontend.pro new file mode 100644 index 0000000000..e38780c4da --- /dev/null +++ b/src/plugins/cpaster/frontend/frontend.pro @@ -0,0 +1,30 @@ +TEMPLATE = app +TARGET=cpaster + +include(../../../../qtcreator.pri) +include(../../../rpath.pri) +include(../../../plugins/coreplugin/coreplugin.pri) + +CONFIG += console +QT += network + +LIBS *= -L$$IDE_PLUGIN_PATH/QtProject +QMAKE_RPATHDIR *= $$IDE_PLUGIN_PATH/QtProject + +DESTDIR=$$IDE_APP_PATH + +HEADERS = ../protocol.h \ + ../cpasterconstants.h \ + ../pastebindotcomprotocol.h \ + ../pastebindotcaprotocol.h \ + ../kdepasteprotocol.h \ + ../urlopenprotocol.h \ + argumentscollector.h + +SOURCES += ../protocol.cpp \ + ../pastebindotcomprotocol.cpp \ + ../pastebindotcaprotocol.cpp \ + ../kdepasteprotocol.cpp \ + ../urlopenprotocol.cpp \ + argumentscollector.cpp \ + main.cpp diff --git a/src/plugins/cpaster/frontend/frontend.qbs b/src/plugins/cpaster/frontend/frontend.qbs new file mode 100644 index 0000000000..100bbbbe5d --- /dev/null +++ b/src/plugins/cpaster/frontend/frontend.qbs @@ -0,0 +1,30 @@ +import qbs.base 1.0 +import "../../../tools/QtcTool.qbs" as QtcTool + +QtcTool { + name: "cpaster" + + Depends { name: "cpp" } + Depends { + name: "Qt" + submodules: "core", "gui", "network" + } + Depends { name: "Core" } + + cpp.includePaths: ["../../"] + cpp.rpaths: [ + "$ORIGIN/../lib/qtcreator", + "$ORIGIN/../lib/qtcreator/plugins", + "$ORIGIN/../lib/qtcreator/plugins/QtProject" + ] + + files: [ "main.cpp", + "argumentscollector.h", "argumentscollector.cpp", + "../cpasterconstants.h", + "../kdepasteprotocol.h", "../kdepasteprotocol.cpp", + "../pastebindotcaprotocol.h", "../pastebindotcaprotocol.cpp", + "../pastebindotcomprotocol.h", "../pastebindotcomprotocol.cpp", + "../protocol.h", "../protocol.cpp", + "../urlopenprotocol.h", "../urlopenprotocol.cpp", + ] +} diff --git a/src/plugins/cpaster/frontend/main.cpp b/src/plugins/cpaster/frontend/main.cpp new file mode 100644 index 0000000000..e79dab4378 --- /dev/null +++ b/src/plugins/cpaster/frontend/main.cpp @@ -0,0 +1,127 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "argumentscollector.h" +#include "../kdepasteprotocol.h" +#include "../pastebindotcaprotocol.h" +#include "../pastebindotcomprotocol.h" + +#include <QFile> +#include <QObject> +#include <QTimer> + +#include <cstdio> +#include <cstdlib> +#include <iostream> + +using namespace CodePaster; + +class PasteReceiver : public QObject +{ + Q_OBJECT +public: + PasteReceiver(const QString &protocol, const QString &filePath) : m_filePath(filePath) + { + const QSharedPointer<NetworkAccessManagerProxy> accessMgr(new NetworkAccessManagerProxy); + if (protocol == KdePasteProtocol::protocolName().toLower()) + m_protocol.reset(new KdePasteProtocol(accessMgr)); + else if (protocol == PasteBinDotCaProtocol::protocolName().toLower()) + m_protocol.reset(new PasteBinDotCaProtocol(accessMgr)); + else if (protocol == PasteBinDotComProtocol::protocolName().toLower()) + m_protocol.reset(new PasteBinDotComProtocol(accessMgr)); + else + qFatal("Internal error: Invalid protocol."); + } + +public slots: + void paste() + { + QFile file(m_filePath); + const bool success = m_filePath.isEmpty() + ? file.open(stdin, QIODevice::ReadOnly) : file.open(QIODevice::ReadOnly); + if (!success) { + std::cerr << "Error: Failed to open file to paste from." << std::endl; + qApp->exit(EXIT_FAILURE); + return; + } + const QString content = QString::fromLocal8Bit(file.readAll()); + if (content.isEmpty()) { + std::cerr << "Empty input, aborting." << std::endl; + qApp->exit(EXIT_FAILURE); + return; + } + connect(m_protocol.data(), SIGNAL(pasteDone(QString)), SLOT(handlePasteDone(QString))); + m_protocol->paste(content); + } + +private slots: + void handlePasteDone(const QString &link) + { + std::cout << qPrintable(link) << std::endl; + qApp->quit(); + } + +private: + const QString m_filePath; + QScopedPointer<Protocol> m_protocol; +}; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + const QStringList protocols = QStringList() << KdePasteProtocol::protocolName().toLower() + << PasteBinDotCaProtocol::protocolName().toLower() + << PasteBinDotComProtocol::protocolName().toLower(); + ArgumentsCollector argsCollector(protocols); + QStringList arguments = QCoreApplication::arguments(); + arguments.removeFirst(); + if (!argsCollector.collect(arguments)) { + std::cerr << "Error: " << qPrintable(argsCollector.errorString()) << '.' << std::endl + << qPrintable(argsCollector.usageString()) << std::endl; + return EXIT_FAILURE; + } + + switch (argsCollector.requestType()) { + case ArgumentsCollector::RequestTypeHelp: + std::cout << qPrintable(argsCollector.usageString()) << std::endl; + return EXIT_SUCCESS; + case ArgumentsCollector::RequestTypeListProtocols: + foreach (const QString &protocol, protocols) + std::cout << qPrintable(protocol) << std::endl; + return EXIT_SUCCESS; + case ArgumentsCollector::RequestTypePaste: { + PasteReceiver pr(argsCollector.protocol(), argsCollector.inputFilePath()); + QTimer::singleShot(0, &pr, SLOT(paste())); + return app.exec(); + } + } +} + +#include "main.moc" diff --git a/src/plugins/cpaster/pastebindotcaprotocol.cpp b/src/plugins/cpaster/pastebindotcaprotocol.cpp index b01c5135d0..e036c0b39a 100644 --- a/src/plugins/cpaster/pastebindotcaprotocol.cpp +++ b/src/plugins/cpaster/pastebindotcaprotocol.cpp @@ -118,7 +118,7 @@ void PasteBinDotCaProtocol::pasteFinished() } else { /// returns ""SUCCESS:[id]"" const QByteArray data = m_pasteReply->readAll(); - const QString link = QString::fromLatin1(urlC) + QString::fromAscii(data).remove(QLatin1String("SUCCESS:")); + const QString link = QString::fromLatin1(urlC) + QString::fromLatin1(data).remove(QLatin1String("SUCCESS:")); emit pasteDone(link); } m_pasteReply->deleteLater(); diff --git a/src/plugins/cpaster/pastebindotcaprotocol.h b/src/plugins/cpaster/pastebindotcaprotocol.h index 8ace2de13c..7a2642f621 100644 --- a/src/plugins/cpaster/pastebindotcaprotocol.h +++ b/src/plugins/cpaster/pastebindotcaprotocol.h @@ -38,7 +38,9 @@ class PasteBinDotCaProtocol : public NetworkProtocol Q_OBJECT public: explicit PasteBinDotCaProtocol(const NetworkAccessManagerProxyPtr &nw); - QString name() const { return QLatin1String("Pastebin.Ca"); } + + static QString protocolName() { return QLatin1String("Pastebin.Ca"); } + QString name() const { return protocolName(); } virtual bool hasSettings() const { return false; } virtual unsigned capabilities() const; diff --git a/src/plugins/cpaster/pastebindotcomprotocol.cpp b/src/plugins/cpaster/pastebindotcomprotocol.cpp index 4cbba323b7..dade4e201b 100644 --- a/src/plugins/cpaster/pastebindotcomprotocol.cpp +++ b/src/plugins/cpaster/pastebindotcomprotocol.cpp @@ -133,7 +133,7 @@ void PasteBinDotComProtocol::pasteFinished() if (m_pasteReply->error()) { qWarning("Pastebin.com protocol error: %s", qPrintable(m_pasteReply->errorString())); } else { - emit pasteDone(QString::fromAscii(m_pasteReply->readAll())); + emit pasteDone(QString::fromLatin1(m_pasteReply->readAll())); } m_pasteReply->deleteLater(); @@ -170,7 +170,7 @@ void PasteBinDotComProtocol::fetchFinished() qDebug() << "fetchFinished: error" << m_fetchId << content; } else { title = QString::fromLatin1("Pastebin.com: %1").arg(m_fetchId); - content = QString::fromAscii(m_fetchReply->readAll()); + content = QString::fromLatin1(m_fetchReply->readAll()); // Cut out from '<pre>' formatting const int preEnd = content.lastIndexOf(QLatin1String("</pre>")); if (preEnd != -1) diff --git a/src/plugins/cpaster/pasteselectdialog.cpp b/src/plugins/cpaster/pasteselectdialog.cpp index 13c9488c6a..d6774d71b3 100644 --- a/src/plugins/cpaster/pasteselectdialog.cpp +++ b/src/plugins/cpaster/pasteselectdialog.cpp @@ -30,6 +30,7 @@ #include "pasteselectdialog.h" #include "protocol.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDebug> @@ -55,9 +56,8 @@ PasteSelectDialog::PasteSelectDialog(const QList<Protocol*> &protocols, connect(m_refreshButton, SIGNAL(clicked()), this, SLOT(list())); m_ui.listWidget->setSelectionMode(QAbstractItemView::SingleSelection); -#ifndef Q_OS_MACX - m_ui.listWidget->setFrameStyle(QFrame::NoFrame); -#endif // Q_OS_MACX + if (!Utils::HostOsInfo::isMacHost()) + m_ui.listWidget->setFrameStyle(QFrame::NoFrame); // Proportional formatting of columns for CodePaster QFont listFont = m_ui.listWidget->font(); listFont.setFamily(QLatin1String("Courier")); diff --git a/src/plugins/cpaster/settings.cpp b/src/plugins/cpaster/settings.cpp index 19f5ec8006..8279a08247 100644 --- a/src/plugins/cpaster/settings.cpp +++ b/src/plugins/cpaster/settings.cpp @@ -30,6 +30,8 @@ #include "settings.h" #include "pastebindotcomprotocol.h" +#include <utils/environment.h> + #include <QVariant> #include <QSettings> @@ -64,11 +66,7 @@ void Settings::toSettings(QSettings *settings) const void Settings::fromSettings(const QSettings *settings) { const QString rootKey = QLatin1String(groupC) + QLatin1Char('/'); -#ifdef Q_OS_WIN - const QString defaultUser = QString::fromLocal8Bit(qgetenv("USERNAME")); -#else - const QString defaultUser = QString::fromLocal8Bit(qgetenv("USER")); -#endif + const QString defaultUser = Utils::Environment::systemEnvironment().userName(); username = settings->value(rootKey + QLatin1String(userNameKeyC), defaultUser).toString(); protocol = settings->value(rootKey + QLatin1String(defaultProtocolKeyC), PasteBinDotComProtocol::protocolName()).toString(); copyToClipboard = settings->value(rootKey + QLatin1String(copyToClipboardKeyC), true).toBool(); diff --git a/src/plugins/cppeditor/cppcompleteswitch.cpp b/src/plugins/cppeditor/cppcompleteswitch.cpp index 554e3faba7..687538c457 100644 --- a/src/plugins/cppeditor/cppcompleteswitch.cpp +++ b/src/plugins/cppeditor/cppcompleteswitch.cpp @@ -46,6 +46,7 @@ using namespace CPlusPlus; using namespace CppEditor; using namespace CppEditor::Internal; using namespace CppTools; +using namespace TextEditor; using namespace Utils; namespace { @@ -79,7 +80,7 @@ public: scope); if (!candidates .isEmpty() && candidates.first().declaration()) { Symbol *decl = candidates.first().declaration(); - values << prettyPrint(LookupContext::fullyQualifiedName(decl)); + values << prettyPrint.prettyName(LookupContext::fullyQualifiedName(decl)); } } return true; @@ -112,10 +113,11 @@ public: "Complete Switch Statement")); } - - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, - const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; int start = currentFile->endOf(compoundStatement->lbrace_token); changes.insert(start, QLatin1String("\ncase ") @@ -130,8 +132,9 @@ public: QStringList values; }; -static Enum *findEnum(const QList<LookupItem> &results, - const LookupContext &ctxt) +} // end of anonymous namespace + +static Enum *findEnum(const QList<LookupItem> &results, const LookupContext &ctxt) { foreach (const LookupItem &result, results) { const FullySpecifiedType fst = result.type(); @@ -153,8 +156,7 @@ static Enum *findEnum(const QList<LookupItem> &results, return 0; } -static Enum *conditionEnum(const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface, - SwitchStatementAST *statement) +static Enum *conditionEnum(const CppQuickFixInterface &interface, SwitchStatementAST *statement) { Block *block = statement->symbol; Scope *scope = interface->semanticInfo().doc->scopeAt(block->line(), block->column()); @@ -167,15 +169,12 @@ static Enum *conditionEnum(const QSharedPointer<const CppEditor::Internal::CppQu return findEnum(results, typeOfExpression.context()); } -} // end of anonymous namespace - -QList<CppQuickFixOperation::Ptr> CompleteSwitchCaseStatement::match( - const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface) +void CompleteSwitchCaseStatement::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); if (path.isEmpty()) - return noResult(); // nothing to do + return; // look for switch statement for (int depth = path.size() - 1; depth >= 0; --depth) { @@ -183,10 +182,10 @@ QList<CppQuickFixOperation::Ptr> CompleteSwitchCaseStatement::match( SwitchStatementAST *switchStatement = ast->asSwitchStatement(); if (switchStatement) { if (!interface->isCursorOn(switchStatement->switch_token) || !switchStatement->statement) - return noResult(); + return; CompoundStatementAST *compoundStatement = switchStatement->statement->asCompoundStatement(); if (!compoundStatement) // we ignore pathologic case "switch (t) case A: ;" - return noResult(); + return; // look if the condition's type is an enum if (Enum *e = conditionEnum(interface, switchStatement)) { // check the possible enum values @@ -194,7 +193,7 @@ QList<CppQuickFixOperation::Ptr> CompleteSwitchCaseStatement::match( Overview prettyPrint; for (unsigned i = 0; i < e->memberCount(); ++i) { if (Declaration *decl = e->memberAt(i)->asDeclaration()) { - values << prettyPrint(LookupContext::fullyQualifiedName(decl)); + values << prettyPrint.prettyName(LookupContext::fullyQualifiedName(decl)); } } // Get the used values @@ -205,15 +204,12 @@ QList<CppQuickFixOperation::Ptr> CompleteSwitchCaseStatement::match( // save the values that would be added foreach (const QString &usedValue, usedValues) values.removeAll(usedValue); - if (values.isEmpty()) - return noResult(); - else - return singleResult(new Operation(interface, depth, compoundStatement, values)); + if (!values.isEmpty()) + result.append(CppQuickFixOperation::Ptr(new Operation(interface, depth, compoundStatement, values))); + return; } - return noResult(); + return; } } - - return noResult(); } diff --git a/src/plugins/cppeditor/cppcompleteswitch.h b/src/plugins/cppeditor/cppcompleteswitch.h index 001e52760b..5158987989 100644 --- a/src/plugins/cppeditor/cppcompleteswitch.h +++ b/src/plugins/cppeditor/cppcompleteswitch.h @@ -32,8 +32,6 @@ #include "cppquickfix.h" -#include <CPlusPlusForwardDeclarations.h> - namespace CppEditor { namespace Internal { @@ -43,8 +41,7 @@ namespace Internal { class CompleteSwitchCaseStatement: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match( - const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface); + void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); }; } // namespace Internal diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 5dd4308da0..399b108a25 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1743,7 +1743,7 @@ Core::IEditor *CPPEditor::duplicate(QWidget *parent) Core::Id CPPEditor::id() const { - return CppEditor::Constants::CPPEDITOR_ID; + return Core::Id(CppEditor::Constants::CPPEDITOR_ID); } bool CPPEditor::open(QString *errorString, const QString &fileName, const QString &realFileName) @@ -2122,7 +2122,7 @@ void SemanticHighlighter::run() SemanticInfo SemanticHighlighter::semanticInfo(const Source &source) { SemanticInfo semanticInfo; - semanticInfo.revision = source.revision; + semanticInfo.revision = m_lastSemanticInfo.revision; semanticInfo.forced = source.force; m_mutex.lock(); @@ -2162,6 +2162,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source) DeclarationAST *currentFunctionDefinition = functionDefinitionUnderCursor(ast, source.line, source.column); const LocalSymbols useTable(semanticInfo.doc, currentFunctionDefinition); + semanticInfo.revision = source.revision; semanticInfo.localUses = useTable.uses; semanticInfo.hasQ = useTable.hasQ; semanticInfo.hasD = useTable.hasD; diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 8b9295c940..8cd892a574 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -12,16 +12,11 @@ QtcPlugin { Depends { name: "TextEditor" } Depends { name: "ProjectExplorer" } Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - "../../libs/3rdparty", - buildDirectory - ] + + cpp.includePaths: base.concat("../../libs/3rdparty") files: [ "CppEditor.mimetypes.xml", - "cppeditor.qrc", "cppautocompleter.cpp", "cppautocompleter.h", "cppclasswizard.cpp", @@ -30,6 +25,7 @@ QtcPlugin { "cppcompleteswitch.h", "cppeditor.cpp", "cppeditor.h", + "cppeditor.qrc", "cppeditor_global.h", "cppeditorconstants.h", "cppeditorenums.h", @@ -59,7 +55,6 @@ QtcPlugin { "cppsnippetprovider.cpp", "cppsnippetprovider.h", "cpptypehierarchy.cpp", - "cpptypehierarchy.h" + "cpptypehierarchy.h", ] } - diff --git a/src/plugins/cppeditor/cppelementevaluator.cpp b/src/plugins/cppeditor/cppelementevaluator.cpp index d24d4a15e9..c7fc227a52 100644 --- a/src/plugins/cppeditor/cppelementevaluator.cpp +++ b/src/plugins/cppeditor/cppelementevaluator.cpp @@ -237,171 +237,82 @@ void CppEditor::Internal::CppElementEvaluator::clear() } // CppElement -CppElement::CppElement() : m_helpCategory(TextEditor::HelpItem::Unknown) +CppElement::CppElement() : helpCategory(TextEditor::HelpItem::Unknown) {} CppElement::~CppElement() {} -void CppElement::setHelpCategory(const TextEditor::HelpItem::Category &cat) -{ m_helpCategory = cat; } - -const TextEditor::HelpItem::Category &CppElement::helpCategory() const -{ return m_helpCategory; } - -void CppElement::setHelpIdCandidates(const QStringList &candidates) -{ m_helpIdCandidates = candidates; } - -void CppElement::addHelpIdCandidate(const QString &candidate) -{ m_helpIdCandidates.append(candidate); } - -const QStringList &CppElement::helpIdCandidates() const -{ return m_helpIdCandidates; } - -void CppElement::setHelpMark(const QString &mark) -{ m_helpMark = mark; } - -const QString &CppElement::helpMark() const -{ return m_helpMark; } - -void CppElement::setLink(const CPPEditorWidget::Link &link) -{ m_link = link; } - -const CPPEditorWidget::Link &CppElement::link() const -{ return m_link; } - -void CppElement::setTooltip(const QString &tooltip) -{ m_tooltip = tooltip; } - -const QString &CppElement::tooltip() const -{ return m_tooltip; } - - // Unknown -Unknown::Unknown(const QString &type) : CppElement(), m_type(type) +Unknown::Unknown(const QString &type) : type(type) { - setTooltip(m_type); + tooltip = type; } -Unknown::~Unknown() -{} - -const QString &Unknown::type() const -{ return m_type; } // CppInclude -CppInclude::~CppInclude() -{} CppInclude::CppInclude(const Document::Include &includeFile) : - CppElement(), - m_path(QDir::toNativeSeparators(includeFile.fileName())), - m_fileName(QFileInfo(includeFile.fileName()).fileName()) + path(QDir::toNativeSeparators(includeFile.fileName())), + fileName(QFileInfo(includeFile.fileName()).fileName()) { - setHelpCategory(TextEditor::HelpItem::Brief); - setHelpIdCandidates(QStringList(m_fileName)); - setHelpMark(m_fileName); - setLink(CPPEditorWidget::Link(m_path)); - setTooltip(m_path); + helpCategory = TextEditor::HelpItem::Brief; + helpIdCandidates = QStringList(fileName); + helpMark = fileName; + link = CPPEditorWidget::Link(path); + tooltip = path; } -const QString &CppInclude::path() const -{ return m_path; } - -const QString &CppInclude::fileName() const -{ return m_fileName; } - // CppMacro -CppMacro::CppMacro(const Macro ¯o) : CppElement() +CppMacro::CppMacro(const Macro ¯o) { - setHelpCategory(TextEditor::HelpItem::Macro); + helpCategory = TextEditor::HelpItem::Macro; const QString macroName = QLatin1String(macro.name()); - setHelpIdCandidates(QStringList(macroName)); - setHelpMark(macroName); - setLink(CPPEditorWidget::Link(macro.fileName(), macro.line())); - setTooltip(macro.toStringWithLineBreaks()); + helpIdCandidates = QStringList(macroName); + helpMark = macroName; + link = CPPEditorWidget::Link(macro.fileName(), macro.line()); + tooltip = macro.toStringWithLineBreaks(); } -CppMacro::~CppMacro() -{} - // CppDeclarableElement -CppDeclarableElement::CppDeclarableElement() -{} CppDeclarableElement::CppDeclarableElement(Symbol *declaration) : CppElement() { - m_icon = Icons().iconForSymbol(declaration); + icon = Icons().iconForSymbol(declaration); Overview overview; - overview.setShowArgumentNames(true); - overview.setShowReturnTypes(true); - m_name = overview.prettyName(declaration->name()); + overview.showArgumentNames = true; + overview.showReturnTypes = true; + name = overview.prettyName(declaration->name()); if (declaration->enclosingScope()->isClass() || declaration->enclosingScope()->isNamespace() || declaration->enclosingScope()->isEnum()) { - m_qualifiedName = overview.prettyName(LookupContext::fullyQualifiedName(declaration)); - setHelpIdCandidates(stripName(m_qualifiedName)); + qualifiedName = overview.prettyName(LookupContext::fullyQualifiedName(declaration)); + helpIdCandidates = stripName(qualifiedName); } else { - m_qualifiedName = m_name; - setHelpIdCandidates(QStringList(m_name)); + qualifiedName = name; + helpIdCandidates.append(name); } - setTooltip(overview.prettyType(declaration->type(), m_qualifiedName)); - setLink(CPPEditorWidget::linkToSymbol(declaration)); - setHelpMark(m_name); + tooltip = overview.prettyType(declaration->type(), qualifiedName); + link = CPPEditorWidget::linkToSymbol(declaration); + helpMark = name; } -CppDeclarableElement::~CppDeclarableElement() -{} - -void CppDeclarableElement::setName(const QString &name) -{ m_name = name; } - -const QString &CppDeclarableElement::name() const -{ return m_name; } - -void CppDeclarableElement::setQualifiedName(const QString &name) -{ m_qualifiedName = name; } - -const QString &CppDeclarableElement::qualifiedName() const -{ return m_qualifiedName; } - -void CppDeclarableElement::setType(const QString &type) -{ m_type = type; } - -const QString &CppDeclarableElement::type() const -{ return m_type; } - -void CppDeclarableElement::setIcon(const QIcon &icon) -{ m_icon = icon; } - -const QIcon &CppDeclarableElement::icon() const -{ return m_icon; } - // CppNamespace CppNamespace::CppNamespace(Symbol *declaration) : CppDeclarableElement(declaration) { - setHelpCategory(TextEditor::HelpItem::ClassOrNamespace); - setTooltip(qualifiedName()); + helpCategory = TextEditor::HelpItem::ClassOrNamespace; + tooltip = qualifiedName; } -CppNamespace::~CppNamespace() -{} - // CppClass -CppClass::CppClass() -{} - CppClass::CppClass(Symbol *declaration) : CppDeclarableElement(declaration) { - setHelpCategory(TextEditor::HelpItem::ClassOrNamespace); - setTooltip(qualifiedName()); + helpCategory = TextEditor::HelpItem::ClassOrNamespace; + tooltip = qualifiedName; } -CppClass::~CppClass() -{} - void CppClass::lookupBases(Symbol *declaration, const CPlusPlus::LookupContext &context) { typedef QPair<ClassOrNamespace *, CppClass *> Data; @@ -424,8 +335,8 @@ void CppClass::lookupBases(Symbol *declaration, const CPlusPlus::LookupContext & !visited.contains(clazz)) { CppClass baseCppClass(symbol); CppClass *cppClass = current.second; - cppClass->m_bases.append(baseCppClass); - q.enqueue(qMakePair(clazz, &cppClass->m_bases.last())); + cppClass->bases.append(baseCppClass); + q.enqueue(qMakePair(clazz, &cppClass->bases.last())); } } } @@ -447,59 +358,45 @@ void CppClass::lookupDerived(CPlusPlus::Symbol *declaration, const CPlusPlus::Sn CppClass *clazz = current.first; const TypeHierarchy &classHierarchy = current.second; foreach (const TypeHierarchy &derivedHierarchy, classHierarchy.hierarchy()) { - clazz->m_derived.append(CppClass(derivedHierarchy.symbol())); - q.enqueue(qMakePair(&clazz->m_derived.last(), derivedHierarchy)); + clazz->derived.append(CppClass(derivedHierarchy.symbol())); + q.enqueue(qMakePair(&clazz->derived.last(), derivedHierarchy)); } } } -const QList<CppClass> &CppClass::bases() const -{ return m_bases; } - -const QList<CppClass> &CppClass::derived() const -{ return m_derived; } - // CppFunction -CppFunction::CppFunction(Symbol *declaration) : CppDeclarableElement(declaration) +CppFunction::CppFunction(Symbol *declaration) + : CppDeclarableElement(declaration) { - setHelpCategory(TextEditor::HelpItem::Function); + helpCategory = TextEditor::HelpItem::Function; const FullySpecifiedType &type = declaration->type(); // Functions marks can be found either by the main overload or signature based // (with no argument names and no return). Help ids have no signature at all. Overview overview; - overview.setShowDefaultArguments(false); - setHelpMark(overview.prettyType(type, name())); + overview.showDefaultArguments = false; + helpMark = overview.prettyType(type, name); - overview.setShowFunctionSignatures(false); - addHelpIdCandidate(overview.prettyName(declaration->name())); + overview.showFunctionSignatures = false; + helpIdCandidates.append(overview.prettyName(declaration->name())); } -CppFunction::~CppFunction() -{} - // CppEnum CppEnum::CppEnum(Enum *declaration) : CppDeclarableElement(declaration) { - setHelpCategory(TextEditor::HelpItem::Enum); - setTooltip(qualifiedName()); + helpCategory = TextEditor::HelpItem::Enum; + tooltip = qualifiedName; } -CppEnum::~CppEnum() -{} - // CppTypedef CppTypedef::CppTypedef(Symbol *declaration) : CppDeclarableElement(declaration) { - setHelpCategory(TextEditor::HelpItem::Typedef); - setTooltip(Overview().prettyType(declaration->type(), qualifiedName())); + helpCategory = TextEditor::HelpItem::Typedef; + tooltip = Overview().prettyType(declaration->type(), qualifiedName); } -CppTypedef::~CppTypedef() -{} - // CppVariable CppVariable::CppVariable(Symbol *declaration, const LookupContext &context, Scope *scope) : CppDeclarableElement(declaration) @@ -527,12 +424,12 @@ CppVariable::CppVariable(Symbol *declaration, const LookupContext &context, Scop const QString &name = overview.prettyName(LookupContext::fullyQualifiedName(symbol)); if (!name.isEmpty()) { - setTooltip(name); - setHelpCategory(TextEditor::HelpItem::ClassOrNamespace); + tooltip = name; + helpCategory = TextEditor::HelpItem::ClassOrNamespace; const QStringList &allNames = stripName(name); if (!allNames.isEmpty()) { - setHelpMark(allNames.last()); - setHelpIdCandidates(allNames); + helpMark = allNames.last(); + helpIdCandidates = allNames; } } } @@ -540,13 +437,10 @@ CppVariable::CppVariable(Symbol *declaration, const LookupContext &context, Scop } } -CppVariable::~CppVariable() -{} - CppEnumerator::CppEnumerator(CPlusPlus::EnumeratorDeclaration *declaration) : CppDeclarableElement(declaration) { - setHelpCategory(TextEditor::HelpItem::Enum); + helpCategory = TextEditor::HelpItem::Enum; Overview overview; @@ -554,19 +448,14 @@ CppEnumerator::CppEnumerator(CPlusPlus::EnumeratorDeclaration *declaration) const QString enumName = overview.prettyName(LookupContext::fullyQualifiedName(enumSymbol)); const QString enumeratorName = overview.prettyName(declaration->name()); QString enumeratorValue; - if (const StringLiteral *value = declaration->constantValue()) { + if (const StringLiteral *value = declaration->constantValue()) enumeratorValue = QString::fromUtf8(value->chars(), value->size()); - } - setHelpMark(overview.prettyName(enumSymbol->name())); + helpMark = overview.prettyName(enumSymbol->name()); - QString tooltip = enumeratorName; + tooltip = enumeratorName; if (!enumName.isEmpty()) tooltip.prepend(enumName + QLatin1Char(' ')); if (!enumeratorValue.isEmpty()) tooltip.append(QLatin1String(" = ") + enumeratorValue); - setTooltip(tooltip); } - -CppEnumerator::~CppEnumerator() -{} diff --git a/src/plugins/cppeditor/cppelementevaluator.h b/src/plugins/cppeditor/cppelementevaluator.h index 3f7918f6ee..e2a91d64f3 100644 --- a/src/plugins/cppeditor/cppelementevaluator.h +++ b/src/plugins/cppeditor/cppelementevaluator.h @@ -94,96 +94,60 @@ private: class CppElement { -public: - virtual ~CppElement(); - - const TextEditor::HelpItem::Category &helpCategory() const; - const QStringList &helpIdCandidates() const; - const QString &helpMark() const; - const CPPEditorWidget::Link &link() const; - const QString &tooltip() const; - protected: CppElement(); - void setHelpCategory(const TextEditor::HelpItem::Category &category); - void setLink(const CPPEditorWidget::Link &link); - void setTooltip(const QString &tooltip); - void setHelpIdCandidates(const QStringList &candidates); - void addHelpIdCandidate(const QString &candidate); - void setHelpMark(const QString &mark); +public: + virtual ~CppElement(); -private: - TextEditor::HelpItem::Category m_helpCategory; - QStringList m_helpIdCandidates; - QString m_helpMark; - CPPEditorWidget::Link m_link; - QString m_tooltip; + TextEditor::HelpItem::Category helpCategory; + QStringList helpIdCandidates; + QString helpMark; + CPPEditorWidget::Link link; + QString tooltip; }; class Unknown : public CppElement { public: explicit Unknown(const QString &type); - virtual ~Unknown(); - - const QString &type() const; -private: - QString m_type; +public: + QString type; }; class CppInclude : public CppElement { public: explicit CppInclude(const CPlusPlus::Document::Include &includeFile); - virtual ~CppInclude(); - - const QString &path() const; - const QString &fileName() const; -private: - QString m_path; - QString m_fileName; +public: + QString path; + QString fileName; }; class CppMacro : public CppElement { public: explicit CppMacro(const CPlusPlus::Macro ¯o); - virtual ~CppMacro(); }; class CppDeclarableElement : public CppElement { public: - CppDeclarableElement(); explicit CppDeclarableElement(CPlusPlus::Symbol *declaration); - virtual ~CppDeclarableElement(); - - const QString &name() const; - const QString &qualifiedName() const; - const QString &type() const; - const QIcon &icon() const; - -protected: - void setName(const QString &name); - void setQualifiedName(const QString &name); - void setType(const QString &type); - void setIcon(const QIcon &icon); -private: - QString m_name; - QString m_qualifiedName; - QString m_type; - QIcon m_icon; +public: + QString name; + QString qualifiedName; + QString type; + QIcon icon; }; class CppNamespace : public CppDeclarableElement { public: explicit CppNamespace(CPlusPlus::Symbol *declaration); - virtual ~CppNamespace(); }; class CppClass : public CppDeclarableElement @@ -191,38 +155,31 @@ class CppClass : public CppDeclarableElement public: CppClass(); explicit CppClass(CPlusPlus::Symbol *declaration); - virtual ~CppClass(); void lookupBases(CPlusPlus::Symbol *declaration, const CPlusPlus::LookupContext &context); void lookupDerived(CPlusPlus::Symbol *declaration, const CPlusPlus::Snapshot &snapshot); - const QList<CppClass> &bases() const; - const QList<CppClass> &derived() const; - -private: - QList<CppClass> m_bases; - QList<CppClass> m_derived; +public: + QList<CppClass> bases; + QList<CppClass> derived; }; class CppFunction : public CppDeclarableElement { public: explicit CppFunction(CPlusPlus::Symbol *declaration); - virtual ~CppFunction(); }; class CppEnum : public CppDeclarableElement { public: explicit CppEnum(CPlusPlus::Enum *declaration); - virtual ~CppEnum(); }; class CppTypedef : public CppDeclarableElement { public: explicit CppTypedef(CPlusPlus::Symbol *declaration); - virtual ~CppTypedef(); }; class CppVariable : public CppDeclarableElement @@ -231,14 +188,12 @@ public: CppVariable(CPlusPlus::Symbol *declaration, const CPlusPlus::LookupContext &context, CPlusPlus::Scope *scope); - virtual ~CppVariable(); }; class CppEnumerator : public CppDeclarableElement { public: explicit CppEnumerator(CPlusPlus::EnumeratorDeclaration *declaration); - virtual ~CppEnumerator(); }; } // namespace Internal diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp index 326cb9b812..b55f6a3c7a 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp @@ -59,6 +59,7 @@ using namespace CPlusPlus; using namespace CppEditor; using namespace CppEditor::Internal; using namespace CppTools; +using namespace TextEditor; FunctionDeclDefLinkFinder::FunctionDeclDefLinkFinder(QObject *parent) : QObject(parent) @@ -573,7 +574,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ QString newDeclText = linkSelection.selectedText(); for (int i = 0; i < newDeclText.size(); ++i) { - if (newDeclText.at(i).toAscii() == 0) + if (newDeclText.at(i).toLatin1() == 0) newDeclText[i] = QLatin1Char('\n'); } newDeclText.append(QLatin1String("{}")); @@ -596,15 +597,15 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ return changes; Overview overview; - overview.setShowReturnTypes(true); - overview.setShowTemplateParameters(true); - overview.setShowArgumentNames(true); - overview.setShowFunctionSignatures(true); + overview.showReturnTypes = true; + overview.showTemplateParameters = true; + overview.showArgumentNames = true; + overview.showFunctionSignatures = true; // abort if the name of the newly parsed function is not the expected one DeclaratorIdAST *newDeclId = getDeclaratorId(newDef->declarator); if (!newDeclId || !newDeclId->name || !newDeclId->name->name - || overview(newDeclId->name->name) != nameInitial) { + || overview.prettyName(newDeclId->name->name) != nameInitial) { return changes; } @@ -650,7 +651,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ if (!newFunction->returnType().isEqualTo(sourceFunction->returnType()) && !newFunction->returnType().isEqualTo(targetFunction->returnType())) { FullySpecifiedType type = rewriteType(newFunction->returnType(), &env, control); - const QString replacement = overview(type, targetFunction->name()); + const QString replacement = overview.prettyType(type, targetFunction->name()); changes.replace(returnTypeStart, targetFile->startOf(targetFunctionDeclarator->lparen_token), replacement); @@ -706,19 +707,19 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ QMultiHash<QString, int> sourceParamNameToIndex; for (int i = 0; i < existingParamCount; ++i) { Symbol *sourceParam = sourceFunction->argumentAt(i); - sourceParamNameToIndex.insert(overview(sourceParam->name()), i); + sourceParamNameToIndex.insert(overview.prettyName(sourceParam->name()), i); } QMultiHash<QString, int> newParamNameToIndex; for (int i = 0; i < newParamCount; ++i) { Symbol *newParam = newFunction->argumentAt(i); - newParamNameToIndex.insert(overview(newParam->name()), i); + newParamNameToIndex.insert(overview.prettyName(newParam->name()), i); } // name-based binds (possibly disambiguated by type) for (int sourceParamIndex = 0; sourceParamIndex < existingParamCount; ++sourceParamIndex) { Symbol *sourceParam = sourceFunction->argumentAt(sourceParamIndex); - const QString &name = overview(sourceParam->name()); + const QString &name = overview.prettyName(sourceParam->name()); QList<int> newParams = newParamNameToIndex.values(name); QList<int> sourceParams = sourceParamNameToIndex.values(name); @@ -783,7 +784,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ // if it's genuinely new, add it if (existingParamIndex == -1) { FullySpecifiedType type = rewriteType(newParam->type(), &env, control); - newTargetParam = overview(type, newParam->name()); + newTargetParam = overview.prettyType(type, newParam->name()); hadChanges = true; } // otherwise preserve as much as possible from the existing parameter @@ -821,7 +822,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ // track renames if (replacementName != targetParam->name() && replacementName) - renamedTargetParameters[targetParam] = overview(replacementName); + renamedTargetParameters[targetParam] = overview.prettyName(replacementName); // need to change the type (and name)? if (!newParam->type().isEqualTo(sourceParam->type()) @@ -837,14 +838,14 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ FullySpecifiedType replacementType = rewriteType(newParam->type(), &env, control); newTargetParam = targetFile->textOf(parameterStart, parameterTypeStart); - newTargetParam += overview(replacementType, replacementName); + newTargetParam += overview.prettyType(replacementType, replacementName); newTargetParam += targetFile->textOf(parameterTypeEnd, parameterEnd); hadChanges = true; } // change the name only? else if (!namesEqual(targetParam->name(), replacementName)) { DeclaratorIdAST *id = getDeclaratorId(targetParamAst->declarator); - const QString &replacementNameStr = overview(replacementName); + const QString &replacementNameStr = overview.prettyName(replacementName); if (id) { newTargetParam += targetFile->textOf(parameterStart, targetFile->startOf(id)); QString rest = targetFile->textOf(targetFile->endOf(id), parameterEnd); @@ -991,21 +992,18 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ class ApplyDeclDefLinkOperation : public CppQuickFixOperation { public: - explicit ApplyDeclDefLinkOperation( - const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface, + explicit ApplyDeclDefLinkOperation(const CppQuickFixInterface &interface, const QSharedPointer<FunctionDeclDefLink> &link) : CppQuickFixOperation(interface, 10) , m_link(link) {} - virtual void perform() + void perform() { CPPEditorWidget *editor = assistInterface()->editor(); QSharedPointer<FunctionDeclDefLink> link = editor->declDefLink(); - if (link != m_link) - return; - - return editor->applyDeclDefLinkChanges(/*don't jump*/false); + if (link == m_link) + editor->applyDeclDefLinkChanges(/*don't jump*/false); } protected: @@ -1016,17 +1014,13 @@ private: QSharedPointer<FunctionDeclDefLink> m_link; }; -QList<CppQuickFixOperation::Ptr> ApplyDeclDefLinkChanges::match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) +void ApplyDeclDefLinkChanges::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - QList<CppQuickFixOperation::Ptr> results; - QSharedPointer<FunctionDeclDefLink> link = interface->editor()->declDefLink(); if (!link || !link->isMarkerVisible()) - return results; + return; QSharedPointer<ApplyDeclDefLinkOperation> op(new ApplyDeclDefLinkOperation(interface, link)); op->setDescription(FunctionDeclDefLink::tr("Apply Function Signature Changes")); - results += op; - - return results; + result += op; } diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.h b/src/plugins/cppeditor/cppfunctiondecldeflink.h index 02ee37a0ba..152edcf6c1 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.h +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.h @@ -127,8 +127,7 @@ private: class ApplyDeclDefLinkChanges: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> - match(const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface); + void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); }; } // namespace Internal diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp index 520c398550..1baa798981 100644 --- a/src/plugins/cppeditor/cpphighlighter.cpp +++ b/src/plugins/cppeditor/cpphighlighter.cpp @@ -28,10 +28,11 @@ ****************************************************************************/ #include "cpphighlighter.h" -#include <cpptools/cppdoxygen.h> #include <Token.h> #include <cplusplus/SimpleLexer.h> +#include <cplusplus/Lexer.h> +#include <cpptools/cppdoxygen.h> #include <cpptools/cpptoolsreuse.h> #include <texteditor/basetextdocumentlayout.h> @@ -78,10 +79,12 @@ void CppHighlighter::highlightBlock(const QString &text) setCurrentBlockState(previousState); BaseTextDocumentLayout::clearParentheses(currentBlock()); if (text.length()) {// the empty line can still contain whitespace - if (!initialState) - setFormat(0, text.length(), m_formats[CppVisualWhitespace]); + if (initialState == Lexer::State_MultiLineComment) + highlightLine(text, 0, text.length(), m_formats[CppCommentFormat]); + else if (initialState == Lexer::State_MultiLineDoxyComment) + highlightLine(text, 0, text.length(), m_formats[CppDoxygenCommentFormat]); else - setFormat(0, text.length(), m_formats[CppCommentFormat]); + setFormat(0, text.length(), m_formats[CppVisualWhitespace]); } BaseTextDocumentLayout::setFoldingIndent(currentBlock(), foldingIndent); return; @@ -105,12 +108,8 @@ void CppHighlighter::highlightBlock(const QString &text) tokens.at(i - 1).length(); } - if (previousTokenEnd != tk.begin()) { - if (initialState && tk.isComment()) - setFormat(previousTokenEnd, tk.begin() - previousTokenEnd, m_formats[CppCommentFormat]); - else - setFormat(previousTokenEnd, tk.begin() - previousTokenEnd, m_formats[CppVisualWhitespace]); - } + if (previousTokenEnd != tk.begin()) + setFormat(previousTokenEnd, tk.begin() - previousTokenEnd, m_formats[CppVisualWhitespace]); if (tk.is(T_LPAREN) || tk.is(T_LBRACE) || tk.is(T_LBRACKET)) { const QChar c = text.at(tk.begin()); @@ -165,14 +164,15 @@ void CppHighlighter::highlightBlock(const QString &text) setFormat(tk.begin(), tk.length(), m_formats[CppNumberFormat]); else if (tk.isStringLiteral() || tk.isCharLiteral()) - setFormat(tk.begin(), tk.length(), m_formats[CppStringFormat]); + highlightLine(text, tk.begin(), tk.length(), m_formats[CppStringFormat]); else if (tk.isComment()) { + const int startPosition = initialState ? previousTokenEnd : tk.begin(); if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT)) - setFormat(tk.begin(), tk.length(), m_formats[CppCommentFormat]); + highlightLine(text, startPosition, tk.end() - startPosition, m_formats[CppCommentFormat]); else // a doxygen comment - highlightDoxygenComment(text, tk.begin(), tk.length()); + highlightDoxygenComment(text, startPosition, tk.end() - startPosition); // we need to insert a close comment parenthesis, if // - the line starts in a C Comment (initalState != 0) @@ -207,12 +207,9 @@ void CppHighlighter::highlightBlock(const QString &text) } // mark the trailing white spaces - { - const Token tk = tokens.last(); - const int lastTokenEnd = tk.begin() + tk.length(); - if (text.length() > lastTokenEnd) - highlightLine(text, lastTokenEnd, text.length() - lastTokenEnd, QTextCharFormat()); - } + const int lastTokenEnd = tokens.last().end(); + if (text.length() > lastTokenEnd) + highlightLine(text, lastTokenEnd, text.length() - lastTokenEnd, m_formats[CppVisualWhitespace]); if (! initialState && state && ! tokens.isEmpty()) { parentheses.append(Parenthesis(Parenthesis::Opened, QLatin1Char('+'), @@ -334,7 +331,8 @@ bool CppHighlighter::isPPKeyword(const QStringRef &text) const void CppHighlighter::highlightLine(const QString &text, int position, int length, const QTextCharFormat &format) { - const QTextCharFormat visualSpaceFormat = m_formats[CppVisualWhitespace]; + QTextCharFormat visualSpaceFormat = m_formats[CppVisualWhitespace]; + visualSpaceFormat.setBackground(format.background()); const int end = position + length; int index = position; diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp index f0b2de2a8d..106bc1c282 100644 --- a/src/plugins/cppeditor/cpphoverhandler.cpp +++ b/src/plugins/cppeditor/cpphoverhandler.cpp @@ -82,12 +82,12 @@ void CppHoverHandler::identifyMatch(TextEditor::ITextEditor *editor, int pos) if (evaluator.identifiedCppElement()) { const QSharedPointer<CppElement> &cppElement = evaluator.cppElement(); if (!isDiagnosticTooltip()) - setToolTip(cppElement->tooltip()); - foreach (const QString &helpId, cppElement->helpIdCandidates()) { + setToolTip(cppElement->tooltip); + foreach (const QString &helpId, cppElement->helpIdCandidates) { if (!Core::HelpManager::instance()->linksForIdentifier(helpId).isEmpty()) { setLastHelpItemIdentified(TextEditor::HelpItem(helpId, - cppElement->helpMark(), - cppElement->helpCategory())); + cppElement->helpMark, + cppElement->helpCategory)); break; } } diff --git a/src/plugins/cppeditor/cppinsertdecldef.cpp b/src/plugins/cppeditor/cppinsertdecldef.cpp index 8bcebbbf43..b715f5b2db 100644 --- a/src/plugins/cppeditor/cppinsertdecldef.cpp +++ b/src/plugins/cppeditor/cppinsertdecldef.cpp @@ -55,6 +55,7 @@ using namespace CPlusPlus; using namespace CppEditor; using namespace CppEditor::Internal; using namespace CppTools; +using namespace TextEditor; namespace { @@ -86,9 +87,10 @@ public: "Add %1 Declaration").arg(type)); } - void performChanges(const CppRefactoringFilePtr &, - const CppRefactoringChanges &refactoring) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + InsertionPointLocator locator(refactoring); const InsertionLocation loc = locator.methodDeclarationInClass( m_targetFileName, m_targetSymbol, m_xsSpec); @@ -147,8 +149,7 @@ Class *isMemberFunction(const LookupContext &context, Function *function) } // anonymous namespace -QList<CppQuickFixOperation::Ptr> DeclFromDef::match( - const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface) +void DeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); CppRefactoringFilePtr file = interface->currentFile(); @@ -161,24 +162,21 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match( if (DeclaratorIdAST *declId = node->asDeclaratorId()) { if (file->isCursorOn(declId)) { if (FunctionDefinitionAST *candidate = path.at(idx - 2)->asFunctionDefinition()) { - if (funDef) { - return noResult(); - } else { - funDef = candidate; - break; - } + if (funDef) + return; + funDef = candidate; + break; } } } } - if (node->asClassSpecifier()) { - return noResult(); - } + if (node->asClassSpecifier()) + return; } if (!funDef || !funDef->symbol) - return noResult(); + return; Function *fun = funDef->symbol; if (Class *matchingClass = isMemberFunction(interface->context(), fun)) { @@ -191,28 +189,26 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match( if (s->type().isEqualTo(fun->type())) { // Declaration exists. - return noResult(); + return; } } QString fileName = QString::fromUtf8(matchingClass->fileName(), matchingClass->fileNameLength()); const QString decl = InsertDeclOperation::generateDeclaration(fun); - return singleResult(new InsertDeclOperation(interface, fileName, matchingClass, - InsertionPointLocator::Public, decl)); + result.append(TextEditor::QuickFixOperation::Ptr(new InsertDeclOperation(interface, fileName, matchingClass, + InsertionPointLocator::Public, decl))); } - - return noResult(); } QString InsertDeclOperation::generateDeclaration(Function *function) { Overview oo; - oo.setShowFunctionSignatures(true); - oo.setShowReturnTypes(true); - oo.setShowArgumentNames(true); + oo.showFunctionSignatures = true; + oo.showReturnTypes = true; + oo.showArgumentNames = true; QString decl; - decl += oo(function->type(), function->unqualifiedName()); + decl += oo.prettyType(function->type(), function->unqualifiedName()); decl += QLatin1String(";\n"); return decl; @@ -220,9 +216,6 @@ QString InsertDeclOperation::generateDeclaration(Function *function) namespace { - - - class InsertDefOperation: public CppQuickFixOperation { public: @@ -239,17 +232,16 @@ public: .arg(dir.relativeFilePath(m_loc.fileName()))); } - void performChanges(const CppRefactoringFilePtr &, - const CppRefactoringChanges &refactoring) + void perform() { QTC_ASSERT(m_loc.isValid(), return); - + CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr targetFile = refactoring.file(m_loc.fileName()); Overview oo; - oo.setShowFunctionSignatures(true); - oo.setShowReturnTypes(true); - oo.setShowArgumentNames(true); + oo.showFunctionSignatures = true; + oo.showReturnTypes = true; + oo.showArgumentNames = true; // make target lookup context Document::Ptr targetDoc = targetFile->cppDocument(); @@ -271,7 +263,7 @@ public: FullySpecifiedType tn = rewriteType(m_decl->type(), &env, control); // rewrite the function name - QString name = oo(LookupContext::minimalName(m_decl, targetCoN, control)); + QString name = oo.prettyName(LookupContext::minimalName(m_decl, targetCoN, control)); QString defText = oo.prettyType(tn, name) + QLatin1String("\n{\n}"); @@ -293,8 +285,7 @@ private: } // anonymous namespace -QList<CppQuickFixOperation::Ptr> DefFromDecl::match( - const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface) +void DefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); @@ -310,22 +301,18 @@ QList<CppQuickFixOperation::Ptr> DefFromDecl::match( && decl->enclosingScope()->isClass()) { CppRefactoringChanges refactoring(interface->snapshot()); InsertionPointLocator locator(refactoring); - QList<CppQuickFixOperation::Ptr> results; foreach (const InsertionLocation &loc, locator.methodDefinition(decl)) { if (loc.isValid()) - results.append(CppQuickFixOperation::Ptr(new InsertDefOperation(interface, decl, loc))); + result.append(CppQuickFixOperation::Ptr(new InsertDefOperation(interface, decl, loc))); } - return results; + return; } } } } - break; } } - - return noResult(); } namespace { @@ -333,7 +320,7 @@ namespace { class ExtractFunctionOperation : public CppQuickFixOperation { public: - ExtractFunctionOperation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, + ExtractFunctionOperation(const CppQuickFixInterface &interface, int extractionStart, int extractionEnd, FunctionDefinitionAST *refFuncDef, @@ -349,10 +336,11 @@ public: setDescription(QCoreApplication::translate("QuickFix::ExtractFunction", "Extract Function")); } - void performChanges(const CppTools::CppRefactoringFilePtr ¤tFile, - const CppTools::CppRefactoringChanges &refactoring) + void perform() { QTC_ASSERT(!m_funcReturn || !m_relevantDecls.isEmpty(), return); + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); const QString &funcName = getFunctionName(); if (funcName.isEmpty()) @@ -728,14 +716,13 @@ public: } // anonymous namespace -QList<CppQuickFixOperation::Ptr> ExtractFunction::match( - const QSharedPointer<const CppQuickFixAssistInterface> &interface) +void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { CppRefactoringFilePtr file = interface->currentFile(); QTextCursor cursor = file->cursor(); if (!cursor.hasSelection()) - return noResult(); + return; const QList<AST *> &path = interface->path(); FunctionDefinitionAST *refFuncDef = 0; // The "reference" function, which we will extract from. @@ -752,7 +739,7 @@ QList<CppQuickFixOperation::Ptr> ExtractFunction::match( || !refFuncDef->symbol || !refFuncDef->symbol->name() || refFuncDef->symbol->enclosingScope()->isTemplate() /* TODO: Templates... */) { - return noResult(); + return; } // Adjust selection ends. @@ -770,7 +757,7 @@ QList<CppQuickFixOperation::Ptr> ExtractFunction::match( file, printer); if (!analyser(refFuncDef)) - return noResult(); + return; // We also need to collect the declarations of the parameters from the reference function. QSet<QString> refFuncParams; @@ -826,20 +813,20 @@ QList<CppQuickFixOperation::Ptr> ExtractFunction::match( if ((usedBeforeExtraction && usedInsideExtraction) || (usedInsideExtraction && refFuncParams.contains(name))) { - QTC_ASSERT(analyser.m_knownDecls.contains(name), return noResult()); + QTC_ASSERT(analyser.m_knownDecls.contains(name), return); relevantDecls.append(qMakePair(name, analyser.m_knownDecls.value(name))); } // We assume that the first use of a local corresponds to its declaration. if (usedInsideExtraction && usedAfterExtraction && !usedBeforeExtraction) { if (!funcReturn) { - QTC_ASSERT(analyser.m_knownDecls.contains(name), return noResult()); + QTC_ASSERT(analyser.m_knownDecls.contains(name), return); // The return, if any, is stored as the first item in the list. relevantDecls.prepend(qMakePair(name, analyser.m_knownDecls.value(name))); funcReturn = it.key(); } else { // Would require multiple returns. (Unless we do fancy things, as pointed below.) - return noResult(); + return; } } } @@ -847,10 +834,10 @@ QList<CppQuickFixOperation::Ptr> ExtractFunction::match( // The current implementation doesn't try to be too smart since it preserves the original form // of the declarations. This might be or not the desired effect. An improvement would be to // let the user somehow customize the function interface. - return singleResult(new ExtractFunctionOperation(interface, + result.append(CppQuickFixOperation::Ptr(new ExtractFunctionOperation(interface, analyser.m_extractionStart, analyser.m_extractionEnd, refFuncDef, funcReturn, - relevantDecls)); + relevantDecls))); } diff --git a/src/plugins/cppeditor/cppinsertdecldef.h b/src/plugins/cppeditor/cppinsertdecldef.h index 9868b599e5..950e20d294 100644 --- a/src/plugins/cppeditor/cppinsertdecldef.h +++ b/src/plugins/cppeditor/cppinsertdecldef.h @@ -38,24 +38,20 @@ namespace Internal { class DeclFromDef: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> - match(const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface); + void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); }; class DefFromDecl: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> - match(const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface); + void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); }; class ExtractFunction : public CppQuickFixFactory { - virtual QList<CppQuickFixOperation::Ptr> - match(const QSharedPointer<const CppQuickFixAssistInterface> &interface); + void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); }; - } // namespace Internal } // namespace CppEditor diff --git a/src/plugins/cppeditor/cppinsertqtpropertymembers.cpp b/src/plugins/cppeditor/cppinsertqtpropertymembers.cpp index 6d22946e5c..a64d0dd4c1 100644 --- a/src/plugins/cppeditor/cppinsertqtpropertymembers.cpp +++ b/src/plugins/cppeditor/cppinsertqtpropertymembers.cpp @@ -50,18 +50,18 @@ using namespace Utils; using namespace CppEditor; using namespace CppEditor::Internal; -QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match( - const QSharedPointer<const CppQuickFixAssistInterface> &interface) +void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface, + QuickFixOperations &result) { const QList<AST *> &path = interface->path(); if (path.isEmpty()) - return noResult(); + return; AST * const ast = path.last(); QtPropertyDeclarationAST *qtPropertyDeclaration = ast->asQtPropertyDeclaration(); if (!qtPropertyDeclaration) - return noResult(); + return; ClassSpecifierAST *klass = 0; for (int i = path.size() - 2; i >= 0; --i) { @@ -70,7 +70,7 @@ QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match( break; } if (!klass) - return noResult(); + return; CppRefactoringFilePtr file = interface->currentFile(); const QString propertyName = file->textOf(qtPropertyDeclaration->property_name); @@ -102,7 +102,7 @@ QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match( Symbol *member = c->memberAt(i); FullySpecifiedType type = member->type(); if (member->asFunction() || (type.isValid() && type->asFunctionType())) { - const QString name = overview(member->name()); + const QString name = overview.prettyName(member->name()); if (name == getterName) { generateFlags &= ~GenerateGetter; } else if (name == setterName) { @@ -111,22 +111,22 @@ QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match( generateFlags &= ~GenerateSignal; } } else if (member->asDeclaration()) { - const QString name = overview(member->name()); + const QString name = overview.prettyName(member->name()); if (name == storageName) generateFlags &= ~GenerateStorage; } } if (getterName.isEmpty() && setterName.isEmpty() && signalName.isEmpty()) - return noResult(); + return; - return singleResult(new Operation(interface, path.size() - 1, qtPropertyDeclaration, c, - generateFlags, - getterName, setterName, signalName, storageName)); + result.append(QuickFixOperation::Ptr( + new Operation(interface, path.size() - 1, qtPropertyDeclaration, c, + generateFlags, getterName, setterName, signalName, storageName))); } InsertQtPropertyMembers::Operation::Operation( - const QSharedPointer<const CppQuickFixAssistInterface> &interface, + const CppQuickFixInterface &interface, int priority, QtPropertyDeclarationAST *declaration, Class *klass, int generateFlags, const QString &getterName, const QString &setterName, const QString &signalName, const QString &storageName) @@ -143,9 +143,11 @@ InsertQtPropertyMembers::Operation::Operation( setDescription(desc); } -void InsertQtPropertyMembers::Operation::performChanges(const CppRefactoringFilePtr &file, - const CppRefactoringChanges &refactoring) +void InsertQtPropertyMembers::Operation::perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr file = refactoring.file(fileName()); + InsertionPointLocator locator(refactoring); Utils::ChangeSet declarations; diff --git a/src/plugins/cppeditor/cppinsertqtpropertymembers.h b/src/plugins/cppeditor/cppinsertqtpropertymembers.h index b6611dd3a9..5400c32b53 100644 --- a/src/plugins/cppeditor/cppinsertqtpropertymembers.h +++ b/src/plugins/cppeditor/cppinsertqtpropertymembers.h @@ -60,8 +60,7 @@ class InsertQtPropertyMembers : public CppQuickFixFactory Q_OBJECT public: - virtual QList<CppQuickFixOperation::Ptr> - match(const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface); + void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); private: enum GenerateFlag { @@ -81,8 +80,7 @@ private: const QString &getterName, const QString &setterName, const QString &signalName, const QString &storageName); - virtual void performChanges(const CppTools::CppRefactoringFilePtr &file, - const CppTools::CppRefactoringChanges &refactoring); + void perform(); private: void insertAndIndent(const TextEditor::RefactoringFilePtr &file, Utils::ChangeSet *changeSet, diff --git a/src/plugins/cppeditor/cppplugin.cpp b/src/plugins/cppeditor/cppplugin.cpp index 4f4176bb05..2a1b452a13 100644 --- a/src/plugins/cppeditor/cppplugin.cpp +++ b/src/plugins/cppeditor/cppplugin.cpp @@ -54,6 +54,7 @@ #include <texteditor/texteditorplugin.h> #include <texteditor/texteditorsettings.h> #include <texteditor/texteditorconstants.h> +#include <utils/hostosinfo.h> #include <cpptools/ModelManagerInterface.h> #include <cpptools/cpptoolsconstants.h> #include <cpptools/cpptoolssettings.h> @@ -83,21 +84,21 @@ CppEditorFactory::CppEditorFactory(CppPlugin *owner) : << QLatin1String(CppEditor::Constants::CPP_SOURCE_MIMETYPE) << QLatin1String(CppEditor::Constants::CPP_HEADER_MIMETYPE); -#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN) - Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance(); - Core::MimeDatabase *mimeDatabase = Core::ICore::mimeDatabase(); - iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_cpp.png")), - mimeDatabase->findByType(QLatin1String(CppEditor::Constants::CPP_SOURCE_MIMETYPE))); - iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_c.png")), - mimeDatabase->findByType(QLatin1String(CppEditor::Constants::C_SOURCE_MIMETYPE))); - iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_h.png")), - mimeDatabase->findByType(QLatin1String(CppEditor::Constants::CPP_HEADER_MIMETYPE))); -#endif + if (!Utils::HostOsInfo::isMacHost() && !Utils::HostOsInfo::isWindowsHost()) { + Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance(); + Core::MimeDatabase *mimeDatabase = Core::ICore::mimeDatabase(); + iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_cpp.png")), + mimeDatabase->findByType(QLatin1String(CppEditor::Constants::CPP_SOURCE_MIMETYPE))); + iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_c.png")), + mimeDatabase->findByType(QLatin1String(CppEditor::Constants::C_SOURCE_MIMETYPE))); + iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_h.png")), + mimeDatabase->findByType(QLatin1String(CppEditor::Constants::CPP_HEADER_MIMETYPE))); + } } Core::Id CppEditorFactory::id() const { - return CppEditor::Constants::CPPEDITOR_ID; + return Core::Id(CppEditor::Constants::CPPEDITOR_ID); } QString CppEditorFactory::displayName() const @@ -149,7 +150,7 @@ void CppPlugin::initializeEditor(CPPEditorWidget *editor) { m_actionHandler->setupActions(editor); - editor->setLanguageSettingsId(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID)); + editor->setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID); TextEditor::TextEditorSettings::instance()->initializeEditor(editor); // method combo box sorting diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp index b510eb7117..2720cf86a3 100644 --- a/src/plugins/cppeditor/cppquickfix.cpp +++ b/src/plugins/cppeditor/cppquickfix.cpp @@ -53,23 +53,15 @@ using namespace CppEditor::Internal; using namespace CppTools; using namespace TextEditor; using namespace CPlusPlus; -using namespace Utils; -CppQuickFixOperation::CppQuickFixOperation( - const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority) +CppQuickFixOperation::CppQuickFixOperation(const CppQuickFixInterface &interface, int priority) : QuickFixOperation(priority) , m_interface(interface) {} -CppQuickFixOperation::~CppQuickFixOperation() -{} - -void CppQuickFixOperation::perform() +Snapshot CppQuickFixOperation::snapshot() const { - CppRefactoringChanges refactoring(m_interface->snapshot()); - CppRefactoringFilePtr current = refactoring.file(fileName()); - - performChanges(current, refactoring); + return m_interface->snapshot(); } const CppQuickFixAssistInterface *CppQuickFixOperation::assistInterface() const @@ -82,32 +74,10 @@ QString CppQuickFixOperation::fileName() const return m_interface->document()->fileName(); } -CppQuickFixFactory::CppQuickFixFactory() -{ -} - -CppQuickFixFactory::~CppQuickFixFactory() +void CppQuickFixFactory::matchingOperations(const QuickFixInterface &interface, QuickFixOperations &result) { -} - -QList<QuickFixOperation::Ptr> CppQuickFixFactory::matchingOperations( - const QSharedPointer<const TextEditor::IAssistInterface> &interface) -{ - QSharedPointer<const CppQuickFixAssistInterface> cppInterface = - interface.staticCast<const CppQuickFixAssistInterface>(); + CppQuickFixInterface cppInterface = interface.staticCast<const CppQuickFixAssistInterface>(); if (cppInterface->path().isEmpty()) - return QList<QuickFixOperation::Ptr>(); - return match(cppInterface); -} - -QList<CppQuickFixOperation::Ptr> CppQuickFixFactory::singleResult(CppQuickFixOperation *operation) -{ - QList<CppQuickFixOperation::Ptr> result; - result.append(CppQuickFixOperation::Ptr(operation)); - return result; -} - -QList<CppQuickFixOperation::Ptr> CppQuickFixFactory::noResult() -{ - return QList<CppQuickFixOperation::Ptr>(); + return; + match(cppInterface, result); } diff --git a/src/plugins/cppeditor/cppquickfix.h b/src/plugins/cppeditor/cppquickfix.h index 0067c5ff00..53c57e09d0 100644 --- a/src/plugins/cppeditor/cppquickfix.h +++ b/src/plugins/cppeditor/cppquickfix.h @@ -35,44 +35,26 @@ namespace CPlusPlus { class CppModelManagerInterface; -} - -namespace CppTools { - class CppRefactoringFile; - class CppRefactoringChanges; - typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr; -} // namespace CppTools - -namespace ExtensionSystem { -class IPlugin; +class Snapshot; } namespace CppEditor { +namespace Internal { class CppQuickFixAssistInterface; } -namespace Internal { -class CppQuickFixAssistInterface; -} +typedef QSharedPointer<const Internal::CppQuickFixAssistInterface> CppQuickFixInterface; class CPPEDITOR_EXPORT CppQuickFixOperation: public TextEditor::QuickFixOperation { public: - explicit CppQuickFixOperation( - const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface, - int priority = -1); - virtual ~CppQuickFixOperation(); - - virtual void perform(); + explicit CppQuickFixOperation(const CppQuickFixInterface &interface, int priority = -1); protected: - virtual void performChanges(const CppTools::CppRefactoringFilePtr ¤tFile, - const CppTools::CppRefactoringChanges &refactoring) = 0; - QString fileName() const; - + CPlusPlus::Snapshot snapshot() const; const Internal::CppQuickFixAssistInterface *assistInterface() const; private: - QSharedPointer<const Internal::CppQuickFixAssistInterface> m_interface; + CppQuickFixInterface m_interface; }; class CPPEDITOR_EXPORT CppQuickFixFactory: public TextEditor::QuickFixFactory @@ -80,29 +62,17 @@ class CPPEDITOR_EXPORT CppQuickFixFactory: public TextEditor::QuickFixFactory Q_OBJECT public: - CppQuickFixFactory(); - virtual ~CppQuickFixFactory(); + CppQuickFixFactory() {} - virtual QList<TextEditor::QuickFixOperation::Ptr> - matchingOperations(const QSharedPointer<const TextEditor::IAssistInterface> &interface); + void matchingOperations(const TextEditor::QuickFixInterface &interface, + TextEditor::QuickFixOperations &result); /*! Implement this method to match and create the appropriate CppQuickFixOperation objects. */ - virtual QList<CppQuickFixOperation::Ptr> match( - const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface) = 0; - -protected: - /*! - Creates a list of 1 single element: the shared-pointer to the given - operation. This shared-pointer takes over the ownership (meaning the - responsibility to delete the operation). - */ - static QList<CppQuickFixOperation::Ptr> singleResult(CppQuickFixOperation *operation); - - /// Utility method which creates an empty list. - static QList<CppQuickFixOperation::Ptr> noResult(); + virtual void match(const CppQuickFixInterface &interface, + TextEditor::QuickFixOperations &result) = 0; }; } // namespace CppEditor diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 3a49abd733..9128e37d97 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -76,8 +76,8 @@ using namespace CppEditor; using namespace CppEditor::Internal; using namespace CppTools; -using namespace TextEditor; using namespace CPlusPlus; +using namespace TextEditor; using namespace Utils; static inline bool isQtStringLiteral(const QByteArray &id) @@ -103,18 +103,17 @@ namespace { class UseInverseOp: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - QList<CppQuickFixOperation::Ptr> result; CppRefactoringFilePtr file = interface->currentFile(); const QList<AST *> &path = interface->path(); int index = path.size() - 1; BinaryExpressionAST *binary = path.at(index)->asBinaryExpression(); if (! binary) - return result; + return; if (! interface->isCursorOn(binary->binary_op_token)) - return result; + return; Kind invertToken; switch (file->tokenAt(binary->binary_op_token).kind()) { @@ -137,11 +136,10 @@ public: invertToken = T_EQUAL_EQUAL; break; default: - return result; + return; } result.append(CppQuickFixOperation::Ptr(new Operation(interface, index, binary, invertToken))); - return result; } private: @@ -154,7 +152,7 @@ private: QString replacement; public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, + Operation(const CppQuickFixInterface &interface, int priority, BinaryExpressionAST *binary, Kind invertToken) : CppQuickFixOperation(interface, priority) , binary(binary), nested(0), negation(0) @@ -180,8 +178,11 @@ private: return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; if (negation) { // can't remove parentheses since that might break precedence @@ -211,18 +212,17 @@ private: class FlipBinaryOp: public CppQuickFixFactory { public: - virtual QList<QuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - QList<QuickFixOperation::Ptr> result; const QList<AST *> &path = interface->path(); CppRefactoringFilePtr file = interface->currentFile(); int index = path.size() - 1; BinaryExpressionAST *binary = path.at(index)->asBinaryExpression(); if (! binary) - return result; + return; if (! interface->isCursorOn(binary->binary_op_token)) - return result; + return; Kind flipToken; switch (file->tokenAt(binary->binary_op_token).kind()) { @@ -245,7 +245,7 @@ public: flipToken = T_EOF_SYMBOL; break; default: - return result; + return; } QString replacement; @@ -256,14 +256,13 @@ public: } result.append(QuickFixOperation::Ptr(new Operation(interface, index, binary, replacement))); - return result; } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, + Operation(const CppQuickFixInterface &interface, int priority, BinaryExpressionAST *binary, QString replacement) : CppQuickFixOperation(interface) , binary(binary) @@ -280,10 +279,12 @@ private: return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { - ChangeSet changes; + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; changes.flip(currentFile->range(binary->left_expression), currentFile->range(binary->right_expression)); if (! replacement.isEmpty()) changes.replace(currentFile->range(binary->binary_op_token), replacement); @@ -310,9 +311,8 @@ private: class RewriteLogicalAndOp: public CppQuickFixFactory { public: - virtual QList<QuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - QList<QuickFixOperation::Ptr> result; BinaryExpressionAST *expression = 0; const QList<AST *> &path = interface->path(); CppRefactoringFilePtr file = interface->currentFile(); @@ -325,10 +325,10 @@ public: } if (! expression) - return result; + return; if (! interface->isCursorOn(expression->binary_op_token)) - return result; + return; QSharedPointer<Operation> op(new Operation(interface)); @@ -340,8 +340,6 @@ public: op->setPriority(index); result.append(op); } - - return result; } private: @@ -353,7 +351,7 @@ private: UnaryExpressionAST *right; BinaryExpressionAST *pattern; - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + Operation(const CppQuickFixInterface &interface) : CppQuickFixOperation(interface) , mk(new ASTPatternBuilder) { @@ -362,8 +360,11 @@ private: pattern = mk->BinaryExpression(left, right); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; changes.replace(currentFile->range(pattern->binary_op_token), QLatin1String("||")); changes.remove(currentFile->range(left->unary_op_token)); @@ -423,12 +424,12 @@ class SplitSimpleDeclarationOp: public CppQuickFixFactory } public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - QList<CppQuickFixOperation::Ptr> result; CoreDeclaratorAST *core_declarator = 0; const QList<AST *> &path = interface->path(); CppRefactoringFilePtr file = interface->currentFile(); + const int cursorPosition = file->cursor().selectionStart(); for (int index = path.size() - 1; index != -1; --index) { AST *node = path.at(index); @@ -440,34 +441,32 @@ public: if (checkDeclaration(simpleDecl)) { SimpleDeclarationAST *declaration = simpleDecl; - const int cursorPosition = file->cursor().selectionStart(); - const int startOfDeclSpecifier = file->startOf(declaration->decl_specifier_list->firstToken()); const int endOfDeclSpecifier = file->endOf(declaration->decl_specifier_list->lastToken() - 1); if (cursorPosition >= startOfDeclSpecifier && cursorPosition <= endOfDeclSpecifier) { // the AST node under cursor is a specifier. - return singleResult(new Operation(interface, index, declaration)); + result.append(QuickFixOperation::Ptr(new Operation(interface, index, declaration))); + return; } if (core_declarator && interface->isCursorOn(core_declarator)) { // got a core-declarator under the text cursor. - return singleResult(new Operation(interface, index, declaration)); + result.append(QuickFixOperation::Ptr(new Operation(interface, index, declaration))); + return; } } - break; + return; } } - - return result; } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, SimpleDeclarationAST *decl) + Operation(const CppQuickFixInterface &interface, int priority, SimpleDeclarationAST *decl) : CppQuickFixOperation(interface, priority) , declaration(decl) { @@ -475,8 +474,11 @@ private: "Split Declaration")); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; SpecifierListAST *specifiers = declaration->decl_specifier_list; @@ -527,7 +529,7 @@ private: class AddBracesToIfOp: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); @@ -536,7 +538,8 @@ public: IfStatementAST *ifStatement = path.at(index)->asIfStatement(); if (ifStatement && interface->isCursorOn(ifStatement->if_token) && ifStatement->statement && ! ifStatement->statement->asCompoundStatement()) { - return singleResult(new Operation(interface, index, ifStatement->statement)); + result.append(QuickFixOperation::Ptr(new Operation(interface, index, ifStatement->statement))); + return; } // or if we're on the statement contained in the if @@ -546,21 +549,20 @@ public: if (ifStatement && ifStatement->statement && interface->isCursorOn(ifStatement->statement) && ! ifStatement->statement->asCompoundStatement()) { - return singleResult(new Operation(interface, index, ifStatement->statement)); + result.append(QuickFixOperation::Ptr(new Operation(interface, index, ifStatement->statement))); + return; } } // ### This could very well be extended to the else branch // and other nodes entirely. - - return noResult(); } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, StatementAST *statement) + Operation(const CppQuickFixInterface &interface, int priority, StatementAST *statement) : CppQuickFixOperation(interface, priority) , _statement(statement) { @@ -568,8 +570,11 @@ private: "Add Curly Braces")); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; const int start = currentFile->endOf(_statement->firstToken() - 1); @@ -601,7 +606,7 @@ private: class MoveDeclarationOutOfIfOp: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); QSharedPointer<Operation> op(new Operation(interface)); @@ -613,26 +618,23 @@ public: DeclaratorAST *declarator = op->condition->declarator; op->core = declarator->core_declarator; if (! op->core) - return noResult(); + return; if (interface->isCursorOn(op->core)) { - QList<CppQuickFixOperation::Ptr> result; op->setPriority(index); result.append(op); - return result; + return; } } } } - - return noResult(); } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + Operation(const CppQuickFixInterface &interface) : CppQuickFixOperation(interface) { setDescription(QApplication::translate("CppTools::QuickFix", @@ -642,8 +644,11 @@ private: pattern = mk.IfStatement(condition); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; changes.copy(currentFile->range(core), currentFile->startOf(condition)); @@ -679,7 +684,7 @@ private: class MoveDeclarationOutOfWhileOp: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); QSharedPointer<Operation> op(new Operation(interface)); @@ -692,32 +697,29 @@ public: op->core = declarator->core_declarator; if (! op->core) - return noResult(); + return; - else if (! declarator->equal_token) - return noResult(); + if (! declarator->equal_token) + return; - else if (! declarator->initializer) - return noResult(); + if (! declarator->initializer) + return; if (interface->isCursorOn(op->core)) { - QList<CppQuickFixOperation::Ptr> result; op->setPriority(index); result.append(op); - return result; + return; } } } } - - return noResult(); } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + Operation(const CppQuickFixInterface &interface) : CppQuickFixOperation(interface) { setDescription(QApplication::translate("CppTools::QuickFix", @@ -727,8 +729,11 @@ private: pattern = mk.WhileStatement(condition); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; changes.insert(currentFile->startOf(condition), QLatin1String("(")); @@ -780,7 +785,7 @@ private: class SplitIfStatementOp: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { IfStatementAST *pattern = 0; const QList<AST *> &path = interface->path(); @@ -795,14 +800,14 @@ public: } if (! pattern || ! pattern->statement) - return noResult(); + return; unsigned splitKind = 0; for (++index; index < path.size(); ++index) { AST *node = path.at(index); BinaryExpressionAST *condition = node->asBinaryExpression(); if (! condition) - return noResult(); + return; Token binaryToken = interface->currentFile()->tokenAt(condition->binary_op_token); @@ -810,26 +815,26 @@ public: if (! splitKind) { splitKind = binaryToken.kind(); if (splitKind != T_AMPER_AMPER && splitKind != T_PIPE_PIPE) - return noResult(); + return; // we can't reliably split &&s in ifs with an else branch if (splitKind == T_AMPER_AMPER && pattern->else_statement) - return noResult(); + return; } else if (splitKind != binaryToken.kind()) { - return noResult(); + return; } - if (interface->isCursorOn(condition->binary_op_token)) - return singleResult(new Operation(interface, index, pattern, condition)); + if (interface->isCursorOn(condition->binary_op_token)) { + result.append(QuickFixOperation::Ptr(new Operation(interface, index, pattern, condition))); + return; + } } - - return noResult(); } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, + Operation(const CppQuickFixInterface &interface, int priority, IfStatementAST *pattern, BinaryExpressionAST *condition) : CppQuickFixOperation(interface, priority) , pattern(pattern) @@ -839,8 +844,11 @@ private: "Split if Statement")); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + const Token binaryToken = currentFile->tokenAt(condition->binary_op_token); if (binaryToken.is(T_AMPER_AMPER)) @@ -931,7 +939,7 @@ static inline QString msgQtStringLiteralDescription(const QString &replacement) class WrapStringLiteral: public CppQuickFixFactory { public: - typedef const QSharedPointer<const CppQuickFixAssistInterface> AssistInterfacePtr; + typedef const CppQuickFixInterface AssistInterfacePtr; enum ActionFlags { @@ -946,7 +954,8 @@ public: enum Type { TypeString, TypeObjCString, TypeChar, TypeNone }; - virtual QList<CppQuickFixOperation::Ptr> match(const AssistInterfacePtr &interface); + //void match(const AssistInterfacePtr &interface, QuickFixOperations &result); + void match(const CppQuickFixInterface &interface, QuickFixOperations &result); static QString replacement(unsigned actions); static QByteArray stringToCharEscapeSequences(const QByteArray &content); static QByteArray charToStringEscapeSequences(const QByteArray &content); @@ -964,7 +973,8 @@ public: unsigned actions, const QString &description, ExpressionAST *literal, const QString &translationContext = QString()); - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &); + void perform(); + private: const unsigned m_actions; ExpressionAST *m_literal; @@ -1020,7 +1030,7 @@ ExpressionAST *WrapStringLiteral::analyze(const QList<AST *> &path, return literal; } -QList<CppQuickFixOperation::Ptr> WrapStringLiteral::match(const AssistInterfacePtr &interface) +void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { typedef CppQuickFixOperation::Ptr OperationPtr; @@ -1030,18 +1040,16 @@ QList<CppQuickFixOperation::Ptr> WrapStringLiteral::match(const AssistInterfaceP CppRefactoringFilePtr file = interface->currentFile(); ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction); if (!literal || type == TypeNone) - return noResult(); + return; if ((type == TypeChar && enclosingFunction == "QLatin1Char") || isQtStringLiteral(enclosingFunction) || isQtStringTranslation(enclosingFunction)) - return noResult(); + return; - QList<CppQuickFixOperation::Ptr> result; const int priority = path.size() - 1; // very high priority if (type == TypeChar) { unsigned actions = EncloseInQLatin1CharAction; - QString description = - msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions)); + QString description = msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions)); result << OperationPtr(new Operation(interface, priority, actions, description, literal)); if (NumericLiteralAST *charLiteral = literal->asNumericLiteral()) { @@ -1083,7 +1091,6 @@ QList<CppQuickFixOperation::Ptr> WrapStringLiteral::match(const AssistInterfaceP msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions), 5), literal)); } - return result; } QString WrapStringLiteral::replacement(unsigned actions) @@ -1134,8 +1141,11 @@ WrapStringLiteral::Operation::Operation(const AssistInterfacePtr &interface, int setDescription(description); } -void WrapStringLiteral::Operation::performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) +void WrapStringLiteral::Operation::perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; const int startPos = currentFile->startOf(m_literal); @@ -1205,7 +1215,7 @@ void WrapStringLiteral::Operation::performChanges(const CppRefactoringFilePtr &c class TranslateStringLiteral: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { // Initialize WrapStringLiteral::Type type = WrapStringLiteral::TypeNone; @@ -1215,7 +1225,7 @@ public: ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction); if (!literal || type != WrapStringLiteral::TypeString || isQtStringLiteral(enclosingFunction) || isQtStringTranslation(enclosingFunction)) - return noResult(); + return; QString trContext; @@ -1224,9 +1234,7 @@ public: // Check whether we are in a method: const QString description = QApplication::translate("CppTools::QuickFix", "Mark as Translatable"); - QList<CppQuickFixOperation::Ptr> result; - for (int i = path.size() - 1; i >= 0; --i) - { + for (int i = path.size() - 1; i >= 0; --i) { if (FunctionDefinitionAST *definition = path.at(i)->asFunctionDefinition()) { Function *function = definition->symbol; ClassOrNamespace *b = interface->context().lookupType(function); @@ -1236,9 +1244,10 @@ public: Symbol *s = r.declaration(); if (s->type()->isFunctionType()) { // no context required for tr - return singleResult(new WrapStringLiteral::Operation(interface, path.size() - 1, + result.append(QuickFixOperation::Ptr(new WrapStringLiteral::Operation(interface, path.size() - 1, WrapStringLiteral::TranslateTrAction, - description, literal)); + description, literal))); + return; } } } @@ -1253,16 +1262,17 @@ public: // ... or global if none available! if (trContext.isEmpty()) trContext = QLatin1String("GLOBAL"); - return singleResult(new WrapStringLiteral::Operation(interface, path.size() - 1, + result.append(QuickFixOperation::Ptr(new WrapStringLiteral::Operation(interface, path.size() - 1, WrapStringLiteral::TranslateQCoreApplicationAction, - description, literal, trContext)); + description, literal, trContext))); + return; } } // We need to use Q_TRANSLATE_NOOP - return singleResult(new WrapStringLiteral::Operation(interface, path.size() - 1, + result.append(QuickFixOperation::Ptr(new WrapStringLiteral::Operation(interface, path.size() - 1, WrapStringLiteral::TranslateNoopAction, - description, literal, trContext)); + description, literal, trContext))); } }; @@ -1279,12 +1289,12 @@ public: class CStringToNSString: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { CppRefactoringFilePtr file = interface->currentFile(); if (interface->editor()->mimeType() != QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)) - return noResult(); + return; WrapStringLiteral::Type type = WrapStringLiteral::TypeNone; QByteArray enclosingFunction; @@ -1292,18 +1302,18 @@ public: const QList<AST *> &path = interface->path(); ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction, &qlatin1Call); if (!literal || type != WrapStringLiteral::TypeString) - return noResult(); + return; if (!isQtStringLiteral(enclosingFunction)) qlatin1Call = 0; - return singleResult(new Operation(interface, path.size() - 1, literal->asStringLiteral(), qlatin1Call)); + result.append(QuickFixOperation::Ptr(new Operation(interface, path.size() - 1, literal->asStringLiteral(), qlatin1Call))); } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, StringLiteralAST *stringLiteral, CallAST *qlatin1Call) + Operation(const CppQuickFixInterface &interface, int priority, StringLiteralAST *stringLiteral, CallAST *qlatin1Call) : CppQuickFixOperation(interface, priority) , stringLiteral(stringLiteral) , qlatin1Call(qlatin1Call) @@ -1312,8 +1322,11 @@ private: "Convert to Objective-C String Literal")); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; if (qlatin1Call) { @@ -1354,27 +1367,25 @@ private: class ConvertNumericLiteral: public CppQuickFixFactory { public: - virtual QList<QuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - QList<QuickFixOperation::Ptr> result; - const QList<AST *> &path = interface->path(); CppRefactoringFilePtr file = interface->currentFile(); if (path.isEmpty()) - return result; // nothing to do + return; NumericLiteralAST *literal = path.last()->asNumericLiteral(); if (! literal) - return result; + return; Token token = file->tokenAt(literal->asNumericLiteral()->literal_token); if (!token.is(T_NUMERIC_LITERAL)) - return result; + return; const NumericLiteral *numeric = token.number; if (numeric->isDouble() || numeric->isFloat()) - return result; + return; // remove trailing L or U and stuff const char * const spell = numeric->chars(); @@ -1382,13 +1393,13 @@ public: while (numberLength > 0 && !std::isxdigit(spell[numberLength - 1])) --numberLength; if (numberLength < 1) - return result; + return; // convert to number bool valid; ulong value = QString::fromUtf8(spell).left(numberLength).toULong(&valid, 0); if (!valid) // e.g. octal with digit > 7 - return result; + return; const int priority = path.size() - 1; // very high priority const int start = file->startOf(literal); @@ -1449,15 +1460,13 @@ public: result.append(op); } } - - return result; } private: class ConvertNumeric: public CppQuickFixOperation { public: - ConvertNumeric(const QSharedPointer<const CppQuickFixAssistInterface> &interface, + ConvertNumeric(const CppQuickFixInterface &interface, int start, int end, const QString &replacement) : CppQuickFixOperation(interface) , start(start) @@ -1465,8 +1474,11 @@ private: , replacement(replacement) {} - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + ChangeSet changes; changes.replace(start, end, replacement); currentFile->setChangeSet(changes); @@ -1487,26 +1499,28 @@ private: class FixForwardDeclarationOp: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); for (int index = path.size() - 1; index != -1; --index) { AST *ast = path.at(index); if (NamedTypeSpecifierAST *namedTy = ast->asNamedTypeSpecifier()) { - if (Symbol *fwdClass = checkName(interface, namedTy->name)) - return singleResult(new Operation(interface, index, fwdClass)); + if (Symbol *fwdClass = checkName(interface, namedTy->name)) { + result.append(QuickFixOperation::Ptr(new Operation(interface, index, fwdClass))); + return; + } } else if (ElaboratedTypeSpecifierAST *eTy = ast->asElaboratedTypeSpecifier()) { - if (Symbol *fwdClass = checkName(interface, eTy->name)) - return singleResult(new Operation(interface, index, fwdClass)); + if (Symbol *fwdClass = checkName(interface, eTy->name)) { + result.append(QuickFixOperation::Ptr(new Operation(interface, index, fwdClass))); + return; + } } } - - return noResult(); } protected: - static Symbol *checkName(const QSharedPointer<const CppQuickFixAssistInterface> &interface, NameAST *ast) + static Symbol *checkName(const CppQuickFixInterface &interface, NameAST *ast) { if (ast && interface->isCursorOn(ast)) { if (const Name *name = ast->name) { @@ -1537,7 +1551,7 @@ private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, Symbol *fwdClass) + Operation(const CppQuickFixInterface &interface, int priority, Symbol *fwdClass) : CppQuickFixOperation(interface, priority) , fwdClass(fwdClass) { @@ -1545,21 +1559,20 @@ private: "#include Header File")); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, - const CppRefactoringChanges &) + void perform() { QTC_ASSERT(fwdClass != 0, return); + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); CppTools::SymbolFinder symbolFinder; - if (Class *k = - symbolFinder.findMatchingClassDeclaration(fwdClass, - assistInterface()->snapshot())) { + if (Class *k = symbolFinder.findMatchingClassDeclaration(fwdClass, snapshot())) { const QString headerFile = QString::fromUtf8(k->fileName(), k->fileNameLength()); // collect the fwd headers Snapshot fwdHeaders; - fwdHeaders.insert(assistInterface()->snapshot().document(headerFile)); - foreach (Document::Ptr doc, assistInterface()->snapshot()) { + fwdHeaders.insert(snapshot().document(headerFile)); + foreach (Document::Ptr doc, snapshot()) { QFileInfo headerFileInfo(doc->fileName()); if (doc->globalSymbolCount() == 0 && doc->includes().size() == 1) fwdHeaders.insert(doc); @@ -1629,7 +1642,7 @@ private: class AddLocalDeclarationOp: public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); CppRefactoringFilePtr file = interface->currentFile(); @@ -1654,33 +1667,34 @@ public: } if (! decl) { - return singleResult(new Operation(interface, index, binary)); + result.append(QuickFixOperation::Ptr(new Operation(interface, index, binary))); + return; } } } } } - - return noResult(); } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, BinaryExpressionAST *binaryAST) + Operation(const CppQuickFixInterface &interface, int priority, BinaryExpressionAST *binaryAST) : CppQuickFixOperation(interface, priority) , binaryAST(binaryAST) { setDescription(QApplication::translate("CppTools::QuickFix", "Add Local Declaration")); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, - const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + TypeOfExpression typeOfExpression; typeOfExpression.init(assistInterface()->semanticInfo().doc, - assistInterface()->snapshot(), assistInterface()->context().bindings()); + snapshot(), assistInterface()->context().bindings()); Scope *scope = currentFile->scopeAt(binaryAST->firstToken()); const QList<LookupItem> result = typeOfExpression(currentFile->textOf(binaryAST->right_expression).toUtf8(), @@ -1702,7 +1716,7 @@ private: FullySpecifiedType tn = rewriteType(result.first().type(), &env, control); Overview oo; - QString ty = oo(tn); + QString ty = oo.prettyType(tn); if (! ty.isEmpty()) { const QChar ch = ty.at(ty.size() - 1); @@ -1731,12 +1745,12 @@ private: class ToCamelCaseConverter : public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> &path = interface->path(); if (path.isEmpty()) - return noResult(); + return; AST * const ast = path.last(); const Name *name = 0; @@ -1748,24 +1762,24 @@ public: } if (!name) - return noResult(); + return; QString newName = QString::fromUtf8(name->identifier()->chars()); if (newName.length() < 3) - return noResult(); + return; for (int i = 1; i < newName.length() - 1; ++i) { - if (Operation::isConvertibleUnderscore(newName, i)) - return singleResult(new Operation(interface, path.size() - 1, newName)); + if (Operation::isConvertibleUnderscore(newName, i)) { + result.append(QuickFixOperation::Ptr(new Operation(interface, path.size() - 1, newName))); + return; + } } - - return noResult(); } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, const QString &newName) + Operation(const CppQuickFixInterface &interface, int priority, const QString &newName) : CppQuickFixOperation(interface, priority) , m_name(newName) { @@ -1773,9 +1787,11 @@ private: "Convert to Camel Case")); } - virtual void performChanges(const CppRefactoringFilePtr &, - const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + for (int i = 1; i < m_name.length(); ++i) { QCharRef c = m_name[i]; if (c.isUpper()) { @@ -1806,16 +1822,16 @@ private: class IncludeAdder : public CppQuickFixFactory { public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { CppClassesFilter *classesFilter = ExtensionSystem::PluginManager::getObject<CppClassesFilter>(); if (!classesFilter) - return noResult(); + return; const QList<AST *> &path = interface->path(); if (path.isEmpty()) - return noResult(); + return; // find the largest enclosing Name const NameAST *enclosingName = 0; @@ -1826,14 +1842,14 @@ public: if (!innermostName) { innermostName = nameAst->asSimpleName(); if (!innermostName) - return noResult(); + return; } } else { break; } } if (!enclosingName || !enclosingName->name) - return noResult(); + return; // find the enclosing scope unsigned line, column; @@ -1841,18 +1857,16 @@ public: doc->translationUnit()->getTokenStartPosition(enclosingName->firstToken(), &line, &column); Scope *scope = doc->scopeAt(line, column); if (!scope) - return noResult(); + return; // check if the name resolves to something QList<LookupItem> existingResults = interface->context().lookup(enclosingName->name, scope); if (!existingResults.isEmpty()) - return noResult(); + return; - const QString &className = Overview()(innermostName->name); + const QString &className = Overview().prettyName(innermostName->name); if (className.isEmpty()) - return noResult(); - - QList<CppQuickFixOperation::Ptr> results; + return; // find the include paths QStringList includePaths; @@ -1905,7 +1919,7 @@ public: } if (!shortestInclude.isEmpty()) - results += CppQuickFixOperation::Ptr(new Operation(interface, 0, shortestInclude)); + result += CppQuickFixOperation::Ptr(new Operation(interface, 0, shortestInclude)); } // for QSomething, propose a <QSomething> include -- if such a class was in the locator @@ -1914,17 +1928,15 @@ public: && className.at(0) == QLatin1Char('Q') && className.at(1).isUpper()) { const QString include = QLatin1Char('<') + className + QLatin1Char('>'); - results += CppQuickFixOperation::Ptr(new Operation(interface, 1, include)); + result += CppQuickFixOperation::Ptr(new Operation(interface, 1, include)); } - - return results; } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, const QString &include) + Operation(const CppQuickFixInterface &interface, int priority, const QString &include) : CppQuickFixOperation(interface, priority) , m_include(include) { @@ -1932,9 +1944,11 @@ private: "Add #include %1").arg(m_include)); } - virtual void performChanges(const CppRefactoringFilePtr &file, - const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr file = refactoring.file(fileName()); + // find location of last include in file QList<Document::Include> includes = file->cppDocument()->includes(); unsigned lastIncludeLine = 0; @@ -1973,10 +1987,9 @@ public: }; public: - virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) + void match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList<AST *> path = interface->path(); - QList<CppQuickFixOperation::Ptr> result; ParameterDeclarationAST *paramDecl = 0; int index = path.size() - 1; @@ -1987,10 +2000,10 @@ public: } if (index < 1) - return result; + return; ParameterDeclarationClauseAST *paramDeclClause = path.at(index-1)->asParameterDeclarationClause(); - QTC_ASSERT(paramDeclClause && paramDeclClause->parameter_declaration_list, return result); + QTC_ASSERT(paramDeclClause && paramDeclClause->parameter_declaration_list, return); ParameterDeclarationListAST *paramListNode = paramDeclClause->parameter_declaration_list; ParameterDeclarationListAST *prevParamListNode = 0; @@ -2002,7 +2015,7 @@ public: } if (!paramListNode) - return result; + return; if (prevParamListNode) result.append(CppQuickFixOperation::Ptr(new Operation(interface, paramListNode->value, @@ -2010,15 +2023,13 @@ public: if (paramListNode->next) result.append(CppQuickFixOperation::Ptr(new Operation(interface, paramListNode->value, paramListNode->next->value, TargetNext))); - - return result; } private: class Operation: public CppQuickFixOperation { public: - Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, + Operation(const CppQuickFixInterface &interface, AST *currentParam, AST *targetParam, Target target) : CppQuickFixOperation(interface) @@ -2027,24 +2038,21 @@ private: { QString targetString; if (target == TargetPrevious) - { targetString = QApplication::translate("CppTools::QuickFix", "Switch with Previous Parameter"); - } else - { targetString = QApplication::translate("CppTools::QuickFix", "Switch with Next Parameter"); - } - setDescription(targetString); } - virtual void performChanges(const CppRefactoringFilePtr ¤tFile, - const CppRefactoringChanges &) + void perform() { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.file(fileName()); + int targetEndPos = currentFile->endOf(m_targetParam); - Utils::ChangeSet changes; + ChangeSet changes; changes.flip(currentFile->startOf(m_currentParam), currentFile->endOf(m_currentParam), currentFile->startOf(m_targetParam), targetEndPos); currentFile->setChangeSet(changes); diff --git a/src/plugins/cppeditor/cpptypehierarchy.cpp b/src/plugins/cppeditor/cpptypehierarchy.cpp index d673607b05..39d2705cf4 100644 --- a/src/plugins/cppeditor/cpptypehierarchy.cpp +++ b/src/plugins/cppeditor/cpptypehierarchy.cpp @@ -60,20 +60,20 @@ enum ItemRole { QStandardItem *itemForClass(const CppClass &cppClass) { QStandardItem *item = new QStandardItem; - item->setData(cppClass.name(), Qt::DisplayRole); - if (cppClass.name() != cppClass.qualifiedName()) - item->setData(cppClass.qualifiedName(), AnnotationRole); - item->setData(cppClass.icon(), Qt::DecorationRole); + item->setData(cppClass.name, Qt::DisplayRole); + if (cppClass.name != cppClass.qualifiedName) + item->setData(cppClass.qualifiedName, AnnotationRole); + item->setData(cppClass.icon, Qt::DecorationRole); QVariant link; - link.setValue(CPPEditorWidget::Link(cppClass.link())); + link.setValue(CPPEditorWidget::Link(cppClass.link)); item->setData(link, LinkRole); return item; } bool compareCppClassNames(const CppClass &c1, const CppClass &c2) { - const QString key1 = c1.name() + QLatin1String("::") + c1.qualifiedName(); - const QString key2 = c2.name() + QLatin1String("::") + c2.qualifiedName(); + const QString key1 = c1.name + QLatin1String("::") + c1.qualifiedName; + const QString key2 = c2.name + QLatin1String("::") + c2.qualifiedName; return key1 < key2; } @@ -98,8 +98,8 @@ public: void setup(CppClass *cppClass) { - setText(cppClass->name()); - m_link = cppClass->link(); + setText(cppClass->name); + m_link = cppClass->link; } private: @@ -192,15 +192,15 @@ void CppTypeHierarchyWidget::perform() } } -void CppTypeHierarchyWidget::buildHierarchy(const CppClass &cppClass, QStandardItem *parent, bool isRoot, HierarchyFunc func) +void CppTypeHierarchyWidget::buildHierarchy(const CppClass &cppClass, QStandardItem *parent, bool isRoot, const HierarchyMember member) { if (!isRoot) { QStandardItem *item = itemForClass(cppClass); parent->appendRow(item); parent = item; } - foreach (const CppClass &klass, sortClasses((cppClass.*func)())) - buildHierarchy(klass, parent, false, func); + foreach (const CppClass &klass, sortClasses(cppClass.*member)) + buildHierarchy(klass, parent, false, member); } void CppTypeHierarchyWidget::onItemClicked(const QModelIndex &index) diff --git a/src/plugins/cppeditor/cpptypehierarchy.h b/src/plugins/cppeditor/cpptypehierarchy.h index bdaeb4df56..f98e7d4ee9 100644 --- a/src/plugins/cppeditor/cpptypehierarchy.h +++ b/src/plugins/cppeditor/cpptypehierarchy.h @@ -75,8 +75,8 @@ private slots: void onItemClicked(const QModelIndex &index); private: - typedef const QList<CppClass> &(CppClass::* HierarchyFunc)() const; - void buildHierarchy(const CppClass &cppClass, QStandardItem *parent, bool isRoot, HierarchyFunc func); + typedef QList<CppClass> CppClass::*HierarchyMember; + void buildHierarchy(const CppClass &cppClass, QStandardItem *parent, bool isRoot, HierarchyMember member); CPPEditorWidget *m_cppEditor; Utils::NavigationTreeView *m_treeView; diff --git a/src/plugins/cpptools/ModelManagerInterface.h b/src/plugins/cpptools/ModelManagerInterface.h index d3761a0276..4bb9aac729 100644 --- a/src/plugins/cpptools/ModelManagerInterface.h +++ b/src/plugins/cpptools/ModelManagerInterface.h @@ -58,6 +58,7 @@ namespace CppTools { class CppCompletionAssistProvider; class CppHighlightingSupport; class CppHighlightingSupportFactory; + class CppIndexingSupport; } namespace CPlusPlus { @@ -106,7 +107,7 @@ public: ProjectInfo() { } - ProjectInfo(QWeakPointer<ProjectExplorer::Project> project) + ProjectInfo(QPointer<ProjectExplorer::Project> project) : m_project(project) { } @@ -119,7 +120,7 @@ public: bool isNull() const { return m_project.isNull(); } - QWeakPointer<ProjectExplorer::Project> project() const + QPointer<ProjectExplorer::Project> project() const { return m_project; } const QList<ProjectPart::Ptr> projectParts() const @@ -141,7 +142,7 @@ public: { return m_defines; } private: // attributes - QWeakPointer<ProjectExplorer::Project> m_project; + QPointer<ProjectExplorer::Project> m_project; QList<ProjectPart::Ptr> m_projectParts; // the attributes below are calculated from the project parts. QStringList m_includePaths; @@ -220,6 +221,8 @@ public: virtual CppTools::CppHighlightingSupport *highlightingSupport(Core::IEditor *editor) const = 0; virtual void setHighlightingSupportFactory(CppTools::CppHighlightingSupportFactory *highlightingFactory) = 0; + virtual void addIndexingSupport(CppTools::CppIndexingSupport *indexingSupport) = 0; + Q_SIGNALS: void documentUpdated(CPlusPlus::Document::Ptr doc); void sourceFilesRefreshed(const QStringList &files); diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp index dcd1358b94..13f06b87bb 100644 --- a/src/plugins/cpptools/cppchecksymbols.cpp +++ b/src/plugins/cpptools/cppchecksymbols.cpp @@ -509,9 +509,9 @@ bool CheckSymbols::visit(SimpleDeclarationAST *ast) // Add a diagnostic message if non-virtual function has override/final marker if ((_usages.back().kind != SemanticInfo::VirtualMethodUse)) { if (funTy->isOverride()) - warning(declrIdNameAST, "Only virtual methods can be marked `override'"); + warning(declrIdNameAST, QCoreApplication::translate("CPlusplus::CheckSymbols", "Only virtual methods can be marked `override'")); else if (funTy->isFinal()) - warning(declrIdNameAST, "Only virtual methods can be marked `final'"); + warning(declrIdNameAST, QCoreApplication::translate("CPlusPlus::CheckSymbols", "Only virtual methods can be marked `final'")); } } } @@ -662,13 +662,14 @@ bool CheckSymbols::visit(NewExpressionAST *ast) if (binding && nameAST) { int arguments = 0; if (ast->new_initializer) { - if (ExpressionAST *expr = ast->new_initializer->expression) { - while (BinaryExpressionAST *binExpr = expr->asBinaryExpression()) { - expr = binExpr->right_expression; - ++arguments; - } + ExpressionListAST *list = 0; + if (ExpressionListParenAST *exprListParen = ast->new_initializer->asExpressionListParen()) { + list = exprListParen->expression_list; + } else if (BracedInitializerAST *braceInit = ast->new_initializer->asBracedInitializer()) { + list = braceInit->expression_list; } - + for (ExpressionListAST *it = list; it; it = it->next) + ++arguments; } Scope *scope = enclosingScope(); @@ -712,7 +713,7 @@ void CheckSymbols::checkNamespace(NameAST *name) } const unsigned length = tokenAt(name->lastToken() - 1).end() - tokenAt(name->firstToken()).begin(); - warning(line, column, QCoreApplication::translate("CheckUndefinedSymbols", "Expected a namespace-name"), length); + warning(line, column, QCoreApplication::translate("CPlusPlus::CheckSymbols", "Expected a namespace-name"), length); } bool CheckSymbols::hasVirtualDestructor(Class *klass) const @@ -923,10 +924,17 @@ bool CheckSymbols::visit(MemInitializerAST *ast) } else if (maybeField(nameAST->name)) { maybeAddField(_context.lookup(nameAST->name, klass), nameAST); } else { - // It's a constructor + // It's a constructor, count the number of arguments unsigned arguments = 0; - for (ExpressionListAST *it = ast->expression_list; it; it = it->next) - ++arguments; + if (ast->expression) { + ExpressionListAST *expr_list = 0; + if (ExpressionListParenAST *parenExprList = ast->expression->asExpressionListParen()) + expr_list = parenExprList->expression_list; + else if (BracedInitializerAST *bracedInitList = ast->expression->asBracedInitializer()) + expr_list = bracedInitList->expression_list; + for (ExpressionListAST *it = expr_list; it; it = it->next) + ++arguments; + } maybeAddFunction(_context.lookup(nameAST->name, klass), nameAST, arguments); } @@ -936,7 +944,7 @@ bool CheckSymbols::visit(MemInitializerAST *ast) } } - accept(ast->expression_list); + accept(ast->expression); } return false; @@ -1280,9 +1288,9 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST // Add a diagnostic message if argument count does not match if (matchType == Match_TooFewArgs) - warning(line, column, "Too few arguments", length); + warning(line, column, QCoreApplication::translate("CplusPlus::CheckSymbols", "Too few arguments"), length); else if (matchType == Match_TooManyArgs) - warning(line, column, "Too many arguments", length); + warning(line, column, QCoreApplication::translate("CPlusPlus::CheckSymbols", "Too many arguments"), length); const Use use(line, column, length, kind); addUse(use); diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp index fa23705a42..a66024377f 100644 --- a/src/plugins/cpptools/cppclassesfilter.cpp +++ b/src/plugins/cpptools/cppclassesfilter.cpp @@ -35,7 +35,7 @@ using namespace CppTools::Internal; CppClassesFilter::CppClassesFilter(CppModelManager *manager) : CppLocatorFilter(manager) { - setShortcutString("c"); + setShortcutString(QLatin1String("c")); setIncludedByDefault(false); search.setSymbolsToSearchFor(SearchSymbols::Classes); diff --git a/src/plugins/cpptools/cppclassesfilter.h b/src/plugins/cpptools/cppclassesfilter.h index c01ce15734..95b66be69f 100644 --- a/src/plugins/cpptools/cppclassesfilter.h +++ b/src/plugins/cpptools/cppclassesfilter.h @@ -43,7 +43,7 @@ public: CppClassesFilter(Internal::CppModelManager *manager); ~CppClassesFilter(); - QString displayName() const { return tr("Classes"); } + QString displayName() const { return tr("C++ Classes"); } QString id() const { return QLatin1String("Classes"); } Priority priority() const { return Medium; } }; diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp index 2701d9b806..ecd6aa3ab3 100644 --- a/src/plugins/cpptools/cppcodeformatter.cpp +++ b/src/plugins/cpptools/cppcodeformatter.cpp @@ -299,6 +299,13 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) default: tryExpression(); break; } break; + case braceinit_open: + switch (kind) { + case T_RBRACE: leave(); break; + case T_RPAREN: leave(); continue; // recover? + default: tryExpression(); break; + } break; + case ternary_op: switch (kind) { case T_RPAREN: @@ -339,14 +346,16 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) case member_init: switch (kind) { - case T_LPAREN: enter(member_init_paren_open); break; - case T_RPAREN: leave(); break; case T_LBRACE: + case T_LPAREN: enter(member_init_nest_open); break; + case T_RBRACE: + case T_RPAREN: leave(); break; case T_SEMICOLON: leave(); continue; // try to recover } break; - case member_init_paren_open: + case member_init_nest_open: switch (kind) { + case T_RBRACE: case T_RPAREN: leave(); continue; case T_SEMICOLON: leave(); continue; // try to recover default: tryExpression(); break; @@ -764,6 +773,7 @@ bool CodeFormatter::tryExpression(bool alsoExpression) switch (kind) { case T_LPAREN: newState = arglist_open; break; case T_QUESTION: newState = ternary_op; break; + case T_LBRACE: newState = braceinit_open; break; case T_EQUAL: case T_AMPER_EQUAL: @@ -1234,7 +1244,7 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd case arglist_open: case condition_paren_open: - case member_init_paren_open: + case member_init_nest_open: if (!lastToken) *paddingDepth = nextTokenPosition-*indentDepth; else diff --git a/src/plugins/cpptools/cppcodeformatter.h b/src/plugins/cpptools/cppcodeformatter.h index 52e148420f..4e9e40e563 100644 --- a/src/plugins/cpptools/cppcodeformatter.h +++ b/src/plugins/cpptools/cppcodeformatter.h @@ -123,7 +123,7 @@ public: // must be public to make Q_GADGET introspection work member_init_open, // After ':' that starts a member initialization list. member_init_expected, // At the start and after every ',' in member_init_open member_init, // After an identifier in member_init_expected - member_init_paren_open, // After '(' in member_init. + member_init_nest_open, // After '(' or '{' in member_init. enum_start, // After 'enum' enum_open, // Brace that opens a enum declaration. @@ -167,6 +167,7 @@ public: // must be public to make Q_GADGET introspection work stream_op, // After a '<<' or '>>' in a context where it's likely a stream operator. stream_op_cont, // When finding another stream operator in stream_op ternary_op, // The ? : operator + braceinit_open, // after '{' in an expression context condition_open, // Start of a condition in 'if', 'while', entered after opening paren condition_paren_open, // After an lparen in a condition diff --git a/src/plugins/cpptools/cppcodegen_test.cpp b/src/plugins/cpptools/cppcodegen_test.cpp index 995a5d87f4..2dbbc9aa4a 100644 --- a/src/plugins/cpptools/cppcodegen_test.cpp +++ b/src/plugins/cpptools/cppcodegen_test.cpp @@ -68,7 +68,7 @@ void CppToolsPlugin::test_codegen_public_in_empty_class() "};\n" "\n"; - Document::Ptr doc = Document::create("public_in_empty_class"); + Document::Ptr doc = Document::create(QLatin1String("public_in_empty_class")); doc->setUtf8Source(src); doc->parse(); doc->check(); @@ -108,7 +108,7 @@ void CppToolsPlugin::test_codegen_public_in_nonempty_class() "};\n" // line 4 "\n"; - Document::Ptr doc = Document::create("public_in_nonempty_class"); + Document::Ptr doc = Document::create(QLatin1String("public_in_nonempty_class")); doc->setUtf8Source(src); doc->parse(); doc->check(); @@ -148,7 +148,7 @@ void CppToolsPlugin::test_codegen_public_before_protected() "};\n" "\n"; - Document::Ptr doc = Document::create("public_before_protected"); + Document::Ptr doc = Document::create(QLatin1String("public_before_protected")); doc->setUtf8Source(src); doc->parse(); doc->check(); @@ -189,7 +189,7 @@ void CppToolsPlugin::test_codegen_private_after_protected() "};\n" "\n"; - Document::Ptr doc = Document::create("private_after_protected"); + Document::Ptr doc = Document::create(QLatin1String("private_after_protected")); doc->setUtf8Source(src); doc->parse(); doc->check(); @@ -230,7 +230,7 @@ void CppToolsPlugin::test_codegen_protected_in_nonempty_class() "};\n" // line 4 "\n"; - Document::Ptr doc = Document::create("protected_in_nonempty_class"); + Document::Ptr doc = Document::create(QLatin1String("protected_in_nonempty_class")); doc->setUtf8Source(src); doc->parse(); doc->check(); @@ -271,7 +271,7 @@ void CppToolsPlugin::test_codegen_protected_between_public_and_private() "};\n" // line 5 "\n"; - Document::Ptr doc = Document::create("protected_betwee_public_and_private"); + Document::Ptr doc = Document::create(QLatin1String("protected_betwee_public_and_private")); doc->setUtf8Source(src); doc->parse(); doc->check(); @@ -332,7 +332,7 @@ void CppToolsPlugin::test_codegen_qtdesigner_integration() "\n" "#endif // MAINWINDOW_H\n"; - Document::Ptr doc = Document::create("qtdesigner_integration"); + Document::Ptr doc = Document::create(QLatin1String("qtdesigner_integration")); doc->setUtf8Source(src); doc->parse(); doc->check(); @@ -429,7 +429,7 @@ void CppToolsPlugin::test_codegen_definition_first_member() "};\n" "\n"; - const QByteArray dstText = QString( + const QByteArray dstText = QString::fromLatin1( "\n" "#include \"%1/file.h\"\n" // line 1 "int x;\n" @@ -498,7 +498,7 @@ void CppToolsPlugin::test_codegen_definition_last_member() "};\n" "\n"; - const QByteArray dstText = QString( + const QByteArray dstText = QString::fromLatin1( "\n" "#include \"%1/file.h\"\n" // line 1 "int x;\n" @@ -568,7 +568,7 @@ void CppToolsPlugin::test_codegen_definition_middle_member() "};\n" "\n"; - const QByteArray dstText = QString( + const QByteArray dstText = QString::fromLatin1( "\n" "#include \"%1/file.h\"\n" // line 1 "int x;\n" diff --git a/src/plugins/cpptools/cppcodestylepreferences.cpp b/src/plugins/cpptools/cppcodestylepreferences.cpp index 7ebe2e109c..2cb5da15c9 100644 --- a/src/plugins/cpptools/cppcodestylepreferences.cpp +++ b/src/plugins/cpptools/cppcodestylepreferences.cpp @@ -31,7 +31,7 @@ using namespace CppTools; -static const char *settingsSuffixKey = "CodeStyleSettings"; +static const char settingsSuffixKey[] = "CodeStyleSettings"; CppCodeStylePreferences::CppCodeStylePreferences(QObject *parent) : ICodeStylePreferences(parent) @@ -96,7 +96,7 @@ void CppCodeStylePreferences::slotCurrentValueChanged(const QVariant &value) QString CppCodeStylePreferences::settingsSuffix() const { - return settingsSuffixKey; + return QLatin1String(settingsSuffixKey); } void CppCodeStylePreferences::toMap(const QString &prefix, QVariantMap *map) const diff --git a/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp b/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp index bf11ee4380..f1cf45634c 100644 --- a/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp +++ b/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp @@ -91,14 +91,14 @@ CppCodeStylePreferencesFactory::CppCodeStylePreferencesFactory() { } -QString CppCodeStylePreferencesFactory::languageId() +Core::Id CppCodeStylePreferencesFactory::languageId() { return Constants::CPP_SETTINGS_ID; } QString CppCodeStylePreferencesFactory::displayName() { - return Constants::CPP_SETTINGS_NAME; + return QString::fromUtf8(Constants::CPP_SETTINGS_NAME); } TextEditor::ICodeStylePreferences *CppCodeStylePreferencesFactory::createCodeStyle() const diff --git a/src/plugins/cpptools/cppcodestylepreferencesfactory.h b/src/plugins/cpptools/cppcodestylepreferencesfactory.h index 23f45241e7..a5f9987200 100644 --- a/src/plugins/cpptools/cppcodestylepreferencesfactory.h +++ b/src/plugins/cpptools/cppcodestylepreferencesfactory.h @@ -39,14 +39,14 @@ class CppCodeStylePreferencesFactory : public TextEditor::ICodeStylePreferencesF public: CppCodeStylePreferencesFactory(); - virtual QString languageId(); - virtual QString displayName(); - virtual TextEditor::ICodeStylePreferences *createCodeStyle() const; - virtual QWidget *createEditor(TextEditor::ICodeStylePreferences *settings, - QWidget *parent) const; - virtual TextEditor::Indenter *createIndenter() const; - virtual TextEditor::ISnippetProvider *snippetProvider() const; - virtual QString previewText() const; + Core::Id languageId(); + QString displayName(); + TextEditor::ICodeStylePreferences *createCodeStyle() const; + QWidget *createEditor(TextEditor::ICodeStylePreferences *settings, + QWidget *parent) const; + TextEditor::Indenter *createIndenter() const; + TextEditor::ISnippetProvider *snippetProvider() const; + QString previewText() const; }; } // namespace CppTools diff --git a/src/plugins/cpptools/cppcodestylesettings.cpp b/src/plugins/cpptools/cppcodestylesettings.cpp index c2e7703d21..6295a9f22d 100644 --- a/src/plugins/cpptools/cppcodestylesettings.cpp +++ b/src/plugins/cpptools/cppcodestylesettings.cpp @@ -31,23 +31,23 @@ #include <utils/settingsutils.h> -static const char *groupPostfix = "IndentSettings"; -static const char *indentBlockBracesKey = "IndentBlockBraces"; -static const char *indentBlockBodyKey = "IndentBlockBody"; -static const char *indentClassBracesKey = "IndentClassBraces"; -static const char *indentEnumBracesKey = "IndentEnumBraces"; -static const char *indentNamespaceBracesKey = "IndentNamespaceBraces"; -static const char *indentNamespaceBodyKey = "IndentNamespaceBody"; -static const char *indentAccessSpecifiersKey = "IndentAccessSpecifiers"; -static const char *indentDeclarationsRelativeToAccessSpecifiersKey = "IndentDeclarationsRelativeToAccessSpecifiers"; -static const char *indentFunctionBodyKey = "IndentFunctionBody"; -static const char *indentFunctionBracesKey = "IndentFunctionBraces"; -static const char *indentSwitchLabelsKey = "IndentSwitchLabels"; -static const char *indentStatementsRelativeToSwitchLabelsKey = "IndentStatementsRelativeToSwitchLabels"; -static const char *indentBlocksRelativeToSwitchLabelsKey = "IndentBlocksRelativeToSwitchLabels"; -static const char *indentControlFlowRelativeToSwitchLabelsKey = "IndentControlFlowRelativeToSwitchLabels"; -static const char *extraPaddingForConditionsIfConfusingAlignKey = "ExtraPaddingForConditionsIfConfusingAlign"; -static const char *alignAssignmentsKey = "AlignAssignments"; +static const char groupPostfix[] = "IndentSettings"; +static const char indentBlockBracesKey[] = "IndentBlockBraces"; +static const char indentBlockBodyKey[] = "IndentBlockBody"; +static const char indentClassBracesKey[] = "IndentClassBraces"; +static const char indentEnumBracesKey[] = "IndentEnumBraces"; +static const char indentNamespaceBracesKey[] = "IndentNamespaceBraces"; +static const char indentNamespaceBodyKey[] = "IndentNamespaceBody"; +static const char indentAccessSpecifiersKey[] = "IndentAccessSpecifiers"; +static const char indentDeclarationsRelativeToAccessSpecifiersKey[] = "IndentDeclarationsRelativeToAccessSpecifiers"; +static const char indentFunctionBodyKey[] = "IndentFunctionBody"; +static const char indentFunctionBracesKey[] = "IndentFunctionBraces"; +static const char indentSwitchLabelsKey[] = "IndentSwitchLabels"; +static const char indentStatementsRelativeToSwitchLabelsKey[] = "IndentStatementsRelativeToSwitchLabels"; +static const char indentBlocksRelativeToSwitchLabelsKey[] = "IndentBlocksRelativeToSwitchLabels"; +static const char indentControlFlowRelativeToSwitchLabelsKey[] = "IndentControlFlowRelativeToSwitchLabels"; +static const char extraPaddingForConditionsIfConfusingAlignKey[] = "ExtraPaddingForConditionsIfConfusingAlign"; +static const char alignAssignmentsKey[] = "AlignAssignments"; using namespace CppTools; diff --git a/src/plugins/cpptools/cppcodestylesettingspage.cpp b/src/plugins/cpptools/cppcodestylesettingspage.cpp index 8029f64839..a3262d8015 100644 --- a/src/plugins/cpptools/cppcodestylesettingspage.cpp +++ b/src/plugins/cpptools/cppcodestylesettingspage.cpp @@ -216,9 +216,8 @@ CppCodeStylePreferencesWidget::CppCodeStylePreferencesWidget(QWidget *parent) m_previews << m_ui->previewTextEditGeneral << m_ui->previewTextEditContent << m_ui->previewTextEditBraces << m_ui->previewTextEditSwitch << m_ui->previewTextEditPadding; - for (int i = 0; i < m_previews.size(); ++i) { - m_previews[i]->setPlainText(defaultCodeStyleSnippets[i]); - } + for (int i = 0; i < m_previews.size(); ++i) + m_previews[i]->setPlainText(QLatin1String(defaultCodeStyleSnippets[i])); TextEditor::TextEditorSettings *textEditorSettings = TextEditorSettings::instance(); decorateEditors(textEditorSettings->fontSettings()); @@ -513,17 +512,17 @@ void CppCodeStyleSettingsPage::apply() if (originalCppCodeStylePreferences->codeStyleSettings() != m_pageCppCodeStylePreferences->codeStyleSettings()) { originalCppCodeStylePreferences->setCodeStyleSettings(m_pageCppCodeStylePreferences->codeStyleSettings()); if (s) - originalCppCodeStylePreferences->toSettings(CppTools::Constants::CPP_SETTINGS_ID, s); + originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); } if (originalCppCodeStylePreferences->tabSettings() != m_pageCppCodeStylePreferences->tabSettings()) { originalCppCodeStylePreferences->setTabSettings(m_pageCppCodeStylePreferences->tabSettings()); if (s) - originalCppCodeStylePreferences->toSettings(CppTools::Constants::CPP_SETTINGS_ID, s); + originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); } if (originalCppCodeStylePreferences->currentDelegate() != m_pageCppCodeStylePreferences->currentDelegate()) { originalCppCodeStylePreferences->setCurrentDelegate(m_pageCppCodeStylePreferences->currentDelegate()); if (s) - originalCppCodeStylePreferences->toSettings(CppTools::Constants::CPP_SETTINGS_ID, s); + originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); } } } diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 33dc05aa5c..5823ad702e 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -139,13 +139,13 @@ void CppToolsPlugin::test_completion_forward_declarations_present() setup(&data); Utils::ChangeSet change; - change.insert(data.pos, "Foo::Bar::"); + change.insert(data.pos, QLatin1String("Foo::Bar::")); QTextCursor cursor(data.doc); change.apply(&cursor); data.pos += 10; QStringList expected; - expected.append("Bar"); + expected.append(QLatin1String("Bar")); QStringList completions = getCompletions(data); @@ -172,24 +172,24 @@ void CppToolsPlugin::test_completion_basic_1() QStringList basicCompletions = getCompletions(data); - QVERIFY(!basicCompletions.contains("foo")); - QVERIFY(!basicCompletions.contains("m")); - QVERIFY(basicCompletions.contains("Foo")); - QVERIFY(basicCompletions.contains("func")); - QVERIFY(basicCompletions.contains("f")); + QVERIFY(!basicCompletions.contains(QLatin1String("foo"))); + QVERIFY(!basicCompletions.contains(QLatin1String("m"))); + QVERIFY(basicCompletions.contains(QLatin1String("Foo"))); + QVERIFY(basicCompletions.contains(QLatin1String("func"))); + QVERIFY(basicCompletions.contains(QLatin1String("f"))); Utils::ChangeSet change; - change.insert(data.pos, "f."); + change.insert(data.pos, QLatin1String("f.")); QTextCursor cursor(data.doc); change.apply(&cursor); data.pos += 2; QStringList memberCompletions = getCompletions(data); - QVERIFY(memberCompletions.contains("foo")); - QVERIFY(memberCompletions.contains("m")); - QVERIFY(!memberCompletions.contains("func")); - QVERIFY(!memberCompletions.contains("f")); + QVERIFY(memberCompletions.contains(QLatin1String("foo"))); + QVERIFY(memberCompletions.contains(QLatin1String("m"))); + QVERIFY(!memberCompletions.contains(QLatin1String("func"))); + QVERIFY(!memberCompletions.contains(QLatin1String("f"))); } void CppToolsPlugin::test_completion_template_1() @@ -213,19 +213,19 @@ void CppToolsPlugin::test_completion_template_1() setup(&data); Utils::ChangeSet change; - change.insert(data.pos, "Foo::"); + change.insert(data.pos, QLatin1String("Foo::")); QTextCursor cursor(data.doc); change.apply(&cursor); data.pos += 5; QStringList completions = getCompletions(data); - QVERIFY(completions.contains("Type")); - QVERIFY(completions.contains("foo")); - QVERIFY(completions.contains("m")); - QVERIFY(!completions.contains("T")); - QVERIFY(!completions.contains("f")); - QVERIFY(!completions.contains("func")); + QVERIFY(completions.contains(QLatin1String("Type"))); + QVERIFY(completions.contains(QLatin1String("foo"))); + QVERIFY(completions.contains(QLatin1String("m"))); + QVERIFY(!completions.contains(QLatin1String("T"))); + QVERIFY(!completions.contains(QLatin1String("f"))); + QVERIFY(!completions.contains(QLatin1String("func"))); } void CppToolsPlugin::test_completion_template_2() @@ -258,9 +258,9 @@ void CppToolsPlugin::test_completion_template_2() QStringList completions = getCompletions(data); QCOMPARE(completions.size(), 3); - QVERIFY(completions.contains("Tupple")); - QVERIFY(completions.contains("a")); - QVERIFY(completions.contains("b")); + QVERIFY(completions.contains(QLatin1String("Tupple"))); + QVERIFY(completions.contains(QLatin1String("a"))); + QVERIFY(completions.contains(QLatin1String("b"))); } void CppToolsPlugin::test_completion_template_3() @@ -293,9 +293,9 @@ void CppToolsPlugin::test_completion_template_3() QStringList completions = getCompletions(data); QCOMPARE(completions.size(), 3); - QVERIFY(completions.contains("Tupple")); - QVERIFY(completions.contains("a")); - QVERIFY(completions.contains("b")); + QVERIFY(completions.contains(QLatin1String("Tupple"))); + QVERIFY(completions.contains(QLatin1String("a"))); + QVERIFY(completions.contains(QLatin1String("b"))); } void CppToolsPlugin::test_completion_template_4() @@ -329,9 +329,9 @@ void CppToolsPlugin::test_completion_template_4() QStringList completions = getCompletions(data); QCOMPARE(completions.size(), 3); - QVERIFY(completions.contains("Tupple")); - QVERIFY(completions.contains("a")); - QVERIFY(completions.contains("b")); + QVERIFY(completions.contains(QLatin1String("Tupple"))); + QVERIFY(completions.contains(QLatin1String("a"))); + QVERIFY(completions.contains(QLatin1String("b"))); } void CppToolsPlugin::test_completion_template_5() @@ -365,9 +365,9 @@ void CppToolsPlugin::test_completion_template_5() QStringList completions = getCompletions(data); QCOMPARE(completions.size(), 3); - QVERIFY(completions.contains("Tupple")); - QVERIFY(completions.contains("a")); - QVERIFY(completions.contains("b")); + QVERIFY(completions.contains(QLatin1String("Tupple"))); + QVERIFY(completions.contains(QLatin1String("a"))); + QVERIFY(completions.contains(QLatin1String("b"))); } void CppToolsPlugin::test_completion_template_6() @@ -405,8 +405,8 @@ void CppToolsPlugin::test_completion_template_6() QStringList completions = getCompletions(data); QCOMPARE(completions.size(), 2); - QVERIFY(completions.contains("Item")); - QVERIFY(completions.contains("i")); + QVERIFY(completions.contains(QLatin1String("Item"))); + QVERIFY(completions.contains(QLatin1String("i"))); } void CppToolsPlugin::test_completion() @@ -419,7 +419,7 @@ void CppToolsPlugin::test_completion() setup(&data); Utils::ChangeSet change; - change.insert(data.pos, "c."); + change.insert(data.pos, QLatin1String("c.")); QTextCursor cursor(data.doc); change.apply(&cursor); data.pos += 2; @@ -453,10 +453,10 @@ void CppToolsPlugin::test_completion_template_as_base_data() " @\n" " // padding so we get the scope right\n" "}"; - completions.append("Data"); - completions.append("dataMember"); - completions.append("Other"); - completions.append("otherMember"); + completions.append(QLatin1String("Data")); + completions.append(QLatin1String("dataMember")); + completions.append(QLatin1String("Other")); + completions.append(QLatin1String("otherMember")); QTest::newRow("case: base as template directly") << code << completions; @@ -471,12 +471,12 @@ void CppToolsPlugin::test_completion_template_as_base_data() " @\n" " // padding so we get the scope right\n" "}"; - completions.append("Data"); - completions.append("dataMember"); - completions.append("Other"); - completions.append("otherMember"); - completions.append("More"); - completions.append("moreMember"); + completions.append(QLatin1String("Data")); + completions.append(QLatin1String("dataMember")); + completions.append(QLatin1String("Other")); + completions.append(QLatin1String("otherMember")); + completions.append(QLatin1String("More")); + completions.append(QLatin1String("moreMember")); QTest::newRow("case: base as class template") << code << completions; @@ -491,12 +491,12 @@ void CppToolsPlugin::test_completion_template_as_base_data() " @\n" " // padding so we get the scope right\n" "}"; - completions.append("Data"); - completions.append("dataMember"); - completions.append("Other"); - completions.append("otherMember"); - completions.append("More"); - completions.append("moreMember"); + completions.append(QLatin1String("Data")); + completions.append(QLatin1String("dataMember")); + completions.append(QLatin1String("Other")); + completions.append(QLatin1String("otherMember")); + completions.append(QLatin1String("More")); + completions.append(QLatin1String("moreMember")); QTest::newRow("case: base as globally qualified class template") << code << completions; @@ -513,12 +513,12 @@ void CppToolsPlugin::test_completion_template_as_base_data() " @\n" " // padding so we get the scope right\n" "}"; - completions.append("Data"); - completions.append("dataMember"); - completions.append("Other"); - completions.append("otherMember"); - completions.append("More"); - completions.append("moreMember"); + completions.append(QLatin1String("Data")); + completions.append(QLatin1String("dataMember")); + completions.append(QLatin1String("Other")); + completions.append(QLatin1String("otherMember")); + completions.append(QLatin1String("More")); + completions.append(QLatin1String("moreMember")); QTest::newRow("case: base as namespace qualified class template") << code << completions; @@ -535,10 +535,10 @@ void CppToolsPlugin::test_completion_template_as_base_data() " @\n" " // padding so we get the scope right\n" "}"; - completions.append("Data"); - completions.append("dataMember"); - completions.append("Final"); - completions.append("finalMember"); + completions.append(QLatin1String("Data")); + completions.append(QLatin1String("dataMember")); + completions.append(QLatin1String("Final")); + completions.append(QLatin1String("finalMember")); QTest::newRow("case: base as nested template name") << code << completions; @@ -555,10 +555,10 @@ void CppToolsPlugin::test_completion_template_as_base_data() " @\n" " // padding so we get the scope right\n" "}"; - completions.append("Data"); - completions.append("dataMember"); - completions.append("Final"); - completions.append("finalMember"); + completions.append(QLatin1String("Data")); + completions.append(QLatin1String("dataMember")); + completions.append(QLatin1String("Final")); + completions.append(QLatin1String("finalMember")); QTest::newRow("case: base as nested template name in non-template") << code << completions; completions.clear(); @@ -574,12 +574,12 @@ void CppToolsPlugin::test_completion_template_as_base_data() " @\n" " // padding so we get the scope right\n" "}"; - completions.append("Data"); - completions.append("dataMember"); - completions.append("Final"); - completions.append("finalMember"); - completions.append("Other"); - completions.append("otherMember"); + completions.append(QLatin1String("Data")); + completions.append(QLatin1String("dataMember")); + completions.append(QLatin1String("Final")); + completions.append(QLatin1String("finalMember")); + completions.append(QLatin1String("Other")); + completions.append(QLatin1String("otherMember")); QTest::newRow("case: base as template name in non-template") << code << completions; } @@ -611,10 +611,10 @@ void CppToolsPlugin::test_completion_use_global_identifier_as_base_class_data() "@\n" "// padding so we get the scope right\n"; - completions.append("int_global"); - completions.append("int_final"); - completions.append("Final"); - completions.append("Global"); + completions.append(QLatin1String("int_global")); + completions.append(QLatin1String("int_final")); + completions.append(QLatin1String("Final")); + completions.append(QLatin1String("Global")); QTest::newRow("case: derived as global and base as global") << code << completions; completions.clear(); @@ -637,10 +637,10 @@ void CppToolsPlugin::test_completion_use_global_identifier_as_base_class_data() "@\n" "// padding so we get the scope right\n"; - completions.append("int_global"); - completions.append("int_final"); - completions.append("Final"); - completions.append("Global"); + completions.append(QLatin1String("int_global")); + completions.append(QLatin1String("int_final")); + completions.append(QLatin1String("Final")); + completions.append(QLatin1String("Global")); QTest::newRow("case: derived is inside namespace, base as global") << code << completions; @@ -668,10 +668,10 @@ void CppToolsPlugin::test_completion_use_global_identifier_as_base_class_data() // "@\n" // "// padding so we get the scope right\n"; -// completions.append("int_global"); -// completions.append("int_final"); -// completions.append("Final"); -// completions.append("Global"); +// completions.append(QLatin1String("int_global")); +// completions.append(QLatin1String("int_final")); +// completions.append(QLatin1String("Final")); +// completions.append(QLatin1String("Global")); // QTest::newRow("case: derived is enclosed by template, base as global") // << code << completions; @@ -701,8 +701,8 @@ void CppToolsPlugin::test_completion_base_class_has_name_the_same_as_derived_dat "@\n" "// padding so we get the scope right\n"; - completions.append("int_a"); - completions.append("A"); + completions.append(QLatin1String("int_a")); + completions.append(QLatin1String("A")); QTest::newRow("case: base class is derived class") << code << completions; completions.clear(); @@ -720,8 +720,8 @@ void CppToolsPlugin::test_completion_base_class_has_name_the_same_as_derived_dat "@\n" "// padding so we get the scope right\n"; - completions.append("int_a"); - completions.append("A"); + completions.append(QLatin1String("int_a")); + completions.append(QLatin1String("A")); QTest::newRow("case: base class is derived class. class is in namespace") << code << completions; @@ -740,8 +740,8 @@ void CppToolsPlugin::test_completion_base_class_has_name_the_same_as_derived_dat "@\n" "// padding so we get the scope right\n"; - completions.append("int_a"); - completions.append("A"); + completions.append(QLatin1String("int_a")); + completions.append(QLatin1String("A")); QTest::newRow("case: base class is derived class. class is in namespace. " "use scope operator for base class") << code << completions; @@ -767,9 +767,9 @@ void CppToolsPlugin::test_completion_base_class_has_name_the_same_as_derived_dat "@\n" "// padding so we get the scope right\n"; - completions.append("int_ns1_a"); - completions.append("int_ns2_a"); - completions.append("A"); + completions.append(QLatin1String("int_ns1_a")); + completions.append(QLatin1String("int_ns2_a")); + completions.append(QLatin1String("A")); QTest::newRow("case: base class has the same name as derived but in different namespace") << code << completions; @@ -795,9 +795,9 @@ void CppToolsPlugin::test_completion_base_class_has_name_the_same_as_derived_dat "@\n" "// padding so we get the scope right\n"; - completions.append("int_enclosing_a"); - completions.append("int_ns2_a"); - completions.append("A"); + completions.append(QLatin1String("int_enclosing_a")); + completions.append(QLatin1String("int_ns2_a")); + completions.append(QLatin1String("A")); QTest::newRow("case: base class has the same name as derived(in namespace) " "but is nested by different class") << code << completions; @@ -823,9 +823,9 @@ void CppToolsPlugin::test_completion_base_class_has_name_the_same_as_derived_dat "@\n" "// padding so we get the scope right\n"; - completions.append("int_enclosing_base_a"); - completions.append("int_enclosing_derived_a"); - completions.append("A"); + completions.append(QLatin1String("int_enclosing_base_a")); + completions.append(QLatin1String("int_enclosing_derived_a")); + completions.append(QLatin1String("A")); QTest::newRow("case: base class has the same name as derived(nested) " "but is nested by different class") << code << completions; @@ -842,8 +842,8 @@ void CppToolsPlugin::test_completion_base_class_has_name_the_same_as_derived_dat "@\n" "// padding so we get the scope right\n"; - completions.append("int_a"); - completions.append("A"); + completions.append(QLatin1String("int_a")); + completions.append(QLatin1String("A")); QTest::newRow("case: base class is derived class. class is a template") << code << completions; @@ -851,7 +851,6 @@ void CppToolsPlugin::test_completion_base_class_has_name_the_same_as_derived_dat } - void CppToolsPlugin::test_completion_cyclic_inheritance() { test_completion(); @@ -873,10 +872,10 @@ void CppToolsPlugin::test_completion_cyclic_inheritance_data() "A c;\n" "@\n" ; - completions.append("A"); - completions.append("_a"); - completions.append("B"); - completions.append("_b"); + completions.append(QLatin1String("A")); + completions.append(QLatin1String("_a")); + completions.append(QLatin1String("B")); + completions.append(QLatin1String("_b")); QTest::newRow("case: direct cyclic inheritance") << code << completions; completions.clear(); @@ -889,12 +888,12 @@ void CppToolsPlugin::test_completion_cyclic_inheritance_data() "A c;\n" "@\n" ; - completions.append("A"); - completions.append("_a"); - completions.append("B"); - completions.append("_b"); - completions.append("C"); - completions.append("_c"); + completions.append(QLatin1String("A")); + completions.append(QLatin1String("_a")); + completions.append(QLatin1String("B")); + completions.append(QLatin1String("_b")); + completions.append(QLatin1String("C")); + completions.append(QLatin1String("_c")); QTest::newRow("case: indirect cyclic inheritance") << code << completions; completions.clear(); @@ -907,12 +906,12 @@ void CppToolsPlugin::test_completion_cyclic_inheritance_data() "A c;\n" "@\n" ; - completions.append("A"); - completions.append("_a"); - completions.append("B"); - completions.append("_b"); - completions.append("C"); - completions.append("_c"); + completions.append(QLatin1String("A")); + completions.append(QLatin1String("_a")); + completions.append(QLatin1String("B")); + completions.append(QLatin1String("_b")); + completions.append(QLatin1String("C")); + completions.append(QLatin1String("_c")); QTest::newRow("case: indirect cyclic inheritance") << code << completions; completions.clear(); @@ -931,11 +930,11 @@ void CppToolsPlugin::test_completion_cyclic_inheritance_data() "D<int, float> c;\n" "@\n" ; - completions.append("D"); - completions.append("_d_t"); - completions.append("_d_s"); - completions.append("C"); - completions.append("_c_t"); + completions.append(QLatin1String("D")); + completions.append(QLatin1String("_d_t")); + completions.append(QLatin1String("_d_s")); + completions.append(QLatin1String("C")); + completions.append(QLatin1String("_c_t")); QTest::newRow("case: direct cyclic inheritance with templates") << code << completions; @@ -959,13 +958,13 @@ void CppToolsPlugin::test_completion_cyclic_inheritance_data() "D<int, float> c;\n" "@\n" ; - completions.append("D"); - completions.append("_d_t"); - completions.append("_d_s"); - completions.append("C"); - completions.append("_c_t"); - completions.append("B"); - completions.append("_b_t"); + completions.append(QLatin1String("D")); + completions.append(QLatin1String("_d_t")); + completions.append(QLatin1String("_d_s")); + completions.append(QLatin1String("C")); + completions.append(QLatin1String("_c_t")); + completions.append(QLatin1String("B")); + completions.append(QLatin1String("_b_t")); QTest::newRow("case: indirect cyclic inheritance with templates") << code << completions; @@ -999,11 +998,57 @@ void CppToolsPlugin::test_completion_cyclic_inheritance_data() "Class<int> c;\n" "@\n" ; - completions.append("Class"); - completions.append("ClassRecurse"); - completions.append("class_t"); - completions.append("class_recurse_s"); - completions.append("class_recurse_t"); + completions.append(QLatin1String("Class")); + completions.append(QLatin1String("ClassRecurse")); + completions.append(QLatin1String("class_t")); + completions.append(QLatin1String("class_recurse_s")); + completions.append(QLatin1String("class_recurse_t")); QTest::newRow("case: direct cyclic inheritance with templates, more complex situation") << code << completions; } + +void CppToolsPlugin::test_completion_enclosing_template_class() +{ + test_completion(); +} + +void CppToolsPlugin::test_completion_enclosing_template_class_data() +{ + QTest::addColumn<QByteArray>("code"); + QTest::addColumn<QStringList>("expectedCompletions"); + + QByteArray code; + QStringList completions; + + code = "\n" + "template<typename T>\n" + "struct Enclosing\n" + "{\n" + " struct Nested { int int_nested; }; \n" + " int int_enclosing;\n" + "};\n" + "\n" + "Enclosing<int>::Nested c;" + "@\n"; + completions.append(QLatin1String("Nested")); + completions.append(QLatin1String("int_nested")); + QTest::newRow("case: nested class with enclosing template class") + << code << completions; + + completions.clear(); + + code = "\n" + "template<typename T>\n" + "struct Enclosing\n" + "{\n" + " template<typename T> struct Nested { int int_nested; }; \n" + " int int_enclosing;\n" + "};\n" + "\n" + "Enclosing<int>::Nested<int> c;" + "@\n"; + completions.append(QLatin1String("Nested")); + completions.append(QLatin1String("int_nested")); + QTest::newRow("case: nested template class with enclosing template class") + << code << completions; +} diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index 8dd911aac8..e9cfda9dda 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -401,20 +401,20 @@ private: QString CppFunctionHintModel::text(int index) const { Overview overview; - overview.setShowReturnTypes(true); - overview.setShowArgumentNames(true); - overview.setMarkedArgument(m_currentArg + 1); + overview.showReturnTypes = true; + overview.showArgumentNames = true; + overview.markedArgument = m_currentArg + 1; Function *f = m_functionSymbols.at(index); - const QString prettyMethod = overview(f->type(), f->name()); - const int begin = overview.markedArgumentBegin(); - const int end = overview.markedArgumentEnd(); + const QString prettyMethod = overview.prettyType(f->type(), f->name()); + const int begin = overview.markedArgumentBegin; + const int end = overview.markedArgumentEnd; QString hintText; hintText += Qt::escape(prettyMethod.left(begin)); - hintText += "<b>"; + hintText += QLatin1String("<b>"); hintText += Qt::escape(prettyMethod.mid(begin, end - begin)); - hintText += "</b>"; + hintText += QLatin1String("</b>"); hintText += Qt::escape(prettyMethod.mid(end)); return hintText; } @@ -536,8 +536,8 @@ public: : _item(0) , _symbol(0) { - overview.setShowReturnTypes(true); - overview.setShowArgumentNames(true); + overview.showReturnTypes = true; + overview.showArgumentNames = true; } BasicProposalItem *operator()(Symbol *symbol) @@ -648,7 +648,7 @@ Function *asFunctionOrTemplateFunctionType(FullySpecifiedType ty) CppCompletionAssistProcessor::CppCompletionAssistProcessor() : m_startPosition(-1) , m_objcEnabled(true) - , m_snippetCollector(CppEditor::Constants::CPP_SNIPPETS_GROUP_ID, + , m_snippetCollector(QLatin1String(CppEditor::Constants::CPP_SNIPPETS_GROUP_ID), QIcon(QLatin1String(":/texteditor/images/snippet.png"))) , preprocessorCompletions(QStringList() << QLatin1String("define") @@ -1068,6 +1068,18 @@ bool CppCompletionAssistProcessor::tryObjCCompletion() return true; } +namespace { +enum CompletionOrder { + // default order is 0 + FunctionArgumentsOrder = 2, + FunctionLocalsOrder = 2, // includes local types + PublicClassMemberOrder = 1, + InjectedClassNameOrder = -1, + MacrosOrder = -2, + KeywordsOrder = -2 +}; +} + void CppCompletionAssistProcessor::addCompletionItem(const QString &text, const QIcon &icon, int order, @@ -1081,12 +1093,14 @@ void CppCompletionAssistProcessor::addCompletionItem(const QString &text, m_completions.append(item); } -void CppCompletionAssistProcessor::addCompletionItem(CPlusPlus::Symbol *symbol) +void CppCompletionAssistProcessor::addCompletionItem(CPlusPlus::Symbol *symbol, + int order) { ConvertToCompletionItem toCompletionItem; BasicProposalItem *item = toCompletionItem(symbol); if (item) { item->setIcon(m_icons.iconForSymbol(symbol)); + item->setOrder(order); m_completions.append(item); } } @@ -1116,17 +1130,17 @@ void CppCompletionAssistProcessor::completeObjCMsgSend(CPlusPlus::ClassOrNamespa if (i > 0) text += QLatin1Char(' '); Symbol *arg = method->argumentAt(i); - text += selectorName->nameAt(i)->identifier()->chars(); + text += QString::fromUtf8(selectorName->nameAt(i)->identifier()->chars()); text += QLatin1Char(':'); text += TextEditor::Snippet::kVariableDelimiter; text += QLatin1Char('('); - text += oo(arg->type()); + text += oo.prettyType(arg->type()); text += QLatin1Char(')'); - text += oo(arg->name()); + text += oo.prettyName(arg->name()); text += TextEditor::Snippet::kVariableDelimiter; } } else { - text = selectorName->identifier()->chars(); + text = QString::fromUtf8(selectorName->identifier()->chars()); } data = text; @@ -1223,7 +1237,7 @@ bool CppCompletionAssistProcessor::objcKeywordsWanted() const QString fileName = document->fileName(); const Core::MimeDatabase *mdb = Core::ICore::mimeDatabase(); - return mdb->findByFile(fileName).type() == CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE; + return mdb->findByFile(fileName).type() == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE); } int CppCompletionAssistProcessor::startCompletionInternal(const QString fileName, @@ -1376,12 +1390,12 @@ void CppCompletionAssistProcessor::globalCompletion(CPlusPlus::Scope *currentSco for (Scope *scope = currentScope; scope; scope = scope->enclosingScope()) { if (scope->isBlock()) { for (unsigned i = 0; i < scope->memberCount(); ++i) { - addCompletionItem(scope->memberAt(i)); + addCompletionItem(scope->memberAt(i), FunctionLocalsOrder); } } else if (scope->isFunction()) { Function *fun = scope->asFunction(); for (unsigned i = 0; i < fun->argumentCount(); ++i) { - addCompletionItem(fun->argumentAt(i)); + addCompletionItem(fun->argumentAt(i), FunctionArgumentsOrder); } break; } else { @@ -1393,10 +1407,10 @@ void CppCompletionAssistProcessor::globalCompletion(CPlusPlus::Scope *currentSco const QList<Symbol *> symbols = currentBinding->symbols(); if (! symbols.isEmpty()) { - if (symbols.first()->isNamespace()) - completeNamespace(currentBinding); - else + if (symbols.first()->isClass()) completeClass(currentBinding); + else + completeNamespace(currentBinding); } } @@ -1423,7 +1437,7 @@ bool CppCompletionAssistProcessor::completeMember(const QList<CPlusPlus::LookupI m_model->m_completionOperator, &m_model->m_replaceDotForArrow)) { if (binding) - completeClass(binding, /*static lookup = */ false); + completeClass(binding, /*static lookup = */ true); return ! m_completions.isEmpty(); } @@ -1466,6 +1480,12 @@ bool CppCompletionAssistProcessor::completeScope(const QList<CPlusPlus::LookupIt completeClass(b); break; } + + } else if (Enum *e = ty->asEnumType()) { + if (ClassOrNamespace *b = context.lookupType(e)) { + completeNamespace(b); + break; + } } } @@ -1490,11 +1510,11 @@ void CppCompletionAssistProcessor::completeNamespace(CPlusPlus::ClassOrNamespace QSet<Scope *> scopesVisited; foreach (Symbol *bb, binding->symbols()) { - if (Namespace *ns = bb->asNamespace()) - scopesToVisit.append(ns); + if (Scope *scope = bb->asScope()) + scopesToVisit.append(scope); } - foreach (Enum *e, binding->enums()) { + foreach (Enum *e, binding->unscopedEnums()) { scopesToVisit.append(e); } @@ -1535,7 +1555,7 @@ void CppCompletionAssistProcessor::completeClass(CPlusPlus::ClassOrNamespace *b, scopesToVisit.append(k); } - foreach (Enum *e, binding->enums()) + foreach (Enum *e, binding->unscopedEnums()) scopesToVisit.append(e); while (! scopesToVisit.isEmpty()) { @@ -1545,7 +1565,8 @@ void CppCompletionAssistProcessor::completeClass(CPlusPlus::ClassOrNamespace *b, scopesVisited.insert(scope); - addCompletionItem(scope); // add a completion item for the injected class name. + if (staticLookup) + addCompletionItem(scope, InjectedClassNameOrder); // add a completion item for the injected class name. for (Scope::iterator it = scope->firstMember(); it != scope->lastMember(); ++it) { Symbol *member = *it; @@ -1559,7 +1580,11 @@ void CppCompletionAssistProcessor::completeClass(CPlusPlus::ClassOrNamespace *b, continue; } - addCompletionItem(member); + if (member->isPublic()) { + addCompletionItem(member, PublicClassMemberOrder); + } else { + addCompletionItem(member); + } } } } @@ -1574,9 +1599,9 @@ bool CppCompletionAssistProcessor::completeQtMethod(const QList<CPlusPlus::Looku ConvertToCompletionItem toCompletionItem; Overview o; - o.setShowReturnTypes(false); - o.setShowArgumentNames(false); - o.setShowFunctionSignatures(true); + o.showReturnTypes = false; + o.showArgumentNames = false; + o.showFunctionSignatures = true; QSet<QString> signatures; foreach (const LookupItem &p, results) { @@ -1678,7 +1703,7 @@ void CppCompletionAssistProcessor::addKeywords() // keyword completion items. for (int i = T_FIRST_KEYWORD; i < keywordLimit; ++i) - addCompletionItem(QLatin1String(Token::name(i)), m_icons.keywordIcon()); + addCompletionItem(QLatin1String(Token::name(i)), m_icons.keywordIcon(), KeywordsOrder); } void CppCompletionAssistProcessor::addMacros(const QString &fileName, const CPlusPlus::Snapshot &snapshot) @@ -1689,7 +1714,7 @@ void CppCompletionAssistProcessor::addMacros(const QString &fileName, const CPlu addMacros_helper(snapshot, fileName, &processed, &definedMacros); foreach (const QString ¯oName, definedMacros) - addCompletionItem(macroName, m_icons.macroIcon()); + addCompletionItem(macroName, m_icons.macroIcon(), MacrosOrder); } void CppCompletionAssistProcessor::addMacros_helper(const CPlusPlus::Snapshot &snapshot, @@ -1838,7 +1863,7 @@ bool CppCompletionAssistProcessor::completeConstructorOrFunction(const QList<CPl int lineStartToken = bs.startOfLine(startToken); // make sure the required tokens are actually available bs.LA(startToken - lineStartToken); - QString possibleDecl = bs.mid(lineStartToken).trimmed().append("();"); + QString possibleDecl = bs.mid(lineStartToken).trimmed().append(QLatin1String("();")); Document::Ptr doc = Document::create(QLatin1String("<completion>")); doc->setUtf8Source(possibleDecl.toLatin1()); @@ -1882,13 +1907,13 @@ bool CppCompletionAssistProcessor::completeConstructorOrFunction(const QList<CPl // set up signature autocompletion foreach (Function *f, functions) { Overview overview; - overview.setShowArgumentNames(true); - overview.setShowDefaultArguments(false); + overview.showArgumentNames = true; + overview.showDefaultArguments = false; const FullySpecifiedType localTy = rewriteType(f->type(), &env, control); // gets: "parameter list) cv-spec", - QString completion = overview(localTy).mid(1); + QString completion = overview.prettyType(localTy).mid(1); addCompletionItem(completion, QIcon(), 0, QVariant::fromValue(CompleteFunctionDeclaration(f))); diff --git a/src/plugins/cpptools/cppcompletionassist.h b/src/plugins/cpptools/cppcompletionassist.h index 17f6d74896..f49a161128 100644 --- a/src/plugins/cpptools/cppcompletionassist.h +++ b/src/plugins/cpptools/cppcompletionassist.h @@ -120,7 +120,8 @@ private: const QIcon &icon = QIcon(), int order = 0, const QVariant &data = QVariant()); - void addCompletionItem(CPlusPlus::Symbol *symbol); + void addCompletionItem(CPlusPlus::Symbol *symbol, + int order = 0); void addSnippets(); void addKeywords(); void addMacros(const QString &fileName, const CPlusPlus::Snapshot &snapshot); diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp index 31ffc140c2..d06fe6a839 100644 --- a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp +++ b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp @@ -68,7 +68,7 @@ QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(QFutureInterfac QRegExp regexp(asterisk + entry + asterisk, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.isValid()) return goodEntries; - bool hasWildcard = (entry.contains(asterisk) || entry.contains('?')); + bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?'))); if (m_currentFileName.isEmpty()) return goodEntries; diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.h b/src/plugins/cpptools/cppcurrentdocumentfilter.h index d59b298074..6e87ac265a 100644 --- a/src/plugins/cpptools/cppcurrentdocumentfilter.h +++ b/src/plugins/cpptools/cppcurrentdocumentfilter.h @@ -50,7 +50,7 @@ public: CppCurrentDocumentFilter(CppModelManager *manager, Core::EditorManager *editorManager); ~CppCurrentDocumentFilter() {} - QString displayName() const { return tr("Methods in Current Document"); } + QString displayName() const { return tr("C++ Methods in Current Document"); } QString id() const { return QLatin1String("Methods in current Document"); } Priority priority() const { return Medium; } QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry); diff --git a/src/plugins/cpptools/cppfilesettingspage.cpp b/src/plugins/cpptools/cppfilesettingspage.cpp index da434d2d17..66213189ca 100644 --- a/src/plugins/cpptools/cppfilesettingspage.cpp +++ b/src/plugins/cpptools/cppfilesettingspage.cpp @@ -38,6 +38,7 @@ #include <extensionsystem/pluginmanager.h> +#include <utils/environment.h> #include <utils/fileutils.h> #include <QSettings> @@ -149,11 +150,7 @@ static bool keyWordReplacement(const QString &keyWord, return true; } if (keyWord == QLatin1String("%USER%")) { -#ifdef Q_OS_WIN - *value = QString::fromLocal8Bit(qgetenv("USERNAME")); -#else - *value = QString::fromLocal8Bit(qgetenv("USER")); -#endif + *value = Utils::Environment::systemEnvironment().userName(); return true; } // Environment variables (for example '%$EMAIL%'). diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 6779fe2c9d..173ed20222 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -250,7 +250,7 @@ void CppFindReferences::findUsages(CPlusPlus::Symbol *symbol, Overview overview; Find::SearchResult *search = Find::SearchResultWindow::instance()->startNewSearch(tr("C++ Usages:"), QString(), - overview(context.fullyQualifiedName(symbol)), + overview.prettyName(context.fullyQualifiedName(symbol)), replace ? Find::SearchResultWindow::SearchAndReplace : Find::SearchResultWindow::SearchOnly, QLatin1String("CppEditor")); @@ -297,7 +297,7 @@ void CppFindReferences::findAll_helper(Find::SearchResult *search) Core::ProgressManager *progressManager = Core::ICore::progressManager(); Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching"), - CppTools::Constants::TASK_SEARCH); + QLatin1String(CppTools::Constants::TASK_SEARCH)); connect(progress, SIGNAL(clicked()), search, SLOT(popup())); } @@ -410,7 +410,7 @@ namespace { class SymbolFinder : public SymbolVisitor { public: - SymbolFinder(const QStringList &uid) : m_uid(uid), m_index(0), m_result(0) { } + SymbolFinder(const QList<QByteArray> &uid) : m_uid(uid), m_index(0), m_result(0) { } Symbol *result() const { return m_result; } bool preVisit(Symbol *symbol) @@ -439,7 +439,7 @@ public: } private: - QStringList m_uid; + QList<QByteArray> m_uid; int m_index; Symbol *m_result; }; @@ -461,7 +461,7 @@ bool CppFindReferences::findSymbol(CppFindReferencesParameters *parameters, doc->check(); // construct id of old symbol - QStringList uid; + QList<QByteArray> uid; Symbol *current = parameters->symbol; do { uid.prepend(idForSymbol(current)); @@ -573,22 +573,21 @@ _Lrestart: const Macro &useMacro = use.macro(); if (useMacro.fileName() == macro.fileName()) { // Check if this is a match, but possibly against an outdated document. + if (source.isEmpty()) + source = getSource(fileName, workingCopy); + if (macro.fileRevision() > useMacro.fileRevision()) { // yes, it is outdated, so re-preprocess and start from scratch for this file. - source = getSource(fileName, workingCopy).toLatin1(); doc = snapshot.preprocessedDocument(source, fileName); goto _Lrestart; } - } - if (useMacro.fileName() == macro.fileName() && macro.name() == useMacro.name()) { - if (source.isEmpty()) - source = getSource(fileName, workingCopy); - - unsigned lineStart; - const QString &lineSource = matchingLine(use.begin(), source, &lineStart); - usages.append(Usage(fileName, lineSource, use.beginLine(), - use.begin() - lineStart, useMacro.name().length())); + if (macro.name() == useMacro.name()) { + unsigned lineStart; + const QString &lineSource = matchingLine(use.begin(), source, &lineStart); + usages.append(Usage(fileName, lineSource, use.beginLine(), + use.begin() - lineStart, useMacro.name().length())); + } } } @@ -650,7 +649,7 @@ void CppFindReferences::findMacroUses(const Macro ¯o, const QString &replace Find::SearchResult *search = Find::SearchResultWindow::instance()->startNewSearch( tr("C++ Macro Usages:"), QString(), - macro.name(), + QString::fromUtf8(macro.name()), replace ? Find::SearchResultWindow::SearchAndReplace : Find::SearchResultWindow::SearchOnly, QLatin1String("CppEditor")); @@ -684,13 +683,13 @@ void CppFindReferences::findMacroUses(const Macro ¯o, const QString &replace Core::ProgressManager *progressManager = Core::ICore::progressManager(); Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching"), - CppTools::Constants::TASK_SEARCH); + QLatin1String(CppTools::Constants::TASK_SEARCH)); connect(progress, SIGNAL(clicked()), search, SLOT(popup())); } void CppFindReferences::renameMacroUses(const Macro ¯o, const QString &replacement) { - const QString textToReplace = replacement.isEmpty() ? macro.name() : replacement; + const QString textToReplace = replacement.isEmpty() ? QString::fromUtf8(macro.name()) : replacement; findMacroUses(macro, textToReplace, true); } diff --git a/src/plugins/cpptools/cppfunctionsfilter.h b/src/plugins/cpptools/cppfunctionsfilter.h index 8f91d2b364..4d04edcf22 100644 --- a/src/plugins/cpptools/cppfunctionsfilter.h +++ b/src/plugins/cpptools/cppfunctionsfilter.h @@ -30,7 +30,7 @@ #ifndef CPPFUNCTIONSFILTER_H #define CPPFUNCTIONSFILTER_H -#include <cpplocatorfilter.h> +#include "cpplocatorfilter.h" namespace CppTools { namespace Internal { @@ -43,7 +43,7 @@ public: CppFunctionsFilter(CppModelManager *manager); ~CppFunctionsFilter(); - QString displayName() const { return tr("Methods and Functions"); } + QString displayName() const { return tr("C++ Methods and Functions"); } QString id() const { return QLatin1String("Methods"); } Priority priority() const { return Medium; } }; diff --git a/src/plugins/cpptools/cppindexingsupport.cpp b/src/plugins/cpptools/cppindexingsupport.cpp new file mode 100644 index 0000000000..475e9aefff --- /dev/null +++ b/src/plugins/cpptools/cppindexingsupport.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + + +#include "cppindexingsupport.h" + +namespace CppTools { + +CppIndexingSupport::~CppIndexingSupport() +{ +} + +} // namespace CppTools diff --git a/src/plugins/qt4projectmanager/profilekeywords.h b/src/plugins/cpptools/cppindexingsupport.h index 0aed9caebf..0740ace5e4 100644 --- a/src/plugins/qt4projectmanager/profilekeywords.h +++ b/src/plugins/cpptools/cppindexingsupport.h @@ -27,27 +27,24 @@ ** ****************************************************************************/ -#ifndef PROFILEKEYWORDS_H -#define PROFILEKEYWORDS_H +#ifndef CPPTOOLS_CPPINDEXINGSUPPORT_H +#define CPPTOOLS_CPPINDEXINGSUPPORT_H -#include <QStringList> +#include "cpptools_global.h" -namespace Qt4ProjectManager { +#include <QFuture> +#include <QStringList> -namespace Internal { +namespace CppTools { -class ProFileKeywords +class CPPTOOLS_EXPORT CppIndexingSupport { public: - static QStringList variables(); - static QStringList functions(); - static bool isVariable(const QString &word); - static bool isFunction(const QString &word); -private: - ProFileKeywords(); + virtual ~CppIndexingSupport() = 0; + + virtual QFuture<void> refreshSourceFiles(const QStringList &sourceFiles) = 0; }; -} // namespace Internal -} // namespace Qt4ProjectManager +} // namespace CppTools -#endif // PROFILEKEYWORDS_H +#endif // CPPTOOLS_CPPINDEXINGSUPPORT_H diff --git a/src/plugins/cpptools/cpplocalsymbols.cpp b/src/plugins/cpptools/cpplocalsymbols.cpp index 026c0274cb..8522196957 100644 --- a/src/plugins/cpptools/cpplocalsymbols.cpp +++ b/src/plugins/cpptools/cpplocalsymbols.cpp @@ -127,6 +127,11 @@ protected: return true; } + virtual bool visit(CaptureAST *ast) + { + return checkLocalUse(ast->identifier, ast->firstToken()); + } + virtual bool visit(IdExpressionAST *ast) { return checkLocalUse(ast->name, ast->firstToken()); diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp index 8d8b7e92ac..99a0e36591 100644 --- a/src/plugins/cpptools/cpplocatorfilter.cpp +++ b/src/plugins/cpptools/cpplocatorfilter.cpp @@ -32,10 +32,12 @@ #include <texteditor/itexteditor.h> #include <texteditor/basetexteditor.h> +#include <utils/fileutils.h> #include <QStringMatcher> using namespace CppTools::Internal; +using namespace Utils; CppLocatorFilter::CppLocatorFilter(CppModelManager *manager) : m_manager(manager), @@ -86,7 +88,7 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locato QRegExp regexp(asterisk + entry+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.isValid()) return goodEntries; - bool hasWildcard = (entry.contains(asterisk) || entry.contains('?')); + bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?'))); QHashIterator<QString, QList<ModelItemInfo> > it(m_searchList); while (it.hasNext()) { @@ -102,10 +104,12 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locato QVariant id = qVariantFromValue(info); Locator::FilterEntry filterEntry(this, info.symbolName, id, info.icon); - if (! info.symbolType.isEmpty()) + if (! info.symbolType.isEmpty()) { filterEntry.extraInfo = info.symbolType; - else - filterEntry.extraInfo = info.fileName; + } else { + filterEntry.extraInfo = FileUtils::shortNativePath( + FileName::fromString(info.fileName)); + } if (info.symbolName.startsWith(entry)) betterEntries.append(filterEntry); diff --git a/src/plugins/cpptools/cpplocatorfilter.h b/src/plugins/cpptools/cpplocatorfilter.h index f6e83e2488..ff7a8ae8c3 100644 --- a/src/plugins/cpptools/cpplocatorfilter.h +++ b/src/plugins/cpptools/cpplocatorfilter.h @@ -45,7 +45,7 @@ public: CppLocatorFilter(CppModelManager *manager); ~CppLocatorFilter(); - QString displayName() const { return tr("Classes and Methods"); } + QString displayName() const { return tr("C++ Classes and Methods"); } QString id() const { return QLatin1String("Classes and Methods"); } Priority priority() const { return Medium; } QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 6942c75583..b01c8ae420 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -34,33 +34,29 @@ #include "cppcompletionassist.h" #include "cpphighlightingsupport.h" #include "cpphighlightingsupportinternal.h" +#include "cppindexingsupport.h" #include "abstracteditorsupport.h" -#ifndef ICHECK_BUILD -# include "cpptoolsconstants.h" -# include "cpptoolseditorsupport.h" -# include "cppfindreferences.h" -#endif +#include "cpptoolsconstants.h" +#include "cpptoolseditorsupport.h" +#include "cppfindreferences.h" #include <functional> #include <QtConcurrentRun> -#ifndef ICHECK_BUILD -# include <QFutureSynchronizer> -# include <utils/runextensions.h> -# include <texteditor/itexteditor.h> -# include <texteditor/basetexteditor.h> -# include <projectexplorer/project.h> -# include <projectexplorer/projectexplorer.h> -# include <projectexplorer/projectexplorerconstants.h> -# include <projectexplorer/session.h> -# include <coreplugin/icore.h> -# include <coreplugin/mimedatabase.h> -# include <coreplugin/editormanager/editormanager.h> -# include <coreplugin/progressmanager/progressmanager.h> -# include <extensionsystem/pluginmanager.h> -#else -# include <QDir> -#endif - +#include <QFutureSynchronizer> +#include <utils/runextensions.h> +#include <texteditor/itexteditor.h> +#include <texteditor/basetexteditor.h> +#include <projectexplorer/project.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/session.h> +#include <coreplugin/icore.h> +#include <coreplugin/mimedatabase.h> +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/progressmanager/progressmanager.h> +#include <extensionsystem/pluginmanager.h> + +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <TranslationUnit.h> @@ -197,7 +193,6 @@ static const char pp_configuration[] = "#define __inline inline\n" "#define __forceinline inline\n"; -#ifndef ICHECK_BUILD CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager, bool dumpFileNameWhileParsing) : snapshot(modelManager->snapshot()), m_modelManager(modelManager), @@ -208,16 +203,6 @@ CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager, bool du preprocess.setKeepComments(true); } -#else - -CppPreprocessor::CppPreprocessor(QPointer<CPlusPlus::ParseManager> modelManager) - : preprocess(this, &env), - m_dumpFileNameWhileParsing(false), - m_revision(0) -{ -} -#endif - CppPreprocessor::~CppPreprocessor() { } @@ -234,23 +219,23 @@ void CppPreprocessor::setIncludePaths(const QStringList &includePaths) for (int i = 0; i < includePaths.size(); ++i) { const QString &path = includePaths.at(i); -#ifdef Q_OS_DARWIN - if (i + 1 < includePaths.size() && path.endsWith(QLatin1String(".framework/Headers"))) { - const QFileInfo pathInfo(path); - const QFileInfo frameworkFileInfo(pathInfo.path()); - const QString frameworkName = frameworkFileInfo.baseName(); - - const QFileInfo nextIncludePath = includePaths.at(i + 1); - if (nextIncludePath.fileName() == frameworkName) { - // We got a QtXXX.framework/Headers followed by $QTDIR/include/QtXXX. - // In this case we prefer to include files from $QTDIR/include/QtXXX. - continue; + if (Utils::HostOsInfo::isMacHost()) { + if (i + 1 < includePaths.size() && path.endsWith(QLatin1String(".framework/Headers"))) { + const QFileInfo pathInfo(path); + const QFileInfo frameworkFileInfo(pathInfo.path()); + const QString frameworkName = frameworkFileInfo.baseName(); + + const QFileInfo nextIncludePath = includePaths.at(i + 1); + if (nextIncludePath.fileName() == frameworkName) { + // We got a QtXXX.framework/Headers followed by $QTDIR/include/QtXXX. + // In this case we prefer to include files from $QTDIR/include/QtXXX. + continue; + } } + m_includePaths.append(path); + } else { + m_includePaths.append(path); } - m_includePaths.append(path); -#else - m_includePaths.append(path); -#endif } } @@ -297,7 +282,6 @@ void CppPreprocessor::setProjectFiles(const QStringList &files) void CppPreprocessor::setTodo(const QStringList &files) { m_todo = QSet<QString>::fromList(files); } -#ifndef ICHECK_BUILD namespace { class Process: public std::unary_function<Document::Ptr, void> { @@ -326,13 +310,12 @@ public: _doc->check(_mode); if (_modelManager) - _modelManager->emitDocumentUpdated(_doc); // ### TODO: compress + _modelManager->emitDocumentUpdated(_doc); _doc->releaseSourceAndAST(); } }; } // end of anonymous namespace -#endif void CppPreprocessor::run(const QString &fileName) { @@ -646,21 +629,11 @@ void CppPreprocessor::sourceNeeded(unsigned line, QString &fileName, IncludeType snapshot.insert(doc); m_todo.remove(fileName); -#ifndef ICHECK_BUILD Process process(m_modelManager, doc, snapshot, m_workingCopy); process(); (void) switchDocument(previousDoc); -#else - doc->releaseSource(); - Document::CheckMode mode = Document::FastCheck; - mode = Document::FullCheck; - doc->parse(); - doc->check(mode); - - (void) switchDocument(previousDoc); -#endif } Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc) @@ -670,7 +643,6 @@ Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc) return previousDoc; } -#ifndef ICHECK_BUILD void CppModelManager::updateModifiedSourceFiles() { const Snapshot snapshot = this->snapshot(); @@ -690,12 +662,143 @@ void CppModelManager::updateModifiedSourceFiles() updateSourceFiles(sourceFiles); } -CppModelManager *CppModelManager::instance() -{ - // TODO this is pretty stupid. use regular singleton pattern. - return ExtensionSystem::PluginManager::getObject<CppModelManager>(); -} +namespace { + +class IndexingSupport: public CppIndexingSupport { +public: + typedef CppModelManagerInterface::WorkingCopy WorkingCopy; + +public: + IndexingSupport() + : m_revision(0) + { + m_synchronizer.setCancelOnWait(true); + m_dumpFileNameWhileParsing = !qgetenv("QTCREATOR_DUMP_FILENAME_WHILE_PARSING").isNull(); + } + + ~IndexingSupport() + {} + QFuture<void> refreshSourceFiles(const QStringList &sourceFiles) + { + CppModelManager *mgr = CppModelManager::instance(); + const WorkingCopy workingCopy = mgr->workingCopy(); + + CppPreprocessor *preproc = new CppPreprocessor(mgr, m_dumpFileNameWhileParsing); + preproc->setRevision(++m_revision); + preproc->setProjectFiles(mgr->projectFiles()); + preproc->setIncludePaths(mgr->includePaths()); + preproc->setFrameworkPaths(mgr->frameworkPaths()); + preproc->setWorkingCopy(workingCopy); + + QFuture<void> result = QtConcurrent::run(&parse, preproc, sourceFiles); + + if (m_synchronizer.futures().size() > 10) { + QList<QFuture<void> > futures = m_synchronizer.futures(); + + m_synchronizer.clearFutures(); + + foreach (const QFuture<void> &future, futures) { + if (! (future.isFinished() || future.isCanceled())) + m_synchronizer.addFuture(future); + } + } + + m_synchronizer.addFuture(result); + + if (sourceFiles.count() > 1) { + Core::ICore::progressManager()->addTask(result, + QCoreApplication::translate("IndexingSupport", "Parsing"), + QLatin1String(CppTools::Constants::TASK_INDEX)); + } + + return result; + } + +private: + static void parse(QFutureInterface<void> &future, + CppPreprocessor *preproc, + QStringList files) + { + if (files.isEmpty()) + return; + + const Core::MimeDatabase *mimeDb = Core::ICore::mimeDatabase(); + Core::MimeType cSourceTy = mimeDb->findByType(QLatin1String("text/x-csrc")); + Core::MimeType cppSourceTy = mimeDb->findByType(QLatin1String("text/x-c++src")); + Core::MimeType mSourceTy = mimeDb->findByType(QLatin1String("text/x-objcsrc")); + + QStringList sources; + QStringList headers; + + QStringList suffixes = cSourceTy.suffixes(); + suffixes += cppSourceTy.suffixes(); + suffixes += mSourceTy.suffixes(); + + foreach (const QString &file, files) { + QFileInfo info(file); + + preproc->snapshot.remove(file); + + if (suffixes.contains(info.suffix())) + sources.append(file); + else + headers.append(file); + } + + const int sourceCount = sources.size(); + files = sources; + files += headers; + + preproc->setTodo(files); + + future.setProgressRange(0, files.size()); + + QString conf = QLatin1String(pp_configuration_file); + + bool processingHeaders = false; + + for (int i = 0; i < files.size(); ++i) { + if (future.isPaused()) + future.waitForResume(); + + if (future.isCanceled()) + break; + + const QString fileName = files.at(i); + + const bool isSourceFile = i < sourceCount; + if (isSourceFile) + (void) preproc->run(conf); + + else if (! processingHeaders) { + (void) preproc->run(conf); + + processingHeaders = true; + } + + preproc->run(fileName); + + future.setProgressValue(files.size() - preproc->todo().size()); + + if (isSourceFile) + preproc->resetEnvironment(); + } + + future.setProgressValue(files.size()); + preproc->modelManager()->finishedRefreshingSourceFiles(files); + + delete preproc; + } + +private: + QFutureSynchronizer<void> m_synchronizer; + unsigned m_revision; + bool m_dumpFileNameWhileParsing; +}; + + +} // anonymous namespace /*! \class CppTools::CppModelManager @@ -706,15 +809,25 @@ CppModelManager *CppModelManager::instance() modified within Qt Creator. */ +QMutex CppModelManager::m_modelManagerMutex; +CppModelManager *CppModelManager::m_modelManagerInstance = 0; + +CppModelManager *CppModelManager::instance() +{ + if (m_modelManagerInstance) + return m_modelManagerInstance; + QMutexLocker locker(&m_modelManagerMutex); + if (!m_modelManagerInstance) { + m_modelManagerInstance = new CppModelManager; + } + return m_modelManagerInstance; +} + CppModelManager::CppModelManager(QObject *parent) : CppModelManagerInterface(parent) { m_findReferences = new CppFindReferences(this); m_indexerEnabled = qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull(); - m_dumpFileNameWhileParsing = !qgetenv("QTCREATOR_DUMP_FILENAME_WHILE_PARSING").isNull(); - - m_revision = 0; - m_synchronizer.setCancelOnWait(true); m_dirty = true; @@ -759,6 +872,7 @@ CppModelManager::CppModelManager(QObject *parent) ExtensionSystem::PluginManager::addObject(m_completionAssistProvider); m_highlightingFallback = new CppHighlightingSupportInternalFactory; m_highlightingFactory = m_highlightingFallback; + m_internalIndexingSupport = new IndexingSupport; } CppModelManager::~CppModelManager() @@ -766,6 +880,7 @@ CppModelManager::~CppModelManager() ExtensionSystem::PluginManager::removeObject(m_completionAssistProvider); delete m_completionFallback; delete m_highlightingFallback; + delete m_internalIndexingSupport; } Snapshot CppModelManager::snapshot() const @@ -851,6 +966,39 @@ QByteArray CppModelManager::internalDefinedMacros() const return macros; } +/// This method will aquire the mutex! +void CppModelManager::dumpModelManagerConfiguration() +{ + // Tons of debug output... + qDebug()<<"========= CppModelManager::dumpModelManagerConfiguration ======"; + foreach (const ProjectInfo &pinfo, m_projects.values()) { + qDebug()<<" for project:"<< pinfo.project().data()->document()->fileName(); + foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) { + qDebug() << "=== part ==="; + qDebug() << "language:" << (part->language == CXX ? "C++" : "ObjC++"); + qDebug() << "C++11:" << part->cxx11Enabled; + qDebug() << "Qt version:" << part->qtVersion; + qDebug() << "precompiled header:" << part->precompiledHeaders; + qDebug() << "defines:" << part->defines; + qDebug() << "includes:" << part->includePaths; + qDebug() << "frameworkPaths:" << part->frameworkPaths; + qDebug() << "sources:" << part->sourceFiles; + qDebug() << ""; + } + } + + ensureUpdated(); + qDebug() << "=== Merged include paths ==="; + foreach (const QString &inc, m_includePaths) + qDebug() << inc; + qDebug() << "=== Merged framework paths ==="; + foreach (const QString &inc, m_frameworkPaths) + qDebug() << inc; + qDebug() << "=== Merged defined macros ==="; + qDebug() << m_definedMacros; + qDebug()<<"========= End of dump ======"; +} + void CppModelManager::addEditorSupport(AbstractEditorSupport *editorSupport) { m_addtionalEditorSupport.insert(editorSupport); @@ -904,13 +1052,13 @@ CppModelManager::WorkingCopy CppModelManager::buildWorkingCopyList() QSetIterator<AbstractEditorSupport *> jt(m_addtionalEditorSupport); while (jt.hasNext()) { AbstractEditorSupport *es = jt.next(); - workingCopy.insert(es->fileName(), es->contents()); + workingCopy.insert(es->fileName(), QString::fromUtf8(es->contents())); } // add the project configuration file QByteArray conf(pp_configuration); conf += definedMacros(); - workingCopy.insert(pp_configuration_file, conf); + workingCopy.insert(QLatin1String(pp_configuration_file), QString::fromUtf8(conf)); return workingCopy; } @@ -921,7 +1069,15 @@ CppModelManager::WorkingCopy CppModelManager::workingCopy() const } QFuture<void> CppModelManager::updateSourceFiles(const QStringList &sourceFiles) -{ return refreshSourceFiles(sourceFiles); } +{ + if (sourceFiles.isEmpty() || !m_indexerEnabled) + return QFuture<void>(); + + foreach (CppIndexingSupport *indexer, m_indexingSupporters) + indexer->refreshSourceFiles(sourceFiles); + + return m_internalIndexingSupport->refreshSourceFiles(sourceFiles); +} QList<CppModelManager::ProjectInfo> CppModelManager::projectInfos() const { @@ -939,40 +1095,26 @@ CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Proje void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) { -#if 0 - // Tons of debug output... - qDebug()<<"========= CppModelManager::updateProjectInfo ======"; - qDebug()<<" for project:"<< pinfo.project().data()->document()->fileName(); - foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) { - qDebug() << "=== part ==="; - qDebug() << "language:" << (part->language == CXX ? "C++" : "ObjC++"); - qDebug() << "C++11:" << part->cxx11Enabled; - qDebug() << "Qt version:" << part->qtVersion; - qDebug() << "precompiled header:" << part->precompiledHeaders; - qDebug() << "defines:" << part->defines; - qDebug() << "includes:" << part->includePaths; - qDebug() << "frameworkPaths:" << part->frameworkPaths; - qDebug() << "sources:" << part->sourceFiles; - qDebug() << ""; - } + { // only hold the mutex for a limited scope, so the dumping afterwards can aquire it without deadlocking. + QMutexLocker locker(&mutex); - qDebug() << ""; -#endif - QMutexLocker locker(&mutex); + if (! pinfo.isValid()) + return; - if (! pinfo.isValid()) - return; + ProjectExplorer::Project *project = pinfo.project().data(); + m_projects.insert(project, pinfo); + m_dirty = true; - ProjectExplorer::Project *project = pinfo.project().data(); - m_projects.insert(project, pinfo); - m_dirty = true; + m_srcToProjectPart.clear(); - m_srcToProjectPart.clear(); + foreach (const ProjectInfo &projectInfo, m_projects.values()) + foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) + foreach (const QString &sourceFile, projectPart->sourceFiles) + m_srcToProjectPart[sourceFile].append(projectPart); + } - foreach (const ProjectInfo &projectInfo, m_projects.values()) - foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) - foreach (const QString &sourceFile, projectPart->sourceFiles) - m_srcToProjectPart[sourceFile].append(projectPart); + if (!qgetenv("QTCREATOR_DUMP_PROJECT_INFO").isEmpty()) + dumpModelManagerConfiguration(); } QList<CppModelManager::ProjectPart::Ptr> CppModelManager::projectPart(const QString &fileName) const @@ -982,7 +1124,7 @@ QList<CppModelManager::ProjectPart::Ptr> CppModelManager::projectPart(const QStr return parts; //### FIXME: This is a DIRTY hack! - if (fileName.endsWith(".h")) { + if (fileName.endsWith(QLatin1String(".h"))) { QString cppFile = fileName.mid(0, fileName.length() - 2) + QLatin1String(".cpp"); parts = m_srcToProjectPart.value(cppFile); if (!parts.isEmpty()) @@ -1001,44 +1143,6 @@ QList<CppModelManager::ProjectPart::Ptr> CppModelManager::projectPart(const QStr return parts; } -QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles) -{ - if (! sourceFiles.isEmpty() && m_indexerEnabled) { - const WorkingCopy workingCopy = buildWorkingCopyList(); - - CppPreprocessor *preproc = new CppPreprocessor(this, m_dumpFileNameWhileParsing); - preproc->setRevision(++m_revision); - preproc->setProjectFiles(projectFiles()); - preproc->setIncludePaths(includePaths()); - preproc->setFrameworkPaths(frameworkPaths()); - preproc->setWorkingCopy(workingCopy); - - QFuture<void> result = QtConcurrent::run(&CppModelManager::parse, - preproc, sourceFiles); - - if (m_synchronizer.futures().size() > 10) { - QList<QFuture<void> > futures = m_synchronizer.futures(); - - m_synchronizer.clearFutures(); - - foreach (const QFuture<void> &future, futures) { - if (! (future.isFinished() || future.isCanceled())) - m_synchronizer.addFuture(future); - } - } - - m_synchronizer.addFuture(result); - - if (sourceFiles.count() > 1) { - Core::ICore::progressManager()->addTask(result, tr("Parsing"), - CppTools::Constants::TASK_INDEX); - } - - return result; - } - return QFuture<void>(); -} - /*! \fn void CppModelManager::editorOpened(Core::IEditor *editor) \brief If a C++ editor is opened, the model manager listens to content changes @@ -1254,7 +1358,7 @@ void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) void CppModelManager::onAboutToUnloadSession() { if (Core::ProgressManager *pm = Core::ICore::progressManager()) { - pm->cancelTasks(CppTools::Constants::TASK_INDEX); + pm->cancelTasks(QLatin1String(CppTools::Constants::TASK_INDEX)); } do { QMutexLocker locker(&mutex); @@ -1265,81 +1369,6 @@ void CppModelManager::onAboutToUnloadSession() GC(); } -void CppModelManager::parse(QFutureInterface<void> &future, - CppPreprocessor *preproc, - QStringList files) -{ - if (files.isEmpty()) - return; - - const Core::MimeDatabase *mimeDb = Core::ICore::mimeDatabase(); - Core::MimeType cSourceTy = mimeDb->findByType(QLatin1String("text/x-csrc")); - Core::MimeType cppSourceTy = mimeDb->findByType(QLatin1String("text/x-c++src")); - Core::MimeType mSourceTy = mimeDb->findByType(QLatin1String("text/x-objcsrc")); - - QStringList sources; - QStringList headers; - - QStringList suffixes = cSourceTy.suffixes(); - suffixes += cppSourceTy.suffixes(); - suffixes += mSourceTy.suffixes(); - - foreach (const QString &file, files) { - QFileInfo info(file); - - preproc->snapshot.remove(file); - - if (suffixes.contains(info.suffix())) - sources.append(file); - else - headers.append(file); - } - - const int sourceCount = sources.size(); - files = sources; - files += headers; - - preproc->setTodo(files); - - future.setProgressRange(0, files.size()); - - QString conf = QLatin1String(pp_configuration_file); - - bool processingHeaders = false; - - for (int i = 0; i < files.size(); ++i) { - if (future.isPaused()) - future.waitForResume(); - - if (future.isCanceled()) - break; - - const QString fileName = files.at(i); - - const bool isSourceFile = i < sourceCount; - if (isSourceFile) - (void) preproc->run(conf); - - else if (! processingHeaders) { - (void) preproc->run(conf); - - processingHeaders = true; - } - - preproc->run(fileName); - - future.setProgressValue(files.size() - preproc->todo().size()); - - if (isSourceFile) - preproc->resetEnvironment(); - } - - future.setProgressValue(files.size()); - preproc->modelManager()->finishedRefreshingSourceFiles(files); - - delete preproc; -} - void CppModelManager::GC() { protectSnapshot.lock(); @@ -1421,6 +1450,12 @@ void CppModelManager::setHighlightingSupportFactory(CppHighlightingSupportFactor m_highlightingFactory = m_highlightingFallback; } +void CppModelManager::addIndexingSupport(CppIndexingSupport *indexingSupport) +{ + if (indexingSupport) + m_indexingSupporters.append(indexingSupport); +} + void CppModelManager::setExtraDiagnostics(const QString &fileName, int kind, const QList<Document::DiagnosticMessage> &diagnostics) { @@ -1444,6 +1479,3 @@ QList<Document::DiagnosticMessage> CppModelManager::extraDiagnostics(const QStri } return m_extraDiagnostics.value(fileName).value(kind); } - -#endif - diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 85ecbe3220..fdc06e8bc0 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -33,26 +33,19 @@ #include "cpptools_global.h" #include "cpptoolsconstants.h" #include "ModelManagerInterface.h" -#ifndef ICHECK_BUILD -# include <projectexplorer/project.h> -#endif +#include <projectexplorer/project.h> #include <cplusplus/CppDocument.h> #include <cplusplus/PreprocessorClient.h> -#ifndef ICHECK_BUILD -# include <texteditor/basetexteditor.h> -#endif +#include <texteditor/basetexteditor.h> #include <cplusplus/PreprocessorEnvironment.h> #include <cplusplus/pp-engine.h> -#ifdef ICHECK_BUILD -# include "parsemanager.h" -#else -# include <QHash> -# include <QFutureInterface> -# include <QFutureSynchronizer> -# include <QMutex> -# include <QTimer> -# include <QTextEdit> // for QTextEdit::ExtraSelection -#endif + +#include <QHash> +#include <QFutureInterface> +#include <QFutureSynchronizer> +#include <QMutex> +#include <QTimer> +#include <QTextEdit> // for QTextEdit::ExtraSelection namespace Core { class IEditor; @@ -82,13 +75,12 @@ class CppEditorSupport; class CppPreprocessor; class CppFindReferences; -#ifndef ICHECK_BUILD class CPPTOOLS_EXPORT CppModelManager : public CPlusPlus::CppModelManagerInterface { Q_OBJECT public: - CppModelManager(QObject *parent); + CppModelManager(QObject *parent = 0); virtual ~CppModelManager(); static CppModelManager *instance(); @@ -104,8 +96,6 @@ public: virtual CPlusPlus::Snapshot snapshot() const; virtual void GC(); - QFuture<void> refreshSourceFiles(const QStringList &sourceFiles); - virtual bool isCppEditor(Core::IEditor *editor) const; CppEditorSupport *editorSupport(TextEditor::ITextEditor *editor) const @@ -141,30 +131,7 @@ public: virtual CppHighlightingSupport *highlightingSupport(Core::IEditor *editor) const; virtual void setHighlightingSupportFactory(CppHighlightingSupportFactory *highlightingFactory); -Q_SIGNALS: - void projectPathChanged(const QString &projectPath); - - void aboutToRemoveFiles(const QStringList &files); - -public Q_SLOTS: - void editorOpened(Core::IEditor *editor); - void editorAboutToClose(Core::IEditor *editor); - virtual void updateModifiedSourceFiles(); - -private Q_SLOTS: - // this should be executed in the GUI thread. - void onDocumentUpdated(CPlusPlus::Document::Ptr doc); - void onExtraDiagnosticsUpdated(const QString &fileName); - void onAboutToRemoveProject(ProjectExplorer::Project *project); - void onAboutToUnloadSession(); - void onProjectAdded(ProjectExplorer::Project *project); - void postEditorUpdate(); - void updateEditorSelections(); - -private: - void updateEditor(CPlusPlus::Document::Ptr doc); - - WorkingCopy buildWorkingCopyList(); + virtual void addIndexingSupport(CppIndexingSupport *indexingSupport); QStringList projectFiles() { @@ -190,15 +157,42 @@ private: return m_definedMacros; } +Q_SIGNALS: + void projectPathChanged(const QString &projectPath); + + void aboutToRemoveFiles(const QStringList &files); + +public Q_SLOTS: + void editorOpened(Core::IEditor *editor); + void editorAboutToClose(Core::IEditor *editor); + virtual void updateModifiedSourceFiles(); + +private Q_SLOTS: + // this should be executed in the GUI thread. + void onDocumentUpdated(CPlusPlus::Document::Ptr doc); + void onExtraDiagnosticsUpdated(const QString &fileName); + void onAboutToRemoveProject(ProjectExplorer::Project *project); + void onAboutToUnloadSession(); + void onProjectAdded(ProjectExplorer::Project *project); + void postEditorUpdate(); + void updateEditorSelections(); + +private: + void updateEditor(CPlusPlus::Document::Ptr doc); + + WorkingCopy buildWorkingCopyList(); + void ensureUpdated(); QStringList internalProjectFiles() const; QStringList internalIncludePaths() const; QStringList internalFrameworkPaths() const; QByteArray internalDefinedMacros() const; - static void parse(QFutureInterface<void> &future, - CppPreprocessor *preproc, - QStringList files); + void dumpModelManagerConfiguration(); + +private: + static QMutex m_modelManagerMutex; + static CppModelManager *m_modelManagerInstance; private: CPlusPlus::Snapshot m_snapshot; @@ -237,12 +231,8 @@ private: QTimer *m_updateEditorSelectionsTimer; - QFutureSynchronizer<void> m_synchronizer; - unsigned m_revision; - CppFindReferences *m_findReferences; bool m_indexerEnabled; - bool m_dumpFileNameWhileParsing; mutable QMutex protectExtraDiagnostics; QHash<QString, QHash<int, QList<CPlusPlus::Document::DiagnosticMessage> > > m_extraDiagnostics; @@ -253,17 +243,14 @@ private: CppCompletionAssistProvider *m_completionFallback; CppHighlightingSupportFactory *m_highlightingFactory; CppHighlightingSupportFactory *m_highlightingFallback; + QList<CppIndexingSupport *> m_indexingSupporters; + CppIndexingSupport *m_internalIndexingSupport; }; -#endif class CPPTOOLS_EXPORT CppPreprocessor: public CPlusPlus::Client { public: -#ifndef ICHECK_BUILD CppPreprocessor(QPointer<CppModelManager> modelManager, bool dumpFileNameWhileParsing = false); -#else - CppPreprocessor(QPointer<CPlusPlus::ParseManager> modelManager); -#endif virtual ~CppPreprocessor(); void setRevision(unsigned revision); @@ -312,9 +299,7 @@ protected: virtual void sourceNeeded(unsigned line, QString &fileName, IncludeType type); private: -#ifndef ICHECK_BUILD QPointer<CppModelManager> m_modelManager; -#endif bool m_dumpFileNameWhileParsing; CPlusPlus::Environment env; CPlusPlus::Preprocessor preprocess; diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index 1e0fbc7473..7c49e5e521 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -4,8 +4,7 @@ include(../../qtcreatorplugin.pri) include($$IDE_SOURCE_TREE/src/plugins/locator/locator.pri) include(cpptools_dependencies.pri) -# DEFINES += QT_NO_CAST_FROM_ASCII -DEFINES += QT_NO_CAST_TO_ASCII +DEFINES += QT_NO_CAST_FROM_ASCII INCLUDEPATH += . DEFINES += CPPTOOLS_LIBRARY HEADERS += completionsettingspage.h \ @@ -47,7 +46,8 @@ HEADERS += completionsettingspage.h \ cppsemanticinfo.h \ cppcompletionassistprovider.h \ ModelManagerInterface.h \ - TypeHierarchyBuilder.h + TypeHierarchyBuilder.h \ + cppindexingsupport.h SOURCES += completionsettingspage.cpp \ cppclassesfilter.cpp \ @@ -86,7 +86,8 @@ SOURCES += completionsettingspage.cpp \ cppsemanticinfo.cpp \ cppcompletionassistprovider.cpp \ ModelManagerInterface.cpp \ - TypeHierarchyBuilder.cpp + TypeHierarchyBuilder.cpp \ + cppindexingsupport.cpp FORMS += completionsettingspage.ui \ cppfilesettingspage.ui \ diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 709f1edecb..1b2518cf11 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -1,6 +1,7 @@ import qbs.base 1.0 import "../QtcPlugin.qbs" as QtcPlugin +import "../../../qbs/defaults.js" as Defaults QtcPlugin { name: "CppTools" @@ -15,15 +16,13 @@ QtcPlugin { Depends { name: "LanguageUtils" } Depends { name: "cpp" } - cpp.defines: base.concat(["QT_NO_CAST_TO_ASCII"]) - cpp.includePaths: [ - ".", - "..", - "../../libs", - buildDirectory - ] + cpp.defines: base.concat(["QT_NO_CAST_FROM_ASCII"]) files: [ + "ModelManagerInterface.cpp", + "ModelManagerInterface.h", + "TypeHierarchyBuilder.cpp", + "TypeHierarchyBuilder.h", "abstracteditorsupport.cpp", "abstracteditorsupport.h", "commentssettings.cpp", @@ -31,6 +30,8 @@ QtcPlugin { "completionsettingspage.cpp", "completionsettingspage.h", "completionsettingspage.ui", + "cppchecksymbols.cpp", + "cppchecksymbols.h", "cppclassesfilter.cpp", "cppclassesfilter.h", "cppcodeformatter.cpp", @@ -38,6 +39,7 @@ QtcPlugin { "cppcodestylepreferences.cpp", "cppcodestylepreferences.h", "cppcodestylepreferencesfactory.cpp", + "cppcodestylepreferencesfactory.h", "cppcodestylesettings.cpp", "cppcodestylesettings.h", "cppcodestylesettingspage.cpp", @@ -45,12 +47,14 @@ QtcPlugin { "cppcodestylesettingspage.ui", "cppcompletionassist.cpp", "cppcompletionassist.h", + "cppcompletionassistprovider.cpp", + "cppcompletionassistprovider.h", + "cppcompletionsupport.cpp", + "cppcompletionsupport.h", "cppcurrentdocumentfilter.cpp", "cppcurrentdocumentfilter.h", "cppdoxygen.cpp", "cppdoxygen.h", - "cppcompletionsupport.cpp", - "cppcompletionsupport.h", "cppfilesettingspage.cpp", "cppfilesettingspage.h", "cppfilesettingspage.ui", @@ -58,10 +62,14 @@ QtcPlugin { "cppfindreferences.h", "cppfunctionsfilter.cpp", "cppfunctionsfilter.h", - "cpphighlightingsupportinternal.cpp", - "cpphighlightingsupportinternal.h", "cpphighlightingsupport.cpp", "cpphighlightingsupport.h", + "cpphighlightingsupportinternal.cpp", + "cpphighlightingsupportinternal.h", + "cppindexingsupport.cpp", + "cppindexingsupport.h", + "cpplocalsymbols.cpp", + "cpplocalsymbols.h", "cpplocatorfilter.cpp", "cpplocatorfilter.h", "cppmodelmanager.cpp", @@ -72,10 +80,6 @@ QtcPlugin { "cpprefactoringchanges.h", "cppsemanticinfo.cpp", "cppsemanticinfo.h", - "cppchecksymbols.cpp", - "cppchecksymbols.h", - "cpplocalsymbols.cpp", - "cpplocalsymbols.h", "cpptools_global.h", "cpptoolsconstants.h", "cpptoolseditorsupport.cpp", @@ -98,17 +102,14 @@ QtcPlugin { "symbolsfindfilter.h", "uicodecompletionsupport.cpp", "uicodecompletionsupport.h", - "cppcompletionassistprovider.cpp", - "cppcompletionassistprovider.h", - "cppcodestylepreferencesfactory.h", - "ModelManagerInterface.cpp", - "ModelManagerInterface.h", - "TypeHierarchyBuilder.cpp", - "TypeHierarchyBuilder.h" ] + Group { + condition: Defaults.testsEnabled(qbs) + files: ["cppcodegen_test.cpp", "cppcompletion_test.cpp"] + } + ProductModule { Depends { name: "CPlusPlus" } } } - diff --git a/src/plugins/cpptools/cpptoolseditorsupport.cpp b/src/plugins/cpptools/cpptoolseditorsupport.cpp index a594dd445e..e88518ad2d 100644 --- a/src/plugins/cpptools/cpptoolseditorsupport.cpp +++ b/src/plugins/cpptools/cpptoolseditorsupport.cpp @@ -123,8 +123,8 @@ void CppEditorSupport::updateDocumentNow() _updateDocumentTimer->stop(); QStringList sourceFiles(_textEditor->document()->fileName()); - _cachedContents = _textEditor->contents().toUtf8(); - _documentParser = _modelManager->refreshSourceFiles(sourceFiles); + _cachedContents = _textEditor->contents(); + _documentParser = _modelManager->updateSourceFiles(sourceFiles); } } diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index e368f6c2bb..8c9b35d893 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -39,6 +39,7 @@ #include "cpplocatorfilter.h" #include "symbolsfindfilter.h" #include "cpptoolssettings.h" +#include "cpptoolsreuse.h" #include <extensionsystem/pluginmanager.h> @@ -74,15 +75,17 @@ #include <sstream> -using namespace CppTools::Internal; using namespace CPlusPlus; +namespace CppTools { +namespace Internal { + enum { debug = 0 }; static CppToolsPlugin *m_instance = 0; +static QHash<QString, QString> m_headerSourceMapping; CppToolsPlugin::CppToolsPlugin() : - m_modelManager(0), m_fileSettings(new CppFileSettings) { m_instance = this; @@ -91,7 +94,7 @@ CppToolsPlugin::CppToolsPlugin() : CppToolsPlugin::~CppToolsPlugin() { m_instance = 0; - m_modelManager = 0; // deleted automatically + delete CppModelManager::instance(); } bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error) @@ -102,20 +105,19 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error) m_settings = new CppToolsSettings(this); // force registration of cpp tools settings // Objects - m_modelManager = new CppModelManager(this); + CppModelManager *modelManager = CppModelManager::instance(); Core::VcsManager *vcsManager = Core::ICore::vcsManager(); connect(vcsManager, SIGNAL(repositoryChanged(QString)), - m_modelManager, SLOT(updateModifiedSourceFiles())); + modelManager, SLOT(updateModifiedSourceFiles())); connect(Core::DocumentManager::instance(), SIGNAL(filesChangedInternally(QStringList)), - m_modelManager, SLOT(updateSourceFiles(QStringList))); - addAutoReleasedObject(m_modelManager); + modelManager, SLOT(updateSourceFiles(QStringList))); - addAutoReleasedObject(new CppLocatorFilter(m_modelManager)); - addAutoReleasedObject(new CppClassesFilter(m_modelManager)); - addAutoReleasedObject(new CppFunctionsFilter(m_modelManager)); - addAutoReleasedObject(new CppCurrentDocumentFilter(m_modelManager, Core::ICore::editorManager())); + addAutoReleasedObject(new CppLocatorFilter(modelManager)); + addAutoReleasedObject(new CppClassesFilter(modelManager)); + addAutoReleasedObject(new CppFunctionsFilter(modelManager)); + addAutoReleasedObject(new CppCurrentDocumentFilter(modelManager, Core::ICore::editorManager())); addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings)); - addAutoReleasedObject(new SymbolsFindFilter(m_modelManager)); + addAutoReleasedObject(new SymbolsFindFilter(modelManager)); addAutoReleasedObject(new CppCodeStyleSettingsPage); // Menus @@ -250,16 +252,23 @@ static int commonStringLength(const QString &s1, const QString &s2) return length; } -QString CppToolsPlugin::correspondingHeaderOrSourceI(const QString &fileName) const +} // namespace Internal + +QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader) { - const QFileInfo fi(fileName); - if (m_headerSourceMapping.contains(fi.absoluteFilePath())) - return m_headerSourceMapping.value(fi.absoluteFilePath()); + using namespace Internal; const Core::MimeDatabase *mimeDatase = Core::ICore::mimeDatabase(); - ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::currentProject(); + const QFileInfo fi(fileName); + if (m_headerSourceMapping.contains(fi.absoluteFilePath())) { + if (wasHeader) + *wasHeader = fileType(mimeDatase, fi) == HeaderFile; + return m_headerSourceMapping.value(fi.absoluteFilePath()); + } - const FileType type = fileType(mimeDatase, fi); + FileType type = fileType(mimeDatase, fi); + if (wasHeader) + *wasHeader = type == HeaderFile; if (debug) qDebug() << Q_FUNC_INFO << fileName << type; @@ -298,6 +307,7 @@ QString CppToolsPlugin::correspondingHeaderOrSourceI(const QString &fileName) co } // Find files in the project + ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::currentProject(); if (project) { QString bestFileName; int compareValue = 0; @@ -324,12 +334,6 @@ QString CppToolsPlugin::correspondingHeaderOrSourceI(const QString &fileName) co return QString(); } -QString CppToolsPlugin::correspondingHeaderOrSource(const QString &fileName) -{ - const QString rc = m_instance->correspondingHeaderOrSourceI(fileName); - if (debug) - qDebug() << Q_FUNC_INFO << fileName << rc; - return rc; -} +} // namespace CppTools -Q_EXPORT_PLUGIN(CppToolsPlugin) +Q_EXPORT_PLUGIN(CppTools::Internal::CppToolsPlugin) diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 597a6ab27c..1c026685fe 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -30,6 +30,8 @@ #ifndef CPPTOOLS_H #define CPPTOOLS_H +#include "cpptools_global.h" + #include <extensionsystem/iplugin.h> #include <projectexplorer/projectexplorer.h> #include <find/ifindfilter.h> @@ -69,8 +71,6 @@ public: bool initialize(const QStringList &arguments, QString *errorMessage); void extensionsInitialized(); ShutdownFlag aboutToShutdown(); - CppModelManager *cppModelManager() { return m_modelManager; } - static QString correspondingHeaderOrSource(const QString &fileName); private slots: void switchHeaderSource(); @@ -105,18 +105,16 @@ private slots: void test_completion_base_class_has_name_the_same_as_derived_data(); void test_completion_cyclic_inheritance(); void test_completion_cyclic_inheritance_data(); + void test_completion_enclosing_template_class(); + void test_completion_enclosing_template_class_data(); private: void test_completion(); #endif private: - QString correspondingHeaderOrSourceI(const QString &fileName) const; - - CppModelManager *m_modelManager; QSharedPointer<CppFileSettings> m_fileSettings; CppToolsSettings *m_settings; - mutable QHash<QString, QString> m_headerSourceMapping; }; } // namespace Internal diff --git a/src/plugins/cpptools/cpptoolsreuse.h b/src/plugins/cpptools/cpptoolsreuse.h index d9bc4fc752..6a4b6647d8 100644 --- a/src/plugins/cpptools/cpptoolsreuse.h +++ b/src/plugins/cpptools/cpptoolsreuse.h @@ -52,6 +52,8 @@ bool CPPTOOLS_EXPORT isValidIdentifier(const QString &s); bool CPPTOOLS_EXPORT isQtKeyword(const QStringRef &text); +QString CPPTOOLS_EXPORT correspondingHeaderOrSource(const QString &fileName, bool *wasHeader = 0); + } // CppTools #endif // CPPTOOLSREUSE_H diff --git a/src/plugins/cpptools/cpptoolssettings.cpp b/src/plugins/cpptools/cpptoolssettings.cpp index dbf94e760a..503cc99bb9 100644 --- a/src/plugins/cpptools/cpptoolssettings.cpp +++ b/src/plugins/cpptools/cpptoolssettings.cpp @@ -45,7 +45,7 @@ #include <coreplugin/icore.h> #include <QSettings> -static const char *idKey = "CppGlobal"; +static const char idKey[] = "CppGlobal"; using namespace CppTools; using namespace CppTools::Internal; @@ -102,7 +102,7 @@ CppToolsSettings::CppToolsSettings(QObject *parent) d->m_globalCodeStyle = new CppCodeStylePreferences(this); d->m_globalCodeStyle->setDelegatingPool(pool); d->m_globalCodeStyle->setDisplayName(tr("Global", "Settings")); - d->m_globalCodeStyle->setId(idKey); + d->m_globalCodeStyle->setId(QLatin1String(idKey)); pool->addCodeStyle(d->m_globalCodeStyle); textEditorSettings->registerCodeStyle(CppTools::Constants::CPP_SETTINGS_ID, d->m_globalCodeStyle); @@ -171,7 +171,7 @@ CppToolsSettings::CppToolsSettings(QObject *parent) // load global settings (after built-in settings are added to the pool) QSettings *s = Core::ICore::settings(); - d->m_globalCodeStyle->fromSettings(CppTools::Constants::CPP_SETTINGS_ID, Core::ICore::settings()); + d->m_globalCodeStyle->fromSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), Core::ICore::settings()); // legacy handling start (Qt Creator Version < 2.4) const bool legacyTransformed = @@ -214,7 +214,7 @@ CppToolsSettings::CppToolsSettings(QObject *parent) // change the current delegate and save d->m_globalCodeStyle->setCurrentDelegate(oldCreator); - d->m_globalCodeStyle->toSettings(CppTools::Constants::CPP_SETTINGS_ID, s); + d->m_globalCodeStyle->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); } // mark old settings as transformed s->setValue(QLatin1String("CppCodeStyleSettings/LegacyTransformed"), true); diff --git a/src/plugins/cpptools/insertionpointlocator.cpp b/src/plugins/cpptools/insertionpointlocator.cpp index e70fefd4ee..d30101c085 100644 --- a/src/plugins/cpptools/insertionpointlocator.cpp +++ b/src/plugins/cpptools/insertionpointlocator.cpp @@ -27,7 +27,7 @@ ** ****************************************************************************/ -#include "cpptoolsplugin.h" +#include "cpptoolsreuse.h" #include "cpprefactoringchanges.h" #include "insertionpointlocator.h" #include "symbolfinder.h" @@ -528,14 +528,14 @@ static InsertionLocation nextToSurroundingDefinitions(Declaration *declaration, if (!definitionFunction) return noResult; - Document::Ptr targetDoc = changes.snapshot().document(definition->fileName()); + Document::Ptr targetDoc = changes.snapshot().document(QString::fromUtf8(definition->fileName())); if (!targetDoc) return noResult; targetDoc->translationUnit()->getPosition(definitionFunction->endOffset(), &line, &column); } else { // we don't have an offset to the start of the function definition, so we need to manually find it... - CppRefactoringFilePtr targetFile = changes.file(definition->fileName()); + CppRefactoringFilePtr targetFile = changes.file(QString::fromUtf8(definition->fileName())); if (!targetFile->isValid()) return noResult; @@ -547,7 +547,7 @@ static InsertionLocation nextToSurroundingDefinitions(Declaration *declaration, targetFile->cppDocument()->translationUnit()->getTokenStartPosition(functionDefinition->firstToken(), &line, &column); } - return InsertionLocation(definition->fileName(), prefix, suffix, line, column); + return InsertionLocation(QString::fromUtf8(definition->fileName()), prefix, suffix, line, column); } QList<InsertionLocation> InsertionPointLocator::methodDefinition( @@ -578,7 +578,7 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition( declaration->fileNameLength()); QString target = declFileName; if (!isSourceFile(declFileName)) { - QString candidate = Internal::CppToolsPlugin::correspondingHeaderOrSource(declFileName); + QString candidate = CppTools::correspondingHeaderOrSource(declFileName); if (!candidate.isEmpty()) target = candidate; } diff --git a/src/plugins/cpptools/symbolsfindfilter.cpp b/src/plugins/cpptools/symbolsfindfilter.cpp index ddb4f2fa4b..2ea320ef46 100644 --- a/src/plugins/cpptools/symbolsfindfilter.cpp +++ b/src/plugins/cpptools/symbolsfindfilter.cpp @@ -207,7 +207,7 @@ void SymbolsFindFilter::startSearch(Find::SearchResult *search) m_manager->snapshot(), projectFileNames)); Core::FutureProgress *progress = Core::ICore::progressManager()->addTask(watcher->future(), tr("Searching"), - Find::Constants::TASK_SEARCH); + QLatin1String(Find::Constants::TASK_SEARCH)); connect(progress, SIGNAL(clicked()), search, SLOT(popup())); } @@ -256,17 +256,17 @@ QWidget *SymbolsFindFilter::createConfigWidget() void SymbolsFindFilter::writeSettings(QSettings *settings) { settings->beginGroup(QLatin1String(SETTINGS_GROUP)); - settings->setValue(SETTINGS_SYMBOLTYPES, (int)m_symbolsToSearch); - settings->setValue(SETTINGS_SEARCHSCOPE, (int)m_scope); + settings->setValue(QLatin1String(SETTINGS_SYMBOLTYPES), (int)m_symbolsToSearch); + settings->setValue(QLatin1String(SETTINGS_SEARCHSCOPE), (int)m_scope); settings->endGroup(); } void SymbolsFindFilter::readSettings(QSettings *settings) { settings->beginGroup(QLatin1String(SETTINGS_GROUP)); - m_symbolsToSearch = (SearchSymbols::SymbolTypes)settings->value(SETTINGS_SYMBOLTYPES, + m_symbolsToSearch = (SearchSymbols::SymbolTypes)settings->value(QLatin1String(SETTINGS_SYMBOLTYPES), (int)SearchSymbols::AllTypes).toInt(); - m_scope = (SearchScope)settings->value(SETTINGS_SEARCHSCOPE, + m_scope = (SearchScope)settings->value(QLatin1String(SETTINGS_SEARCHSCOPE), (int)SearchProjectsOnly).toInt(); settings->endGroup(); emit symbolsToSearchChanged(); @@ -274,7 +274,7 @@ void SymbolsFindFilter::readSettings(QSettings *settings) void SymbolsFindFilter::onTaskStarted(const QString &type) { - if (type == CppTools::Constants::TASK_INDEX) { + if (type == QLatin1String(CppTools::Constants::TASK_INDEX)) { m_enabled = false; emit enabledChanged(m_enabled); } @@ -282,7 +282,7 @@ void SymbolsFindFilter::onTaskStarted(const QString &type) void SymbolsFindFilter::onAllTasksFinished(const QString &type) { - if (type == CppTools::Constants::TASK_INDEX) { + if (type == QLatin1String(CppTools::Constants::TASK_INDEX)) { m_enabled = true; emit enabledChanged(m_enabled); } diff --git a/src/plugins/cpptools/uicodecompletionsupport.cpp b/src/plugins/cpptools/uicodecompletionsupport.cpp index b1072889a7..e3d5c88c74 100644 --- a/src/plugins/cpptools/uicodecompletionsupport.cpp +++ b/src/plugins/cpptools/uicodecompletionsupport.cpp @@ -44,8 +44,8 @@ UiCodeModelSupport::UiCodeModelSupport(CppModelManagerInterface *modelmanager, : AbstractEditorSupport(modelmanager), m_sourceName(source), m_fileName(uiHeaderFile), - m_updateIncludingFiles(false), - m_initialized(false) + m_initialized(false), + m_running(false) { if (debug) qDebug()<<"ctor UiCodeModelSupport for"<<m_sourceName<<uiHeaderFile; @@ -91,10 +91,6 @@ void UiCodeModelSupport::init() const qDebug()<<"uic run wasn't succesfull"; m_cacheTime = QDateTime (); m_contents = QByteArray(); - // and if the header file wasn't there, next time we need to update - // all of the files that include this header - if (!uiHeaderFileInfo.exists()) - m_updateIncludingFiles = true; return; } } else { @@ -108,6 +104,8 @@ QByteArray UiCodeModelSupport::contents() const { if (!m_initialized) init(); + if (m_running) + finishProcess(); return m_contents; } @@ -133,42 +131,58 @@ void UiCodeModelSupport::setFileName(const QString &name) bool UiCodeModelSupport::runUic(const QString &ui) const { - QProcess process; const QString uic = uicCommand(); if (uic.isEmpty()) return false; - process.setEnvironment(environment()); + m_process.setEnvironment(environment()); if (debug) qDebug() << "UiCodeModelSupport::runUic " << uic << " on " << ui.size() << " bytes"; - process.start(uic, QStringList(), QIODevice::ReadWrite); - if (!process.waitForStarted()) + m_process.start(uic, QStringList(), QIODevice::ReadWrite); + if (!m_process.waitForStarted()) return false; - process.write(ui.toUtf8()); - if (!process.waitForBytesWritten(3000)) + m_process.write(ui.toUtf8()); + if (!m_process.waitForBytesWritten(3000)) goto error; - process.closeWriteChannel(); - if (!process.waitForFinished(3000) && process.exitStatus() != QProcess::NormalExit && process.exitCode() != 0) - goto error; - - m_contents = process.readAllStandardOutput(); - m_cacheTime = QDateTime::currentDateTime(); - if (debug) - qDebug() << "ok" << m_contents.size() << "bytes."; + m_process.closeWriteChannel(); + m_running = true; return true; error: if (debug) - qDebug() << "failed" << process.readAllStandardError(); - process.kill(); + qDebug() << "failed" << m_process.readAllStandardError(); + m_process.kill(); + m_running = false; return false; } void UiCodeModelSupport::updateFromEditor(const QString &formEditorContents) { - if (runUic(formEditorContents)) { - updateDocument(); + if (runUic(formEditorContents)) + if (finishProcess()) + updateDocument(); +} + +bool UiCodeModelSupport::finishProcess() const +{ + if (!m_running) + return false; + if (!m_process.waitForFinished(3000) + && m_process.exitStatus() != QProcess::NormalExit + && m_process.exitCode() != 0) { + if (debug) + qDebug() << "failed" << m_process.readAllStandardError(); + m_process.kill(); + m_running = false; + return false; } + + m_contents = m_process.readAllStandardOutput(); + m_cacheTime = QDateTime::currentDateTime(); + if (debug) + qDebug() << "ok" << m_contents.size() << "bytes."; + m_running = false; + return true; } void UiCodeModelSupport::updateFromBuild() diff --git a/src/plugins/cpptools/uicodecompletionsupport.h b/src/plugins/cpptools/uicodecompletionsupport.h index 0dcdf7d645..afbdbac211 100644 --- a/src/plugins/cpptools/uicodecompletionsupport.h +++ b/src/plugins/cpptools/uicodecompletionsupport.h @@ -37,6 +37,7 @@ #include "ModelManagerInterface.h" #include <QDateTime> +#include <QProcess> namespace CppTools { @@ -59,12 +60,14 @@ protected: private: void init() const; bool runUic(const QString &ui) const; + bool finishProcess() const; + mutable QProcess m_process; QString m_sourceName; QString m_fileName; - mutable bool m_updateIncludingFiles; mutable bool m_initialized; mutable QByteArray m_contents; mutable QDateTime m_cacheTime; + mutable bool m_running; }; } // CppTools diff --git a/src/plugins/cvs/cvs.qbs b/src/plugins/cvs/cvs.qbs index f45ca0a576..d89725f59d 100644 --- a/src/plugins/cvs/cvs.qbs +++ b/src/plugins/cvs/cvs.qbs @@ -12,36 +12,29 @@ QtcPlugin { Depends { name: "VcsBase" } Depends { name: "Locator" } - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ + "annotationhighlighter.cpp", "annotationhighlighter.h", - "cvsplugin.h", - "cvscontrol.h", - "settingspage.h", - "cvseditor.h", - "cvssubmiteditor.h", - "cvssettings.h", - "cvsutils.h", - "cvsconstants.h", + "checkoutwizard.cpp", "checkoutwizard.h", + "checkoutwizardpage.cpp", "checkoutwizardpage.h", - "annotationhighlighter.cpp", - "cvsplugin.cpp", + "cvs.qrc", + "cvsconstants.h", "cvscontrol.cpp", - "settingspage.cpp", + "cvscontrol.h", "cvseditor.cpp", - "cvssubmiteditor.cpp", + "cvseditor.h", + "cvsplugin.cpp", + "cvsplugin.h", "cvssettings.cpp", + "cvssettings.h", + "cvssubmiteditor.cpp", + "cvssubmiteditor.h", "cvsutils.cpp", - "checkoutwizard.cpp", - "checkoutwizardpage.cpp", + "cvsutils.h", + "settingspage.cpp", + "settingspage.h", "settingspage.ui", - "cvs.qrc" ] } diff --git a/src/plugins/cvs/cvscontrol.cpp b/src/plugins/cvs/cvscontrol.cpp index 0604ecd0ee..5feb30ab52 100644 --- a/src/plugins/cvs/cvscontrol.cpp +++ b/src/plugins/cvs/cvscontrol.cpp @@ -50,7 +50,7 @@ QString CvsControl::displayName() const Core::Id CvsControl::id() const { - return VcsBase::Constants::VCS_ID_CVS; + return Core::Id(VcsBase::Constants::VCS_ID_CVS); } bool CvsControl::isConfigured() const diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 3edb843d0d..1185aa2ce0 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -147,7 +147,7 @@ static inline const VcsBaseEditorParameters *findType(int ie) static inline QString debugCodec(const QTextCodec *c) { - return c ? QString::fromAscii(c->name()) : QString::fromAscii("Null codec"); + return c ? QString::fromLatin1(c->name()) : QString::fromLatin1("Null codec"); } static inline bool messageBoxQuestion(const QString &title, const QString &question, QWidget *parent = 0) @@ -1269,7 +1269,7 @@ IEditor *CvsPlugin::showOutputInEditor(const QString& title, const QString &outp { const VcsBaseEditorParameters *params = findType(editorType); QTC_ASSERT(params, return 0); - const Id id = params->id; + const Id id = Core::Id(QByteArray(params->id)); if (Cvs::Constants::debug) qDebug() << "CVSPlugin::showOutputInEditor" << title << id.name() << "source=" << source << "Size= " << output.size() << " Type=" << editorType << debugCodec(codec); diff --git a/src/plugins/cvs/cvssettings.cpp b/src/plugins/cvs/cvssettings.cpp index f247969120..2b7b7a72e3 100644 --- a/src/plugins/cvs/cvssettings.cpp +++ b/src/plugins/cvs/cvssettings.cpp @@ -30,6 +30,7 @@ #include "cvssettings.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <QSettings> #include <QTextStream> @@ -47,12 +48,7 @@ enum { defaultTimeOutS = 30 }; static QString defaultCommand() { - QString rc; - rc = QLatin1String("cvs"); -#if defined(Q_OS_WIN32) - rc.append(QLatin1String(".exe")); -#endif - return rc; + return QLatin1String("cvs" QTC_HOST_EXE_SUFFIX); } namespace Cvs { diff --git a/src/plugins/debugger/basewindow.h b/src/plugins/debugger/basewindow.h index 733d3ddd50..5898704178 100644 --- a/src/plugins/debugger/basewindow.h +++ b/src/plugins/debugger/basewindow.h @@ -53,6 +53,7 @@ public: void setModel(QAbstractItemModel *model) { m_treeView->setModel(model); } QHeaderView *header() const { return m_treeView->header(); } QAbstractItemModel *model() const { return m_treeView->model(); } + QTreeView *treeView() const { return m_treeView; } private: QTreeView *m_treeView; diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index fb2af54748..f66e8031f1 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -37,6 +37,8 @@ #include "debuggerstringutils.h" #include "stackframe.h" +#include <extensionsystem/invoker.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #if USE_BREAK_MODEL_TEST @@ -180,11 +182,9 @@ QIcon BreakHandler::emptyIcon() static inline bool fileNameMatch(const QString &f1, const QString &f2) { -#ifdef Q_OS_WIN - return f1.compare(f2, Qt::CaseInsensitive) == 0; -#else + if (Utils::HostOsInfo::isWindowsHost()) + return f1.compare(f2, Qt::CaseInsensitive) == 0; return f1 == f2; -#endif } static bool isSimilarTo(const BreakpointParameters &data, const BreakpointResponse &needle) @@ -1163,18 +1163,20 @@ void BreakHandler::saveSessionData() void BreakHandler::loadSessionData() { + beginResetModel(); m_storage.clear(); - reset(); + endResetModel(); loadBreakpoints(); } void BreakHandler::removeSessionData() { + beginResetModel(); Iterator it = m_storage.begin(), et = m_storage.end(); for ( ; it != et; ++it) it->destroyMarker(); m_storage.clear(); - reset(); + endResetModel(); } void BreakHandler::breakByFunction(const QString &functionName) @@ -1257,6 +1259,25 @@ void BreakHandler::updateLineNumberFromMarker(BreakpointModelId id, int lineNumb emit layoutChanged(); } +void BreakHandler::changeLineNumberFromMarker(BreakpointModelId id, int lineNumber) +{ + // We need to delay this as it is called from a marker which will be destroyed. + ExtensionSystem::InvokerBase invoker; + invoker.addArgument(id); + invoker.addArgument(lineNumber); + invoker.setConnectionType(Qt::QueuedConnection); + invoker.invoke(this, "changeLineNumberFromMarkerHelper"); + QTC_CHECK(invoker.wasSuccessful()); +} + +void BreakHandler::changeLineNumberFromMarkerHelper(BreakpointModelId id, int lineNumber) +{ + BreakpointParameters data = breakpointData(id); + data.lineNumber = lineNumber; + removeBreakpoint(id); + appendBreakpoint(data); +} + BreakpointModelIds BreakHandler::allBreakpointIds() const { BreakpointModelIds ids; diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index 750d2faff3..7e6eb46a9b 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -133,6 +133,7 @@ public: void setEnabled(BreakpointModelId id, bool on); void updateFileNameFromMarker(BreakpointModelId id, const QString &fileName); void updateLineNumberFromMarker(BreakpointModelId id, int lineNumber); + void changeLineNumberFromMarker(BreakpointModelId id, int lineNumber); void setMarkerFileAndLine(BreakpointModelId id, const QString &fileName, int lineNumber); bool isOneShot(BreakpointModelId id) const; @@ -189,6 +190,7 @@ private: void loadBreakpoints(); void saveBreakpoints(); void cleanupBreakpoint(BreakpointModelId id); + Q_SLOT void changeLineNumberFromMarkerHelper(Debugger::Internal::BreakpointModelId id, int lineNumber); struct BreakpointItem { diff --git a/src/plugins/debugger/breakpointmarker.cpp b/src/plugins/debugger/breakpointmarker.cpp index 412bc5ade1..da309cd5e0 100644 --- a/src/plugins/debugger/breakpointmarker.cpp +++ b/src/plugins/debugger/breakpointmarker.cpp @@ -68,6 +68,16 @@ void BreakpointMarker::updateLineNumber(int lineNumber) breakHandler()->updateLineNumberFromMarker(m_id, lineNumber); } +void BreakpointMarker::dragToLine(int lineNumber) +{ + breakHandler()->changeLineNumberFromMarker(m_id, lineNumber); +} + +void BreakpointMarker::clicked() +{ + breakHandler()->removeBreakpoint(m_id); +} + void BreakpointMarker::updateFileName(const QString &fileName) { BaseTextMark::updateFileName(fileName); diff --git a/src/plugins/debugger/breakpointmarker.h b/src/plugins/debugger/breakpointmarker.h index 9f6f083828..39d40f6731 100644 --- a/src/plugins/debugger/breakpointmarker.h +++ b/src/plugins/debugger/breakpointmarker.h @@ -46,6 +46,10 @@ public: void removedFromEditor(); void updateLineNumber(int lineNumber); void updateFileName(const QString &fileName); + bool isDraggable() const { return true; } + void dragToLine(int lineNumber); + bool isClickable() const { return true; } + void clicked(); private: BreakpointModelId m_id; diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp index b995e0cc8d..62a0476704 100644 --- a/src/plugins/debugger/breakwindow.cpp +++ b/src/plugins/debugger/breakwindow.cpp @@ -713,11 +713,15 @@ void BreakTreeView::keyPressEvent(QKeyEvent *ev) void BreakTreeView::mouseDoubleClickEvent(QMouseEvent *ev) { QModelIndex indexUnderMouse = indexAt(ev->pos()); - if (indexUnderMouse.isValid() && indexUnderMouse.column() >= 4) { - BreakpointModelId id = breakHandler()->findBreakpointByIndex(indexUnderMouse); - editBreakpoints(BreakpointModelIds() << id); + if (indexUnderMouse.isValid()) { + if (indexUnderMouse.column() >= 4) { + BreakpointModelId id = breakHandler()->findBreakpointByIndex(indexUnderMouse); + editBreakpoints(BreakpointModelIds() << id); + } + } else { + addBreakpoint(); } - QTreeView::mouseDoubleClickEvent(ev); + BaseTreeView::mouseDoubleClickEvent(ev); } void BreakTreeView::setModel(QAbstractItemModel *model) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 96a627c8e2..e1d41052c6 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -62,6 +62,8 @@ #include <texteditor/itexteditor.h> #include <projectexplorer/abi.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/task.h> +#include <projectexplorer/taskhub.h> #include <utils/synchronousprocess.h> #include <utils/qtcprocess.h> @@ -374,6 +376,7 @@ CdbEngine::CdbEngine(const DebuggerStartParameters &sp, const OptionsPtr &option m_operateByInstruction(true), // Default CDB setting m_notifyEngineShutdownOnTermination(false), m_hasDebuggee(false), + m_cdbIs64Bit(false), m_elapsedLogTime(0), m_sourceStepInto(false), m_watchPointX(0), @@ -639,13 +642,13 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa return false; } - const bool is64bit = + m_cdbIs64Bit = #ifdef Q_OS_WIN Utils::winIs64BitBinary(executable); #else false; #endif - const QFileInfo extensionFi(CdbEngine::extensionLibraryName(is64bit)); + const QFileInfo extensionFi(CdbEngine::extensionLibraryName(m_cdbIs64Bit)); if (!extensionFi.isFile()) { *errorMessage = QString::fromLatin1("Internal error: The extension %1 cannot be found."). arg(QDir::toNativeSeparators(extensionFi.absoluteFilePath())); @@ -667,6 +670,8 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa << QLatin1String(".idle_cmd ") + QString::fromLatin1(m_extensionCommandPrefixBA) + QLatin1String("idle"); if (sp.useTerminal) // Separate console arguments << QLatin1String("-2"); + if (m_options->ignoreFirstChanceAccessViolation) + arguments << QLatin1String("-x"); if (!m_options->symbolPaths.isEmpty()) arguments << QLatin1String("-y") << m_options->symbolPaths.join(QString(QLatin1Char(';'))); if (!m_options->sourcePaths.isEmpty()) @@ -801,7 +806,7 @@ void CdbEngine::runEngine() if (debug) qDebug("runEngine"); foreach (const QString &breakEvent, m_options->breakEvents) - postCommand(QByteArray("sxe ") + breakEvent.toAscii(), 0); + postCommand(QByteArray("sxe ") + breakEvent.toLatin1(), 0); // Break functions: each function must be fully qualified, // else the debugger will slow down considerably. foreach (const QString &breakFunctionS, m_options->breakFunctions) { @@ -1159,7 +1164,9 @@ bool CdbEngine::doInterruptInferior(SpecialStopMode sm) showMessage(QString::fromLatin1("Interrupting process %1...").arg(inferiorPid()), LogMisc); QString errorMessage; - const bool ok = interruptProcess(inferiorPid(), CdbEngineType, &errorMessage); + + const bool ok = interruptProcess(inferiorPid(), CdbEngineType, + &errorMessage, m_cdbIs64Bit); if (!ok) { m_specialStopMode = oldSpecialMode; showMessage(errorMessage, LogError); @@ -1251,7 +1258,7 @@ void CdbEngine::handleJumpToLineAddressResolution(const CdbBuiltinCommandPtr &cm bool ok; const quint64 address = answer.toLongLong(&ok, 16); if (ok && address) { - QTC_ASSERT(qVariantCanConvert<ContextData>(cmd->cookie), return); + QTC_ASSERT(cmd->cookie.canConvert<ContextData>(), return); const ContextData cookie = qvariant_cast<ContextData>(cmd->cookie); jumpToAddress(address); gotoLocation(Location(cookie.fileName, cookie.lineNumber)); @@ -1261,7 +1268,7 @@ void CdbEngine::handleJumpToLineAddressResolution(const CdbBuiltinCommandPtr &cm static inline bool isAsciiWord(const QString &s) { foreach (const QChar &c, s) { - if (!c.isLetterOrNumber() || c.toAscii() == 0) + if (!c.isLetterOrNumber() || c.toLatin1() == 0) return false; } return true; @@ -1304,15 +1311,6 @@ void CdbEngine::assignValueInDebugger(const WatchData *w, const QString &expr, c updateLocals(); } -void CdbEngine::parseThreads(const GdbMi &data, int forceCurrentThreadId /* = -1 */) -{ - int currentThreadId; - Threads threads = ThreadsHandler::parseGdbmiThreads(data, ¤tThreadId); - threadsHandler()->setThreads(threads); - threadsHandler()->setCurrentThreadId(forceCurrentThreadId >= 0 ? - forceCurrentThreadId : currentThreadId); -} - void CdbEngine::handleThreads(const CdbExtensionCommandPtr &reply) { if (debug) @@ -1320,7 +1318,7 @@ void CdbEngine::handleThreads(const CdbExtensionCommandPtr &reply) if (reply->success) { GdbMi data; data.fromString(reply->reply); - parseThreads(data); + threadsHandler()->updateThreads(data); // Continue sequence postCommandSequence(reply->commandSequence); } else { @@ -1516,15 +1514,14 @@ void CdbEngine::updateLocals(bool forNewStackFrame) QVariant(flags)); } -void CdbEngine::selectThread(int index) +void CdbEngine::selectThread(ThreadId threadId) { - if (index < 0 || index == threadsHandler()->currentThread()) + if (!threadId.isValid() || threadId == threadsHandler()->currentThread()) return; - const int newThreadId = threadsHandler()->threads().at(index).id; - threadsHandler()->setCurrentThread(index); + threadsHandler()->setCurrentThread(threadId); - const QByteArray cmd = '~' + QByteArray::number(newThreadId) + " s"; + const QByteArray cmd = '~' + QByteArray::number(threadId.raw()) + " s"; postBuiltinCommand(cmd, 0, &CdbEngine::dummyHandler, CommandListStack); } @@ -1684,7 +1681,7 @@ void CdbEngine::handleResolveSymbol(const QList<quint64> &addresses, const QVari { // Disassembly mode: Determine suitable range containing the // agent's address within the function to display. - if (qVariantCanConvert<DisassemblerAgent*>(cookie)) { + if (cookie.canConvert<DisassemblerAgent*>()) { DisassemblerAgent *agent = cookie.value<DisassemblerAgent *>(); const quint64 agentAddress = agent->address(); quint64 functionAddress = 0; @@ -1723,7 +1720,7 @@ void CdbEngine::handleResolveSymbol(const QList<quint64> &addresses, const QVari // Parse: "00000000`77606060 cc int 3" void CdbEngine::handleDisassembler(const CdbBuiltinCommandPtr &command) { - QTC_ASSERT(qVariantCanConvert<DisassemblerAgent*>(command->cookie), return); + QTC_ASSERT(command->cookie.canConvert<DisassemblerAgent*>(), return); DisassemblerAgent *agent = qvariant_cast<DisassemblerAgent*>(command->cookie); agent->setContents(parseCdbDisassembler(command->reply)); } @@ -1762,7 +1759,7 @@ void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, c void CdbEngine::handleMemory(const CdbExtensionCommandPtr &command) { - QTC_ASSERT(qVariantCanConvert<MemoryViewCookie>(command->cookie), return); + QTC_ASSERT(command->cookie.canConvert<MemoryViewCookie>(), return); const MemoryViewCookie memViewCookie = qvariant_cast<MemoryViewCookie>(command->cookie); if (command->success) { const QByteArray data = QByteArray::fromBase64(command->reply); @@ -2091,7 +2088,6 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason, WinException exception; exception.fromGdbMI(stopReason); QString description = exception.toString(); -#ifdef Q_OS_WIN // It is possible to hit on a startup trap or WOW86 exception while stepping (if something // pulls DLLs. Avoid showing a 'stopped' Message box. if (exception.exceptionCode == winExceptionStartupCompleteTrap @@ -2111,7 +2107,6 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason, *message = msgInterrupted(); return rc; } -#endif *exceptionBoxMessage = msgStoppedByException(description, QString::number(threadId)); *message = description; rc |= StopShowExceptionMessageBox|StopReportStatusMessage|StopNotifyStop; @@ -2181,7 +2176,7 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT // Further examine stop and report to user QString message; QString exceptionBoxMessage; - int forcedThreadId = -1; + ThreadId forcedThreadId; const unsigned stopFlags = examineStopReason(stopReason, &message, &exceptionBoxMessage, conditionalBreakPointTriggered); // Do the non-blocking log reporting @@ -2218,7 +2213,7 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT if (stopFlags & StopInArtificialThread) { showMessage(tr("Switching to main thread..."), LogMisc); postCommand("~0 s", 0); - forcedThreadId = 0; + forcedThreadId = ThreadId(0); // Re-fetch stack again. postCommandSequence(CommandListStack); } else { @@ -2234,7 +2229,9 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT } const GdbMi threads = stopReason.findChild("threads"); if (threads.isValid()) { - parseThreads(threads, forcedThreadId); + threadsHandler()->updateThreads(threads); + if (forcedThreadId.isValid()) + threadsHandler()->setCurrentThread(forcedThreadId); } else { showMessage(QString::fromLatin1(stopReason.findChild("threaderror").data()), LogError); } @@ -2392,10 +2389,20 @@ void CdbEngine::handleExtensionMessage(char t, int token, const QByteArray &what exception.fromGdbMI(gdbmi); const QString message = exception.toString(true); showStatusMessage(message); -#ifdef Q_OS_WIN // Report C++ exception in application output as well. + // Report C++ exception in application output as well. if (exception.exceptionCode == winExceptionCppException) showMessage(message + QLatin1Char('\n'), AppOutput); -#endif + if (!isDebuggerWinException(exception.exceptionCode)) { + const Task::TaskType type = + isFatalWinException(exception.exceptionCode) ? Task::Error : Task::Warning; + const Utils::FileName fileName = exception.file.isEmpty() ? + Utils::FileName() : + Utils::FileName::fromUserInput(QString::fromLocal8Bit(exception.file)); + const Task task(type, exception.toString(false), + fileName, exception.lineNumber, + Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME)); + taskHub()->addTask(task); + } return; } @@ -2892,7 +2899,7 @@ void CdbEngine::handleExpression(const CdbExtensionCommandPtr &command) showMessage(QString::fromLocal8Bit(command->errorMessage), LogError); } // Is this a conditional breakpoint? - if (command->cookie.isValid() && qVariantCanConvert<ConditionalBreakPointCookie>(command->cookie)) { + if (command->cookie.isValid() && command->cookie.canConvert<ConditionalBreakPointCookie>()) { const ConditionalBreakPointCookie cookie = qvariant_cast<ConditionalBreakPointCookie>(command->cookie); const QString message = value ? tr("Value %1 obtained from evaluating the condition of breakpoint %2, stopping."). @@ -2940,7 +2947,7 @@ void CdbEngine::postCommandSequence(unsigned mask) return; } if (mask & CommandListRegisters) { - QTC_ASSERT(threadsHandler()->currentThread() >= 0, return); + QTC_ASSERT(threadsHandler()->currentThreadIndex() >= 0, return); postExtensionCommand("registers", QByteArray(), 0, &CdbEngine::handleRegisters, mask & ~CommandListRegisters); return; } @@ -3101,13 +3108,13 @@ void CdbEngine::postWidgetAtCommand() void CdbEngine::handleCustomSpecialStop(const QVariant &v) { - if (qVariantCanConvert<MemoryChangeCookie>(v)) { - const MemoryChangeCookie changeData = qVariantValue<MemoryChangeCookie>(v); + if (v.canConvert<MemoryChangeCookie>()) { + const MemoryChangeCookie changeData = qvariant_cast<MemoryChangeCookie>(v); postCommand(cdbWriteMemoryCommand(changeData.address, changeData.data), 0); return; } - if (qVariantCanConvert<MemoryViewCookie>(v)) { - postFetchMemory(qVariantValue<MemoryViewCookie>(v)); + if (v.canConvert<MemoryViewCookie>()) { + postFetchMemory(qvariant_cast<MemoryViewCookie>(v)); return; } } diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 28fe96eaa6..faa52543b3 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -32,6 +32,7 @@ #include "debuggerengine.h" #include "breakpoint.h" +#include "threaddata.h" #include <QSharedPointer> #include <QProcess> @@ -113,7 +114,7 @@ public: virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); virtual void activateFrame(int index); - virtual void selectThread(int index); + virtual void selectThread(ThreadId threadId); virtual bool stateAcceptsBreakpointChanges() const; virtual bool acceptsBreakpoint(BreakpointModelId id) const; @@ -242,7 +243,6 @@ private: int elapsedLogTime() const; void addLocalsOptions(ByteArrayInputStream &s) const; unsigned parseStackTrace(const GdbMi &data, bool sourceStepInto); - void parseThreads(const GdbMi &, int forceCurrentThreadId = -1); const QByteArray m_creatorExtPrefix; const QByteArray m_tokenPrefix; @@ -265,6 +265,7 @@ private: bool m_operateByInstruction; bool m_notifyEngineShutdownOnTermination; bool m_hasDebuggee; + bool m_cdbIs64Bit; QTime m_logTime; mutable int m_elapsedLogTime; QByteArray m_extensionMessageBuffer; diff --git a/src/plugins/debugger/cdb/cdboptions.cpp b/src/plugins/debugger/cdb/cdboptions.cpp index ea83f54656..6b890f8eab 100644 --- a/src/plugins/debugger/cdb/cdboptions.cpp +++ b/src/plugins/debugger/cdb/cdboptions.cpp @@ -39,13 +39,17 @@ static const char breakFunctionsKeyC[] = "BreakFunctions"; static const char additionalArgumentsKeyC[] = "AdditionalArguments"; static const char cdbConsoleKeyC[] = "CDB_Console"; static const char breakpointCorrectionKeyC[] = "BreakpointCorrection"; +static const char ignoreFirstChanceAccessViolationKeyC[] = "IgnoreFirstChanceAccessViolation"; namespace Debugger { namespace Internal { const char *CdbOptions::crtDbgReport = "CrtDbgReport"; -CdbOptions::CdbOptions() : cdbConsole(false), breakpointCorrection(true) +CdbOptions::CdbOptions() + : cdbConsole(false) + , breakpointCorrection(true) + , ignoreFirstChanceAccessViolation(false) { } @@ -58,7 +62,8 @@ void CdbOptions::clear() { symbolPaths.clear(); sourcePaths.clear(); - cdbConsole = false; + breakpointCorrection = true; + cdbConsole = ignoreFirstChanceAccessViolation = false; breakEvents.clear(); breakFunctions.clear(); } @@ -79,6 +84,7 @@ void CdbOptions::fromSettings(QSettings *s) breakFunctions = s->value(keyRoot + QLatin1String(breakFunctionsKeyC), QStringList()).toStringList(); cdbConsole = s->value(keyRoot + QLatin1String(cdbConsoleKeyC), QVariant(false)).toBool(); breakpointCorrection = s->value(keyRoot + QLatin1String(breakpointCorrectionKeyC), QVariant(true)).toBool(); + ignoreFirstChanceAccessViolation = s->value(keyRoot + QLatin1String(ignoreFirstChanceAccessViolationKeyC), false).toBool(); } void CdbOptions::toSettings(QSettings *s) const @@ -91,6 +97,7 @@ void CdbOptions::toSettings(QSettings *s) const s->setValue(QLatin1String(additionalArgumentsKeyC), additionalArguments); s->setValue(QLatin1String(cdbConsoleKeyC), QVariant(cdbConsole)); s->setValue(QLatin1String(breakpointCorrectionKeyC), QVariant(breakpointCorrection)); + s->setValue(QLatin1String(ignoreFirstChanceAccessViolationKeyC), QVariant(ignoreFirstChanceAccessViolation)); s->endGroup(); } @@ -98,6 +105,7 @@ bool CdbOptions::equals(const CdbOptions &rhs) const { return cdbConsole == rhs.cdbConsole && breakpointCorrection == rhs.breakpointCorrection + && ignoreFirstChanceAccessViolation == rhs.ignoreFirstChanceAccessViolation && additionalArguments == rhs.additionalArguments && symbolPaths == rhs.symbolPaths && sourcePaths == rhs.sourcePaths diff --git a/src/plugins/debugger/cdb/cdboptions.h b/src/plugins/debugger/cdb/cdboptions.h index 14a29482b4..f0bf82ea7d 100644 --- a/src/plugins/debugger/cdb/cdboptions.h +++ b/src/plugins/debugger/cdb/cdboptions.h @@ -66,6 +66,8 @@ public: bool cdbConsole; // Perform code-model based correction of breakpoint location. bool breakpointCorrection; + // Add -x to command line. + bool ignoreFirstChanceAccessViolation; static const char *crtDbgReport; }; diff --git a/src/plugins/debugger/cdb/cdboptionspage.cpp b/src/plugins/debugger/cdb/cdboptionspage.cpp index 68376982b7..77190c7965 100644 --- a/src/plugins/debugger/cdb/cdboptionspage.cpp +++ b/src/plugins/debugger/cdb/cdboptionspage.cpp @@ -32,6 +32,7 @@ #include "commonoptionspage.h" #include "debuggerinternalconstants.h" #include "cdbengine.h" +#include "cdbsymbolpathlisteditor.h" #include <utils/synchronousprocess.h> @@ -39,7 +40,10 @@ #include <QTextStream> #include <QLineEdit> +#include <QDialogButtonBox> +#include <QPushButton> #include <QCheckBox> +#include <QVBoxLayout> namespace Debugger { namespace Internal { @@ -157,6 +161,46 @@ QStringList CdbBreakEventWidget::breakEvents() const return rc; } +CdbPathDialog::CdbPathDialog(QWidget *parent, Mode mode) + : QDialog(parent) + , m_pathListEditor(0) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setMinimumWidth(700); + + switch (mode) { + case SymbolPaths: + setWindowTitle(tr("CDB Symbol Paths")); + m_pathListEditor = new CdbSymbolPathListEditor(this); + break; + case SourcePaths: + setWindowTitle(tr("CDB Source Paths")); + m_pathListEditor = new Utils::PathListEditor(this); + break; + } + + QVBoxLayout *layout = new QVBoxLayout(this); + QGroupBox *groupBox = new QGroupBox(this); + (new QVBoxLayout(groupBox))->addWidget(m_pathListEditor); + layout->addWidget(groupBox); + QDialogButtonBox *buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, + Qt::Horizontal, this); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + layout->addWidget(buttonBox); +} + +QStringList CdbPathDialog::paths() const +{ + return m_pathListEditor->pathList(); +} + +void CdbPathDialog::setPaths(const QStringList &paths) +{ + m_pathListEditor->setPathList(paths); +} + CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) : QWidget(parent), m_breakEventWidget(new CdbBreakEventWidget) { @@ -165,11 +209,11 @@ CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) : // accommodate all options. This page only shows on // Windows, which has large margins by default. - const int margin = m_ui.verticalLayout->margin(); + const int margin = layout()->margin(); const QMargins margins(margin, margin / 3, margin, margin / 3); m_ui.startupFormLayout->setContentsMargins(margins); - m_ui.pathFormLayout->setContentsMargins(margins); + m_ui.pathGroupBox->layout()->setContentsMargins(margins); m_ui.breakpointLayout->setContentsMargins(margins); QVBoxLayout *eventLayout = new QVBoxLayout; @@ -181,13 +225,35 @@ CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) : const QString hint = tr("This is useful to catch runtime error messages, for example caused by assert()."); m_ui.breakCrtDbgReportCheckBox ->setToolTip(CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(CdbOptions::crtDbgReport, hint)); + + connect(m_ui.symbolPathButton, SIGNAL(clicked()), this, SLOT(showSymbolPathDialog())); + connect(m_ui.sourcePathButton, SIGNAL(clicked()), this, SLOT(showSourcePathDialog())); +} + +void CdbOptionsPageWidget::setSymbolPaths(const QStringList &s) +{ + m_symbolPaths = s; + const QString summary = + tr("Symbol paths: %1").arg(m_symbolPaths.isEmpty() ? + tr("<none>") : QString::number(m_symbolPaths.size())); + m_ui.symbolPathLabel->setText(summary); +} + +void CdbOptionsPageWidget::setSourcePaths(const QStringList &s) +{ + m_sourcePaths = s; + const QString summary = + tr("Source paths: %1").arg(m_sourcePaths.isEmpty() ? + tr("<none>") : QString::number(m_sourcePaths.size())); + m_ui.sourcePathLabel->setText(summary); } void CdbOptionsPageWidget::setOptions(CdbOptions &o) { m_ui.additionalArgumentsLineEdit->setText(o.additionalArguments); setSymbolPaths(o.symbolPaths); - m_ui.sourcePathListEditor->setPathList(o.sourcePaths); + setSourcePaths(o.sourcePaths); + m_ui.ignoreFirstChanceAccessViolationCheckBox->setChecked(o.ignoreFirstChanceAccessViolation); m_breakEventWidget->setBreakEvents(o.breakEvents); m_ui.consoleCheckBox->setChecked(o.cdbConsole); m_ui.breakpointCorrectionCheckBox->setChecked(o.breakpointCorrection); @@ -198,8 +264,9 @@ CdbOptions CdbOptionsPageWidget::options() const { CdbOptions rc; rc.additionalArguments = m_ui.additionalArgumentsLineEdit->text().trimmed(); - rc.symbolPaths = symbolPaths(); - rc.sourcePaths = m_ui.sourcePathListEditor->pathList(); + rc.symbolPaths = m_symbolPaths; + rc.sourcePaths = m_sourcePaths; + rc.ignoreFirstChanceAccessViolation = m_ui.ignoreFirstChanceAccessViolationCheckBox->isChecked(); rc.breakEvents = m_breakEventWidget->breakEvents(); rc.cdbConsole = m_ui.consoleCheckBox->isChecked(); rc.breakpointCorrection = m_ui.breakpointCorrectionCheckBox->isChecked(); @@ -208,21 +275,39 @@ CdbOptions CdbOptionsPageWidget::options() const return rc; } -QStringList CdbOptionsPageWidget::symbolPaths() const +void CdbOptionsPageWidget::showSymbolPathDialog() { - return m_ui.symbolPathListEditor->pathList(); + CdbPathDialog pathDialog(this, CdbPathDialog::SymbolPaths); + pathDialog.setPaths(m_symbolPaths); + if (pathDialog.exec() == QDialog::Accepted) + setSymbolPaths(pathDialog.paths()); } -void CdbOptionsPageWidget::setSymbolPaths(const QStringList &s) +void CdbOptionsPageWidget::showSourcePathDialog() +{ + CdbPathDialog pathDialog(this, CdbPathDialog::SourcePaths); + pathDialog.setPaths(m_sourcePaths); + if (pathDialog.exec() == QDialog::Accepted) + setSourcePaths(pathDialog.paths()); +} + +static QString stripColon(QString s) { - m_ui.symbolPathListEditor->setPathList(s); + const int lastColon = s.lastIndexOf(QLatin1Char(':')); + if (lastColon != -1) + s.truncate(lastColon); + return s; } QString CdbOptionsPageWidget::searchKeywords() const { QString rc; - QTextStream(&rc) << m_ui.symbolPathLabel->text() - << ' ' << m_ui.sourcePathLabel->text(); + QTextStream(&rc) + << stripColon(m_ui.additionalArgumentsLabel->text()) << ' ' + << stripColon(m_ui.breakFunctionGroupBox->title()) << ' ' + << m_ui.breakpointsGroupBox->title() << ' ' + << stripColon(m_ui.symbolPathLabel->text()) << ' ' + << stripColon(m_ui.sourcePathLabel->text()); rc.remove(QLatin1Char('&')); return rc; } diff --git a/src/plugins/debugger/cdb/cdboptionspage.h b/src/plugins/debugger/cdb/cdboptionspage.h index 4c0ff6bf9b..24505eb792 100644 --- a/src/plugins/debugger/cdb/cdboptionspage.h +++ b/src/plugins/debugger/cdb/cdboptionspage.h @@ -38,14 +38,20 @@ #include <QWidget> #include <QPointer> #include <QSharedPointer> +#include <QDialog> QT_BEGIN_NAMESPACE class QCheckBox; QT_END_NAMESPACE +namespace Utils { + class PathListEditor; +} namespace Debugger { namespace Internal { +class CdbSymbolPathListEditor; + // Widget displaying a list of break events for the 'sxe' command // with a checkbox to enable 'break' and optionally a QLineEdit for // events with parameters (like 'out:Needle'). @@ -67,6 +73,24 @@ private: QList<QLineEdit*> m_lineEdits; }; +class CdbPathDialog : public QDialog +{ + Q_OBJECT +public: + enum Mode { + SymbolPaths, + SourcePaths + }; + + explicit CdbPathDialog(QWidget *parent, Mode mode); + + QStringList paths() const; + void setPaths(const QStringList &paths); + +private: + Utils::PathListEditor *m_pathListEditor; +}; + class CdbOptionsPageWidget : public QWidget { Q_OBJECT @@ -79,13 +103,20 @@ public: QString searchKeywords() const; +private slots: + void showSymbolPathDialog(); + void showSourcePathDialog(); + private: - QStringList symbolPaths() const; - void setSymbolPaths(const QStringList &s); + void setSymbolPaths(const QStringList &); + void setSourcePaths(const QStringList &); + inline QString path() const; Ui::CdbOptionsPageWidget m_ui; CdbBreakEventWidget *m_breakEventWidget; + QStringList m_symbolPaths; + QStringList m_sourcePaths; }; class CdbOptionsPage : public Core::IOptionsPage diff --git a/src/plugins/debugger/cdb/cdboptionspagewidget.ui b/src/plugins/debugger/cdb/cdboptionspagewidget.ui index 41b3d6a1ff..647449105f 100644 --- a/src/plugins/debugger/cdb/cdboptionspagewidget.ui +++ b/src/plugins/debugger/cdb/cdboptionspagewidget.ui @@ -12,8 +12,8 @@ </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> <widget class="QGroupBox" name="cdbPathGroupBox"> <property name="title"> <string extracomment="Placeholder">Startup</string> @@ -54,59 +54,99 @@ </layout> </widget> </item> + <item row="0" column="1"> + <widget class="QGroupBox" name="pathGroupBox"> + <property name="title"> + <string>Paths</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="symbolPathLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="symbolPathButton"> + <property name="text"> + <string>Edit...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="sourcePathLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="sourcePathButton"> + <property name="text"> + <string>Edit...</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <widget class="QGroupBox" name="breakpointsGroupBox"> + <property name="title"> + <string>Breakpoints</string> + </property> + <layout class="QVBoxLayout" name="breakpointLayout"> + <item> + <widget class="QCheckBox" name="breakpointCorrectionCheckBox"> + <property name="toolTip"> + <string><html><head/><body><p>Attempt to correct the location of a breakpoint based on file and line number should it be in a comment or in a line for which no code is generated. The correction is based on the code model.</p></body></html></string> + </property> + <property name="text"> + <string>Correct breakpoint location</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="1"> + <widget class="QGroupBox" name="breakFunctionGroupBox"> + <property name="title"> + <string>Break on functions:</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QCheckBox" name="breakCrtDbgReportCheckBox"/> + </item> + </layout> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QGroupBox" name="eventGroupBox"> + <property name="title"> + <string>Break on:</string> + </property> + </widget> + </item> </layout> </item> <item> - <widget class="QGroupBox" name="startupGroupBox"> + <widget class="QGroupBox" name="variousGroupBox"> <property name="title"> - <string>Debugger Paths</string> + <string>Various</string> </property> - <layout class="QFormLayout" name="pathFormLayout"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="symbolPathLabel"> - <property name="text"> - <string>&Symbol paths:</string> - </property> - <property name="buddy"> - <cstring>symbolPathListEditor</cstring> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="Debugger::Internal::CdbSymbolPathListEditor" name="symbolPathListEditor" native="true"/> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="sourcePathLabel"> - <property name="text"> - <string>S&ource paths:</string> - </property> - <property name="buddy"> - <cstring>sourcePathListEditor</cstring> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="Utils::PathListEditor" name="sourcePathListEditor" native="true"/> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="breakpointsGroupBox"> - <property name="title"> - <string>Breakpoints</string> - </property> - <layout class="QVBoxLayout" name="breakpointLayout"> + <layout class="QVBoxLayout" name="verticalLayout_3"> <item> - <widget class="QCheckBox" name="breakpointCorrectionCheckBox"> - <property name="toolTip"> - <string><html><head/><body><p>Attempt to correct the location of a breakpoint based on file and line number should it be in a comment or in a line for which no code is generated. The correction is based on the code model.</p></body></html></string> - </property> + <widget class="QCheckBox" name="ignoreFirstChanceAccessViolationCheckBox"> <property name="text"> - <string>Correct breakpoint location</string> + <string>Ignore first chance access violations</string> </property> </widget> </item> @@ -114,25 +154,6 @@ </widget> </item> <item> - <widget class="QGroupBox" name="eventGroupBox"> - <property name="title"> - <string>Break on:</string> - </property> - </widget> - </item> - <item> - <widget class="QGroupBox" name="breakFunctionGroupBox"> - <property name="title"> - <string>Break on functions:</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QCheckBox" name="breakCrtDbgReportCheckBox"/> - </item> - </layout> - </widget> - </item> - <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -147,20 +168,6 @@ </item> </layout> </widget> - <customwidgets> - <customwidget> - <class>Utils::PathListEditor</class> - <extends>QWidget</extends> - <header location="global">utils/pathlisteditor.h</header> - <container>1</container> - </customwidget> - <customwidget> - <class>Debugger::Internal::CdbSymbolPathListEditor</class> - <extends>QWidget</extends> - <header location="global">cdbsymbolpathlisteditor.h</header> - <container>1</container> - </customwidget> - </customwidgets> <resources/> <connections/> </ui> diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.cpp b/src/plugins/debugger/cdb/cdbparsehelpers.cpp index c1d6f40c8d..02afae5abe 100644 --- a/src/plugins/debugger/cdb/cdbparsehelpers.cpp +++ b/src/plugins/debugger/cdb/cdbparsehelpers.cpp @@ -263,7 +263,7 @@ static inline bool parseThread(QByteArray line, ThreadData *thread, bool *curren thread->targetId = QLatin1String("0x") + QString::fromLatin1(pidTid.mid(dotPos + 1)); } case 1: - thread->id = tokens.at(0).toInt(); + thread->id = ThreadId(tokens.at(0).toInt()); break; } // switch size return true; @@ -413,10 +413,10 @@ QString WinException::toString(bool includeLocation) const { QString rc; QTextStream str(&rc); -#ifdef Q_OS_WIN formatWindowsException(exceptionCode, exceptionAddress, exceptionFlags, info1, info2, str); -#endif + if (firstChance) + str << " (first chance)"; if (includeLocation) { if (lineNumber) { str << " at " << QLatin1String(file) << ':' << lineNumber; @@ -555,7 +555,7 @@ bool parseCdbDisassemblerLine(const QString &line, DisassemblerLine *dLine, uint dLine->address = addressS.toULongLong(&ok, 16); if (!ok) return false; - dLine->rawData = QByteArray::fromHex(line.mid(rawDataPos, rawDataEnd - rawDataPos).toAscii()); + dLine->rawData = QByteArray::fromHex(line.mid(rawDataPos, rawDataEnd - rawDataPos).toLatin1()); dLine->data = line.right(line.size() - instructionPos).trimmed(); return true; } diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp index b93ff04f7b..ed128cb47b 100644 --- a/src/plugins/debugger/commonoptionspage.cpp +++ b/src/plugins/debugger/commonoptionspage.cpp @@ -36,11 +36,12 @@ #include <coreplugin/icore.h> #include <coreplugin/manhattanstyle.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <projectexplorer/projectexplorer.h> -#include <QFileInfo> +#include <QLabel> #include <QTextStream> using namespace Core; @@ -54,29 +55,113 @@ CommonOptionsPageWidget::CommonOptionsPageWidget (const QSharedPointer<Utils::SavedActionSet> &group, QWidget *parent) : QWidget(parent), m_group(group) { - m_ui.setupUi(this); + QGroupBox *behaviorBox = new QGroupBox(this); + behaviorBox->setTitle(tr("Behavior")); + + checkBoxUseAlternatingRowColors = new QCheckBox(behaviorBox); + checkBoxUseAlternatingRowColors->setText(tr("Use alternating row colors in debug views")); + + checkBoxFontSizeFollowsEditor = new QCheckBox(behaviorBox); + checkBoxFontSizeFollowsEditor->setToolTip(tr("Change the font size in the debugger views when the font size in the main editor changes.")); + checkBoxFontSizeFollowsEditor->setText(tr("Debugger font size follows main editor")); + + checkBoxUseToolTipsInMainEditor = new QCheckBox(behaviorBox); + checkBoxUseToolTipsInMainEditor->setText(tr("Use tooltips in main editor while debugging")); + + checkBoxListSourceFiles = new QCheckBox(behaviorBox); + checkBoxListSourceFiles->setToolTip(tr("Populate the source file view automatically. This might slow down debugger startup considerably.")); + checkBoxListSourceFiles->setText(tr("Populate source file view automatically")); + + checkBoxCloseBuffersOnExit = new QCheckBox(behaviorBox); + checkBoxCloseBuffersOnExit->setText(tr("Close temporary buffers on debugger exit")); + + checkBoxSwitchModeOnExit = new QCheckBox(behaviorBox); + checkBoxSwitchModeOnExit->setText(tr("Switch to previous mode on debugger exit")); + + checkBoxBringToForegroundOnInterrrupt = new QCheckBox(behaviorBox); + checkBoxBringToForegroundOnInterrrupt->setText(tr("Bring Qt Creator to foreground when application interrupts")); + + checkBoxShowQmlObjectTree = new QCheckBox(behaviorBox); + checkBoxShowQmlObjectTree->setToolTip(tr("Show QML object tree in Locals & Expressions when connected and not stepping.")); + checkBoxShowQmlObjectTree->setText(tr("Show QML object tree")); + + checkBoxBreakpointsFullPath = new QCheckBox(behaviorBox); + checkBoxBreakpointsFullPath->setToolTip(tr("Enable a full file path in breakpoints by default also for the GDB")); + checkBoxBreakpointsFullPath->setText(tr("Breakpoints full path by default")); + + checkBoxRegisterForPostMortem = new QCheckBox(behaviorBox); + checkBoxRegisterForPostMortem->setToolTip(tr("Register Qt Creator for debugging crashed applications.")); + checkBoxRegisterForPostMortem->setText(tr("Use Qt Creator for post-mortem debugging")); + + labelMaximalStackDepth = new QLabel(tr("Maximum stack depth:"), behaviorBox); + + spinBoxMaximalStackDepth = new QSpinBox(behaviorBox); + spinBoxMaximalStackDepth->setSpecialValueText(tr("<unlimited>")); + spinBoxMaximalStackDepth->setMaximum(999); + spinBoxMaximalStackDepth->setSingleStep(5); + spinBoxMaximalStackDepth->setValue(10); + + labelMaximalStringLength = new QLabel(tr("Maximum string length:"), behaviorBox); + + spinBoxMaximalStringLength = new QSpinBox(behaviorBox); + spinBoxMaximalStringLength->setSpecialValueText(tr("<unlimited>")); + spinBoxMaximalStringLength->setMaximum(10000000); + spinBoxMaximalStringLength->setSingleStep(1000); + spinBoxMaximalStringLength->setValue(10000); + + sourcesMappingWidget = new DebuggerSourcePathMappingWidget(this); + + QHBoxLayout *horizontalLayout = new QHBoxLayout(); + horizontalLayout->addWidget(labelMaximalStackDepth); + horizontalLayout->addWidget(spinBoxMaximalStackDepth); + horizontalLayout->addStretch(); + + QHBoxLayout *horizontalLayout2 = new QHBoxLayout(); + horizontalLayout2->addWidget(labelMaximalStringLength); + horizontalLayout2->addWidget(spinBoxMaximalStringLength); + horizontalLayout2->addStretch(); + + QGridLayout *gridLayout = new QGridLayout(behaviorBox); + gridLayout->addWidget(checkBoxUseAlternatingRowColors, 0, 0, 1, 1); + gridLayout->addWidget(checkBoxUseToolTipsInMainEditor, 1, 0, 1, 1); + gridLayout->addWidget(checkBoxCloseBuffersOnExit, 2, 0, 1, 1); + gridLayout->addWidget(checkBoxBringToForegroundOnInterrrupt, 3, 0, 1, 1); + gridLayout->addWidget(checkBoxBreakpointsFullPath, 4, 0, 1, 1); + gridLayout->addLayout(horizontalLayout, 6, 0, 1, 2); + + gridLayout->addWidget(checkBoxFontSizeFollowsEditor, 0, 1, 1, 1); + gridLayout->addWidget(checkBoxListSourceFiles, 1, 1, 1, 1); + gridLayout->addWidget(checkBoxSwitchModeOnExit, 2, 1, 1, 1); + gridLayout->addWidget(checkBoxShowQmlObjectTree, 3, 1, 1, 1); + gridLayout->addWidget(checkBoxRegisterForPostMortem, 4, 1, 1, 1); + gridLayout->addLayout(horizontalLayout2, 6, 1, 1, 2); + + QVBoxLayout *verticalLayout = new QVBoxLayout(this); + verticalLayout->addWidget(behaviorBox); + verticalLayout->addWidget(sourcesMappingWidget); + verticalLayout->addStretch(); DebuggerCore *dc = debuggerCore(); m_group->clear(); m_group->insert(dc->action(ListSourceFiles), - m_ui.checkBoxListSourceFiles); + checkBoxListSourceFiles); m_group->insert(dc->action(UseAlternatingRowColors), - m_ui.checkBoxUseAlternatingRowColors); + checkBoxUseAlternatingRowColors); m_group->insert(dc->action(UseToolTipsInMainEditor), - m_ui.checkBoxUseToolTipsInMainEditor); + checkBoxUseToolTipsInMainEditor); m_group->insert(dc->action(CloseBuffersOnExit), - m_ui.checkBoxCloseBuffersOnExit); + checkBoxCloseBuffersOnExit); m_group->insert(dc->action(SwitchModeOnExit), - m_ui.checkBoxSwitchModeOnExit); + checkBoxSwitchModeOnExit); m_group->insert(dc->action(BreakpointsFullPathByDefault), - m_ui.checkBoxBreakpointsFullPath); + checkBoxBreakpointsFullPath); m_group->insert(dc->action(RaiseOnInterrupt), - m_ui.checkBoxBringToForegroundOnInterrrupt); + checkBoxBringToForegroundOnInterrrupt); m_group->insert(dc->action(ShowQmlObjectTree), - m_ui.checkBoxShowQmlObjectTree); + checkBoxShowQmlObjectTree); m_group->insert(dc->action(FontSizeFollowsEditor), - m_ui.checkBoxFontSizeFollowsEditor); + checkBoxFontSizeFollowsEditor); m_group->insert(dc->action(AutoDerefPointers), 0); m_group->insert(dc->action(UseToolTipsInLocalsView), 0); m_group->insert(dc->action(AlwaysAdjustLocalsColumnWidths), 0); @@ -88,8 +173,8 @@ CommonOptionsPageWidget::CommonOptionsPageWidget m_group->insert(dc->action(UseAddressInBreakpointsView), 0); m_group->insert(dc->action(UseAddressInStackView), 0); m_group->insert(dc->action(AlwaysAdjustStackColumnWidths), 0); - m_group->insert(dc->action(MaximalStackDepth), - m_ui.spinBoxMaximalStackDepth); + m_group->insert(dc->action(MaximalStackDepth), spinBoxMaximalStackDepth); + m_group->insert(dc->action(MaximalStringLength), spinBoxMaximalStringLength); m_group->insert(dc->action(ShowStdNamespace), 0); m_group->insert(dc->action(ShowQtNamespace), 0); m_group->insert(dc->action(SortStructMembers), 0); @@ -97,36 +182,35 @@ CommonOptionsPageWidget::CommonOptionsPageWidget m_group->insert(dc->action(VerboseLog), 0); m_group->insert(dc->action(BreakOnThrow), 0); m_group->insert(dc->action(BreakOnCatch), 0); -#ifdef Q_OS_WIN - Utils::SavedAction *registerAction = dc->action(RegisterForPostMortem); - m_group->insert(registerAction, - m_ui.checkBoxRegisterForPostMortem); - connect(registerAction, SIGNAL(toggled(bool)), - m_ui.checkBoxRegisterForPostMortem, SLOT(setChecked(bool))); -#else - m_ui.checkBoxRegisterForPostMortem->setVisible(false); -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + Utils::SavedAction *registerAction = dc->action(RegisterForPostMortem); + m_group->insert(registerAction, + checkBoxRegisterForPostMortem); + connect(registerAction, SIGNAL(toggled(bool)), + checkBoxRegisterForPostMortem, SLOT(setChecked(bool))); + } else { + checkBoxRegisterForPostMortem->setVisible(false); + } } QString CommonOptionsPageWidget::searchKeyWords() const { QString rc; const QLatin1Char sep(' '); - QTextStream(&rc) - << sep << m_ui.checkBoxUseAlternatingRowColors->text() - << sep << m_ui.checkBoxFontSizeFollowsEditor->text() - << sep << m_ui.checkBoxUseToolTipsInMainEditor->text() - << sep << m_ui.checkBoxListSourceFiles->text() - << sep << m_ui.checkBoxBreakpointsFullPath->text() -#ifdef Q_OS_WIN - << sep << m_ui.checkBoxRegisterForPostMortem->text() -#endif - << sep << m_ui.checkBoxCloseBuffersOnExit->text() - << sep << m_ui.checkBoxSwitchModeOnExit->text() - << sep << m_ui.labelMaximalStackDepth->text() - << sep << m_ui.checkBoxBringToForegroundOnInterrrupt->text() - << sep << m_ui.checkBoxShowQmlObjectTree->text() - ; + QTextStream stream(&rc); + stream << sep << checkBoxUseAlternatingRowColors->text() + << sep << checkBoxFontSizeFollowsEditor->text() + << sep << checkBoxUseToolTipsInMainEditor->text() + << sep << checkBoxListSourceFiles->text() + << sep << checkBoxBreakpointsFullPath->text() + << sep << checkBoxCloseBuffersOnExit->text() + << sep << checkBoxSwitchModeOnExit->text() + << sep << labelMaximalStackDepth->text() + << sep << checkBoxBringToForegroundOnInterrrupt->text() + << sep << checkBoxShowQmlObjectTree->text(); + if (Utils::HostOsInfo::isWindowsHost()) + stream << sep << checkBoxRegisterForPostMortem->text(); + rc.remove(QLatin1Char('&')); return rc; } @@ -134,13 +218,13 @@ QString CommonOptionsPageWidget::searchKeyWords() const GlobalDebuggerOptions CommonOptionsPageWidget::globalOptions() const { GlobalDebuggerOptions o; - o.sourcePathMap = m_ui.sourcesMappingWidget->sourcePathMap(); + o.sourcePathMap = sourcesMappingWidget->sourcePathMap(); return o; } void CommonOptionsPageWidget::setGlobalOptions(const GlobalDebuggerOptions &go) { - m_ui.sourcesMappingWidget->setSourcePathMap(go.sourcePathMap); + sourcesMappingWidget->setSourcePathMap(go.sourcePathMap); } /////////////////////////////////////////////////////////////////////// diff --git a/src/plugins/debugger/commonoptionspage.h b/src/plugins/debugger/commonoptionspage.h index 6b0ebf67e4..b018c2b94a 100644 --- a/src/plugins/debugger/commonoptionspage.h +++ b/src/plugins/debugger/commonoptionspage.h @@ -30,18 +30,21 @@ #ifndef DEBUGGER_COMMONOPTIONSPAGE_H #define DEBUGGER_COMMONOPTIONSPAGE_H -#include "ui_commonoptionspage.h" +#include "debuggersourcepathmappingwidget.h" #include "ui_localsandexpressionsoptionspage.h" #include <coreplugin/dialogs/ioptionspage.h> #include <utils/savedaction.h> -#include <QSharedPointer> +#include <QCheckBox> +#include <QLabel> #include <QPointer> -#include <QWidget> +#include <QSharedPointer> +#include <QSpinBox> namespace Debugger { namespace Internal { + class GlobalDebuggerOptions; /////////////////////////////////////////////////////////////////////// @@ -60,7 +63,22 @@ public: void setGlobalOptions(const GlobalDebuggerOptions &go); private: - Ui::CommonOptionsPage m_ui; + QCheckBox *checkBoxUseAlternatingRowColors; + QCheckBox *checkBoxFontSizeFollowsEditor; + QCheckBox *checkBoxUseToolTipsInMainEditor; + QCheckBox *checkBoxListSourceFiles; + QCheckBox *checkBoxCloseBuffersOnExit; + QCheckBox *checkBoxSwitchModeOnExit; + QCheckBox *checkBoxBringToForegroundOnInterrrupt; + QCheckBox *checkBoxShowQmlObjectTree; + QCheckBox *checkBoxBreakpointsFullPath; + QCheckBox *checkBoxRegisterForPostMortem; + QLabel *labelMaximalStackDepth; + QLabel *labelMaximalStringLength; + QSpinBox *spinBoxMaximalStackDepth; + QSpinBox *spinBoxMaximalStringLength; + + DebuggerSourcePathMappingWidget *sourcesMappingWidget; const QSharedPointer<Utils::SavedActionSet> m_group; }; diff --git a/src/plugins/debugger/commonoptionspage.ui b/src/plugins/debugger/commonoptionspage.ui deleted file mode 100644 index d31e3c85ec..0000000000 --- a/src/plugins/debugger/commonoptionspage.ui +++ /dev/null @@ -1,194 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>Debugger::Internal::CommonOptionsPage</class> - <widget class="QWidget" name="Debugger::Internal::CommonOptionsPage"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>765</width> - <height>341</height> - </rect> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QGroupBox" name="behaviorBox"> - <property name="title"> - <string>Behavior</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QCheckBox" name="checkBoxUseAlternatingRowColors"> - <property name="text"> - <string>Use alternating row colors in debug views</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QCheckBox" name="checkBoxFontSizeFollowsEditor"> - <property name="toolTip"> - <string>Change the font size in the debugger views when the font size in the main editor changes.</string> - </property> - <property name="text"> - <string>Debugger font size follows main editor</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QCheckBox" name="checkBoxUseToolTipsInMainEditor"> - <property name="text"> - <string>Use tooltips in main editor while debugging</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QCheckBox" name="checkBoxListSourceFiles"> - <property name="toolTip"> - <string>Populate the source file view automatically. This might slow down debugger startup considerably.</string> - </property> - <property name="text"> - <string>Populate source file view automatically</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QCheckBox" name="checkBoxCloseBuffersOnExit"> - <property name="text"> - <string>Close temporary buffers on debugger exit</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QCheckBox" name="checkBoxSwitchModeOnExit"> - <property name="text"> - <string>Switch to previous mode on debugger exit</string> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QCheckBox" name="checkBoxBringToForegroundOnInterrrupt"> - <property name="text"> - <string>Bring Qt Creator to foreground when application interrupts</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QCheckBox" name="checkBoxShowQmlObjectTree"> - <property name="toolTip"> - <string>Show QML object tree in Locals & Expressions when connected and not stepping.</string> - </property> - <property name="text"> - <string>Show QML object tree</string> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QCheckBox" name="checkBoxBreakpointsFullPath"> - <property name="toolTip"> - <string>Enable a full file path in breakpoints by default also for the GDB</string> - </property> - <property name="text"> - <string>Breakpoints full path by default</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QCheckBox" name="checkBoxRegisterForPostMortem"> - <property name="toolTip"> - <string>Register Qt Creator for debugging crashed applications.</string> - </property> - <property name="text"> - <string>Use Qt Creator for post-mortem debugging</string> - </property> - </widget> - </item> - <item row="6" column="0" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="labelMaximalStackDepth"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Maximum stack depth:</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinBoxMaximalStackDepth"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="specialValueText"> - <string><unlimited></string> - </property> - <property name="maximum"> - <number>999</number> - </property> - <property name="singleStep"> - <number>5</number> - </property> - <property name="value"> - <number>10</number> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::MinimumExpanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <widget class="Debugger::Internal::DebuggerSourcePathMappingWidget" name="sourcesMappingWidget"/> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::MinimumExpanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>Debugger::Internal::DebuggerSourcePathMappingWidget</class> - <extends>QGroupBox</extends> - <header>debuggersourcepathmappingwidget.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index fa66556673..57dd431b9d 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -70,12 +70,6 @@ HEADERS += \ debuggertooltipmanager.h \ debuggersourcepathmappingwidget.h \ memoryview.h \ - qtmessagelogwindow.h \ - qtmessagelogeditor.h \ - qtmessagelogview.h \ - qtmessagelogproxymodel.h \ - qtmessagelogitemdelegate.h \ - qtmessageloghandler.h \ localsandexpressionswindow.h SOURCES += \ @@ -123,17 +117,10 @@ SOURCES += \ debuggertooltipmanager.cpp \ debuggersourcepathmappingwidget.cpp \ memoryview.cpp \ - qtmessagelogwindow.cpp \ - qtmessagelogproxymodel.cpp \ - qtmessagelogview.cpp \ - qtmessagelogitemdelegate.cpp \ - qtmessageloghandler.cpp \ - qtmessagelogeditor.cpp \ localsandexpressionswindow.cpp FORMS += \ - localsandexpressionsoptionspage.ui \ - commonoptionspage.ui + localsandexpressionsoptionspage.ui RESOURCES += debugger.qrc diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs index eede402cfc..3548700b3f 100644 --- a/src/plugins/debugger/debugger.qbs +++ b/src/plugins/debugger/debugger.qbs @@ -1,6 +1,7 @@ import qbs.base 1.0 import "../QtcPlugin.qbs" as QtcPlugin +import "../../../qbs/defaults.js" as Defaults QtcPlugin { name: "Debugger" @@ -19,32 +20,23 @@ QtcPlugin { Depends { name: "QtcSsh" } Depends { name: "cpp" } - cpp.includePaths: [ - ".", + cpp.includePaths: base.concat([ "shared", "lldb", - "..", - "../../libs", "../../shared/json", - buildDirectory, - "../../libs/utils", - "../../shared/registryaccess/" - ] + "../../shared/registryaccess" + ]) Group { - condition: qbs.buildVariant === "debug" + condition: Defaults.testsEnabled(qbs) qbs.installDir: "tests/manual/debugger/simple/" fileTags: ["install"] files: ["../../../tests/manual/debugger/simple/simple.pro"] } files: [ - "debugger.qrc", - "debuggerkitconfigwidget.cpp", - "debuggerkitconfigwidget.h", - "debuggerkitinformation.cpp", - "debuggerkitinformation.h", "basewindow.cpp", + "basewindow.h", "breakhandler.cpp", "breakhandler.h", "breakpoint.cpp", @@ -55,17 +47,27 @@ QtcPlugin { "breakwindow.h", "commonoptionspage.cpp", "commonoptionspage.h", - "commonoptionspage.ui", + "debugger.qrc", "debugger_global.h", + "debuggeractions.cpp", + "debuggeractions.h", + "debuggerconstants.h", "debuggercore.h", "debuggerdialogs.cpp", "debuggerdialogs.h", "debuggerengine.cpp", "debuggerengine.h", "debuggerinternalconstants.h", + "debuggerkitconfigwidget.cpp", + "debuggerkitconfigwidget.h", + "debuggerkitinformation.cpp", + "debuggerkitinformation.h", "debuggermainwindow.cpp", "debuggermainwindow.h", + "debuggerplugin.cpp", "debuggerplugin.h", + "debuggerruncontrolfactory.h", + "debuggerrunner.cpp", "debuggerrunner.h", "debuggersourcepathmappingwidget.cpp", "debuggersourcepathmappingwidget.h", @@ -98,18 +100,6 @@ QtcPlugin { "outputcollector.h", "procinterrupt.cpp", "procinterrupt.h", - "qtmessagelogwindow.h", - "qtmessagelogeditor.h", - "qtmessagelogview.h", - "qtmessagelogproxymodel.h", - "qtmessagelogitemdelegate.h", - "qtmessageloghandler.h", - "qtmessagelogwindow.cpp", - "qtmessagelogproxymodel.cpp", - "qtmessagelogview.cpp", - "qtmessagelogitemdelegate.cpp", - "qtmessageloghandler.cpp", - "qtmessagelogeditor.cpp", "registerhandler.cpp", "registerhandler.h", "registerwindow.cpp", @@ -145,13 +135,6 @@ QtcPlugin { "watchutils.h", "watchwindow.cpp", "watchwindow.h", - "basewindow.h", - "debuggeractions.cpp", - "debuggeractions.h", - "debuggerconstants.h", - "debuggerplugin.cpp", - "debuggerruncontrolfactory.h", - "debuggerrunner.cpp", "cdb/bytearrayinputstream.cpp", "cdb/bytearrayinputstream.h", "cdb/cdbengine.cpp", @@ -163,17 +146,21 @@ QtcPlugin { "cdb/cdboptionspagewidget.ui", "cdb/cdbparsehelpers.cpp", "cdb/cdbparsehelpers.h", - "gdb/gdb.qrc", "gdb/abstractgdbprocess.cpp", "gdb/abstractgdbprocess.h", "gdb/abstractplaingdbadapter.cpp", "gdb/abstractplaingdbadapter.h", + "gdb/attachgdbadapter.cpp", "gdb/attachgdbadapter.h", + "gdb/classicgdbengine.cpp", "gdb/coregdbadapter.cpp", "gdb/coregdbadapter.h", + "gdb/gdb.qrc", "gdb/gdbengine.cpp", + "gdb/gdbengine.h", "gdb/gdbmi.cpp", "gdb/gdbmi.h", + "gdb/gdboptionspage.cpp", "gdb/gdboptionspage.h", "gdb/localgdbprocess.cpp", "gdb/localgdbprocess.h", @@ -186,14 +173,10 @@ QtcPlugin { "gdb/remotegdbserveradapter.h", "gdb/remoteplaingdbadapter.cpp", "gdb/remoteplaingdbadapter.h", - "gdb/termgdbadapter.h", - "gdb/attachgdbadapter.cpp", - "gdb/classicgdbengine.cpp", - "gdb/gdbengine.h", - "gdb/gdboptionspage.cpp", - "gdb/termgdbadapter.cpp", "gdb/startgdbserverdialog.cpp", "gdb/startgdbserverdialog.h", + "gdb/termgdbadapter.cpp", + "gdb/termgdbadapter.h", "images/breakpoint_16.png", "images/breakpoint_24.png", "images/breakpoint_disabled_16.png", @@ -226,29 +209,40 @@ QtcPlugin { "images/location_24.png", "images/tracepoint.png", "images/watchpoint.png", + "lldb/ipcenginehost.cpp", + "lldb/ipcenginehost.h", + "lldb/lldbenginehost.cpp", + "lldb/lldbenginehost.h", + "namedemangler/demanglerexceptions.h", + "namedemangler/globalparsestate.cpp", + "namedemangler/globalparsestate.h", + "namedemangler/namedemangler.cpp", + "namedemangler/namedemangler.h", + "namedemangler/parsetreenodes.cpp", + "namedemangler/parsetreenodes.h", "pdb/pdbengine.cpp", "pdb/pdbengine.h", - "qml/qmlengine.h", - "qml/qmladapter.h", + "qml/baseqmldebuggerclient.cpp", "qml/baseqmldebuggerclient.h", - "qml/qmlcppengine.h", - "qml/qscriptdebuggerclient.h", - "qml/qmlv8debuggerclient.h", + "qml/interactiveinterpreter.cpp", "qml/interactiveinterpreter.h", - "qml/qmlv8debuggerclientconstants.h", - "qml/qmlengine.cpp", "qml/qmladapter.cpp", - "qml/baseqmldebuggerclient.cpp", + "qml/qmladapter.h", "qml/qmlcppengine.cpp", - "qml/qscriptdebuggerclient.cpp", - "qml/qmlv8debuggerclient.cpp", - "qml/interactiveinterpreter.cpp", + "qml/qmlcppengine.h", + "qml/qmlengine.cpp", + "qml/qmlengine.h", "qml/qmlinspectoradapter.cpp", "qml/qmlinspectoradapter.h", "qml/qmlinspectoragent.cpp", "qml/qmlinspectoragent.h", "qml/qmllivetextpreview.cpp", "qml/qmllivetextpreview.h", + "qml/qmlv8debuggerclient.cpp", + "qml/qmlv8debuggerclient.h", + "qml/qmlv8debuggerclientconstants.h", + "qml/qscriptdebuggerclient.cpp", + "qml/qscriptdebuggerclient.h", "script/scriptengine.cpp", "script/scriptengine.h", "shared/backtrace.cpp", @@ -257,17 +251,6 @@ QtcPlugin { "shared/cdbsymbolpathlisteditor.h", "shared/hostutils.cpp", "shared/hostutils.h", - "lldb/ipcenginehost.cpp", - "lldb/ipcenginehost.h", - "lldb/lldbenginehost.cpp", - "lldb/lldbenginehost.h", - "namedemangler/namedemangler.cpp", - "namedemangler/namedemangler.h", - "namedemangler/parsetreenodes.cpp", - "namedemangler/parsetreenodes.h", - "namedemangler/demanglerexceptions.h", - "namedemangler/globalparsestate.h", - "namedemangler/globalparsestate.cpp" ] Group { @@ -275,7 +258,7 @@ QtcPlugin { prefix: "../../shared/registryaccess/" files: [ "registryaccess.cpp", - "registryaccess.h" + "registryaccess.h", ] } @@ -285,7 +268,7 @@ QtcPlugin { "registerpostmortemaction.cpp", "registerpostmortemaction.h", "shared/peutils.cpp", - "shared/peutils.h" + "shared/peutils.h", ] } @@ -294,7 +277,7 @@ QtcPlugin { files: [ "lldb/lldboptionspage.cpp", "lldb/lldboptionspage.h", - "lldb/lldboptionspagewidget.ui" + "lldb/lldboptionspagewidget.ui", ] } @@ -313,4 +296,3 @@ QtcPlugin { cpp.includePaths: ["."] } } - diff --git a/src/plugins/debugger/debugger.qrc b/src/plugins/debugger/debugger.qrc index a75fb1625e..b1e7d73495 100644 --- a/src/plugins/debugger/debugger.qrc +++ b/src/plugins/debugger/debugger.qrc @@ -30,12 +30,6 @@ <file>images/location_16.png</file> <file>images/location_24.png</file> <file>images/pin.xpm</file> - <file>images/collapse.png</file> - <file>images/error.png</file> - <file>images/expand.png</file> - <file>images/log.png</file> - <file>images/prompt.png</file> - <file>images/warning.png</file> <file>images/qml/zoom.png</file> <file>images/qml/select.png</file> <file>images/qml/app-on-top.png</file> diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 7aa81d784f..a80ad358b6 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -397,6 +397,11 @@ DebuggerSettings::DebuggerSettings(QSettings *settings) insertItem(GdbStartupCommands, item); item = new SavedAction(this); + item->setSettingsKey(debugModeGroup, QLatin1String("GdbPostAttachCommands")); + item->setDefaultValue(QString()); + insertItem(GdbPostAttachCommands, item); + + item = new SavedAction(this); item->setSettingsKey(debugModeGroup, QLatin1String("CloseBuffersOnExit")); item->setCheckable(true); item->setDefaultValue(false); @@ -434,6 +439,18 @@ DebuggerSettings::DebuggerSettings(QSettings *settings) insertItem(AttemptQuickStart, item); item = new SavedAction(this); + item->setSettingsKey(debugModeGroup, QLatin1String("MultiInferior")); + item->setCheckable(true); + item->setDefaultValue(false); + insertItem(MultiInferior, item); + + item = new SavedAction(this); + item->setSettingsKey(debugModeGroup, QLatin1String("IntelFlavor")); + item->setCheckable(true); + item->setDefaultValue(false); + insertItem(IntelFlavor, item); + + item = new SavedAction(this); item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTips")); item->setText(tr("Use tooltips in main editor when debugging")); item->setToolTip(tr("Checking this will enable tooltips for variable " @@ -536,6 +553,11 @@ DebuggerSettings::DebuggerSettings(QSettings *settings) insertItem(MaximalStackDepth, item); item = new SavedAction(this); + item->setSettingsKey(debugModeGroup, QLatin1String("MaximalStringLength")); + item->setDefaultValue(10000); + insertItem(MaximalStringLength, item); + + item = new SavedAction(this); item->setText(tr("Reload Full Stack")); insertItem(ExpandStack, item); diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 68cb565a5e..358f87f943 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -119,11 +119,14 @@ enum DebuggerActionCode LoadGdbInit, AttemptQuickStart, GdbStartupCommands, + GdbPostAttachCommands, GdbWatchdogTimeout, AutoEnrichParameters, UseDynamicType, TargetAsync, WarnOnReleaseBuilds, + MultiInferior, + IntelFlavor, // Stack MaximalStackDepth, @@ -137,6 +140,7 @@ enum DebuggerActionCode SortStructMembers, AutoDerefPointers, AlwaysAdjustLocalsColumnWidths, + MaximalStringLength, // Source List ListSourceFiles, diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index d8815540f0..eb5d41090e 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -74,8 +74,11 @@ const char DOCKWIDGET_THREADS[] = "Debugger.Docks.Threads"; const char DOCKWIDGET_WATCHERS[] = "Debugger.Docks.LocalsAndWatchers"; const char DOCKWIDGET_QML_INSPECTOR[] = "Debugger.Docks.QmlInspector"; -const char DOCKWIDGET_QML_SCRIPTCONSOLE[] = "Debugger.Docks.ScriptConsole"; const char DOCKWIDGET_DEFAULT_AREA[] = "Debugger.Docks.DefaultArea"; + +const char TASK_CATEGORY_DEBUGGER_TEST[] = "DebuggerTest"; +const char TASK_CATEGORY_DEBUGGER_DEBUGINFO[] = "Debuginfo"; +const char TASK_CATEGORY_DEBUGGER_RUNTIME[] = "DebugRuntime"; } // namespace Constants enum DebuggerState @@ -164,7 +167,8 @@ enum DebuggerCapabilities CatchCapability = 0x200000, //!< fork, vfork, syscall OperateByInstructionCapability = 0x400000, RunToLineCapability = 0x800000, - MemoryAddressCapability = 0x1000000 + MemoryAddressCapability = 0x1000000, + ShowModuleSectionsCapability = 0x200000 }; enum LogChannel @@ -181,9 +185,8 @@ enum LogChannel AppOutput, // stdout AppError, // stderr AppStuff, // (possibly) windows debug channel - StatusBar, // LogStatus and also put to the status bar - QtMessageLogOutput, - QtMessageLogStatus + StatusBar, // LogStatus and also put to the status bar + ConsoleOutput // Used to output to console }; enum DebuggerEngineType diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h index e34340d095..cdc75b2c39 100644 --- a/src/plugins/debugger/debuggercore.h +++ b/src/plugins/debugger/debuggercore.h @@ -64,6 +64,7 @@ namespace Internal { class BreakHandler; class SnapshotHandler; class Symbol; +class Section; class DebuggerToolTipManager; class GlobalDebuggerOptions; @@ -113,10 +114,11 @@ public: // DebuggerEngineType et = NoEngineType) const = 0; virtual void showModuleSymbols(const QString &moduleName, const QVector<Symbol> &symbols) = 0; + virtual void showModuleSections(const QString &moduleName, + const QVector<Section> §ions) = 0; virtual void openMemoryEditor() = 0; virtual void languagesChanged() = 0; virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages) = 0; - virtual bool evaluateScriptExpression(const QString &expression) = 0; virtual Utils::SavedAction *action(int code) const = 0; virtual bool boolSetting(int code) const = 0; diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 34df0d02a8..33b3c52197 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -47,7 +47,6 @@ #include "stackhandler.h" #include "threadshandler.h" #include "watchhandler.h" -#include "qtmessageloghandler.h" #include <coreplugin/icore.h> #include <coreplugin/idocument.h> @@ -65,6 +64,8 @@ #include <utils/qtcassert.h> #include <utils/fileinprojectfinder.h> +#include <qmljs/consolemanagerinterface.h> + #include <QDebug> #include <QTimer> #include <QFile> @@ -296,7 +297,6 @@ public: StackHandler m_stackHandler; ThreadsHandler m_threadsHandler; WatchHandler m_watchHandler; - QtMessageLogHandler m_qtMessageHandler; QFutureInterface<void> m_progress; DisassemblerAgent m_disassemblerAgent; @@ -427,11 +427,6 @@ WatchHandler *DebuggerEngine::watchHandler() const : &d->m_watchHandler; } -QtMessageLogHandler *DebuggerEngine::qtMessageLogHandler() const -{ - return &d->m_qtMessageHandler; -} - SourceFilesHandler *DebuggerEngine::sourceFilesHandler() const { return d->m_masterEngine @@ -509,14 +504,6 @@ QAbstractItemModel *DebuggerEngine::sourceFilesModel() const return model; } -QAbstractItemModel *DebuggerEngine::qtMessageLogModel() const -{ - QAbstractItemModel *model = qtMessageLogHandler()->model(); - if (model->objectName().isEmpty()) // Make debugging easier. - model->setObjectName(objectName() + QLatin1String("QtMessageLogModel")); - return model; -} - void DebuggerEngine::fetchMemory(MemoryAgent *, QObject *, quint64 addr, quint64 length) { @@ -545,8 +532,9 @@ void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) c } //if (msg.size() && msg.at(0).isUpper() && msg.at(1).isUpper()) // qDebug() << qPrintable(msg) << "IN STATE" << state(); - if (channel == QtMessageLogOutput) - qtMessageLogHandler()->appendMessage(QtMessageLogHandler::UndefinedType, msg); + QmlJS::ConsoleManagerInterface *consoleManager = QmlJS::ConsoleManagerInterface::instance(); + if (channel == ConsoleOutput && consoleManager) + consoleManager->printToConsolePane(QmlJS::ConsoleItem::UndefinedType, msg); debuggerCore()->showMessage(msg, channel, timeout); if (d->m_runControl) { @@ -1245,10 +1233,6 @@ void DebuggerEngine::setState(DebuggerState state, bool forced) handler->notifyBreakpointReleased(id); } - const bool running = d->m_state == InferiorRunOk; - if (running) - threadsHandler()->notifyRunning(); - showMessage(msg, LogDebug); updateViews(); @@ -1467,6 +1451,10 @@ void DebuggerEngine::requestModuleSymbols(const QString &) { } +void DebuggerEngine::requestModuleSections(const QString &) +{ +} + void DebuggerEngine::reloadRegisters() { } @@ -1598,10 +1586,6 @@ void DebuggerEngine::changeBreakpoint(BreakpointModelId id) QTC_CHECK(false); } -void DebuggerEngine::selectThread(int) -{ -} - void DebuggerEngine::assignValueInDebugger(const WatchData *, const QString &, const QVariant &) { @@ -1667,12 +1651,6 @@ void DebuggerEngine::executeDebuggerCommand(const QString &, DebuggerLanguages) showStatusMessage(tr("This debugger cannot handle user input.")); } -bool DebuggerEngine::evaluateScriptExpression(const QString &) -{ - showStatusMessage(tr("This debugger cannot handle user input.")); - return false; -} - BreakHandler *DebuggerEngine::breakHandler() const { return debuggerCore()->breakHandler(); @@ -1955,8 +1933,12 @@ TaskHub *DebuggerEnginePrivate::taskHub() { if (!m_taskHub) { m_taskHub = ProjectExplorerPlugin::instance()->taskHub(); - m_taskHub->addCategory(Core::Id("Debuginfo"), tr("Debug Information")); - m_taskHub->addCategory(Core::Id("DebuggerTest"), tr("Debugger Test")); + m_taskHub->addCategory(Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO), + tr("Debug Information")); + m_taskHub->addCategory(Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_TEST), + tr("Debugger Test")); + m_taskHub->addCategory(Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME), + tr("Debugger Runtime")); } return m_taskHub; } diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 070b812caf..3067bbe793 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -32,7 +32,8 @@ #include "debugger_global.h" #include "debuggerconstants.h" -#include "breakpoint.h" // For 'BreakpointId' +#include "breakpoint.h" // For BreakpointModelId. +#include "threaddata.h" // For ThreadId. #include <QObject> #include <QStringList> @@ -76,7 +77,6 @@ class QmlAdapter; class QmlCppEngine; class DebuggerToolTipContext; class MemoryMarkup; -class QtMessageLogHandler; struct WatchUpdateFlags { @@ -179,6 +179,7 @@ public: virtual void loadSymbolsForStack(); virtual void loadAllSymbols(); virtual void requestModuleSymbols(const QString &moduleName); + virtual void requestModuleSections(const QString &moduleName); virtual void reloadRegisters(); virtual void reloadSourceFiles(); @@ -206,7 +207,7 @@ public: virtual bool acceptsDebuggerCommands() const { return true; } virtual void assignValueInDebugger(const Internal::WatchData *data, const QString &expr, const QVariant &value); - virtual void selectThread(int index); + virtual void selectThread(Internal::ThreadId threadId) = 0; virtual Internal::ModulesHandler *modulesHandler() const; virtual Internal::RegisterHandler *registerHandler() const; @@ -215,7 +216,6 @@ public: virtual Internal::WatchHandler *watchHandler() const; virtual Internal::SourceFilesHandler *sourceFilesHandler() const; virtual Internal::BreakHandler *breakHandler() const; - virtual Internal::QtMessageLogHandler *qtMessageLogHandler() const; virtual QAbstractItemModel *modulesModel() const; virtual QAbstractItemModel *registerModel() const; @@ -228,7 +228,6 @@ public: virtual QAbstractItemModel *toolTipsModel() const; // Deprecated, FIXME: use watchModel virtual QAbstractItemModel *watchModel() const; virtual QAbstractItemModel *sourceFilesModel() const; - virtual QAbstractItemModel *qtMessageLogModel() const; void progressPing(); void handleFinished(); @@ -353,7 +352,6 @@ protected: virtual void executeRunToFunction(const QString &functionName); virtual void executeJumpToLine(const Internal::ContextData &data); virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); - virtual bool evaluateScriptExpression(const QString &expression); virtual void frameUp(); virtual void frameDown(); diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp index f0c40afa89..127909aaa4 100644 --- a/src/plugins/debugger/debuggerkitconfigwidget.cpp +++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp @@ -65,20 +65,12 @@ static const char dgbToolsDownloadLink64C[] = "http://www.microsoft.com/whdc/dev // ----------------------------------------------------------------------- DebuggerKitConfigWidget::DebuggerKitConfigWidget(ProjectExplorer::Kit *workingCopy, - const DebuggerKitInformation *ki, - QWidget *parent) : - ProjectExplorer::KitConfigWidget(parent), - m_kit(workingCopy), + const DebuggerKitInformation *ki) + : KitConfigWidget(workingCopy), m_info(ki), - m_label(new QLabel(this)), - m_button(new QPushButton(tr("Manage..."), this)) + m_label(new QLabel), + m_button(new QPushButton(tr("Manage..."))) { - setToolTip(tr("The debugger to use for this kit.")); - - QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); - layout->addWidget(m_label); - // ToolButton with Menu, defaulting to 'Autodetect'. QMenu *buttonMenu = new QMenu(m_button); QAction *autoDetectAction = buttonMenu->addAction(tr("Auto-detect")); @@ -90,6 +82,16 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(ProjectExplorer::Kit *workingCo refresh(); } +QString DebuggerKitConfigWidget::toolTip() const +{ + return tr("The debugger to use for this kit."); +} + +QWidget *DebuggerKitConfigWidget::mainWidget() const +{ + return m_label; +} + QWidget *DebuggerKitConfigWidget::buttonWidget() const { return m_button; diff --git a/src/plugins/debugger/debuggerkitconfigwidget.h b/src/plugins/debugger/debuggerkitconfigwidget.h index 505feca558..93fc7585db 100644 --- a/src/plugins/debugger/debuggerkitconfigwidget.h +++ b/src/plugins/debugger/debuggerkitconfigwidget.h @@ -62,23 +62,23 @@ class DebuggerKitConfigWidget : public ProjectExplorer::KitConfigWidget public: DebuggerKitConfigWidget(ProjectExplorer::Kit *workingCopy, - const DebuggerKitInformation *ki, - QWidget *parent = 0); + const DebuggerKitInformation *ki); QString displayName() const; + QString toolTip() const; void makeReadOnly(); void refresh(); QWidget *buttonWidget() const; + QWidget *mainWidget() const; private slots: void autoDetectDebugger(); void showDialog(); private: - ProjectExplorer::Kit *m_kit; const DebuggerKitInformation *m_info; QLabel *m_label; QPushButton *m_button; diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index 605b9941a6..71ba306557 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -689,7 +689,6 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement() QDockWidget *threadsDock = q->dockWidget(QLatin1String(DOCKWIDGET_THREADS)); QDockWidget *outputDock = q->dockWidget(QLatin1String(DOCKWIDGET_OUTPUT)); QDockWidget *qmlInspectorDock = q->dockWidget(QLatin1String(DOCKWIDGET_QML_INSPECTOR)); - QDockWidget *consoleDock = q->dockWidget(QLatin1String(DOCKWIDGET_QML_SCRIPTCONSOLE)); QDockWidget *modulesDock = q->dockWidget(QLatin1String(DOCKWIDGET_MODULES)); QDockWidget *registerDock = q->dockWidget(QLatin1String(DOCKWIDGET_REGISTER)); QDockWidget *sourceFilesDock = q->dockWidget(QLatin1String(DOCKWIDGET_SOURCE_FILES)); @@ -700,7 +699,6 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement() QTC_ASSERT(snapshotsDock, return); QTC_ASSERT(threadsDock, return); QTC_ASSERT(outputDock, return); - QTC_ASSERT(consoleDock, return); QTC_ASSERT(modulesDock, return); QTC_ASSERT(registerDock, return); QTC_ASSERT(sourceFilesDock, return); @@ -713,7 +711,7 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement() // toolBar // -------------------------------------------------------------------------------- - // stack,qmlinspector | breakpoints,modules,register,threads,sourceFiles,snapshots,scriptconsole + // stack,qmlinspector | breakpoints,modules,register,threads,sourceFiles,snapshots // q->splitDockWidget(toolBarDock, stackDock, Qt::Vertical); q->splitDockWidget(stackDock, breakDock, Qt::Horizontal); @@ -726,13 +724,10 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement() q->tabifyDockWidget(breakDock, threadsDock); q->tabifyDockWidget(breakDock, sourceFilesDock); q->tabifyDockWidget(breakDock, snapshotsDock); - q->tabifyDockWidget(breakDock, consoleDock); if (m_activeDebugLanguages.testFlag(Debugger::QmlLanguage)) { if (qmlInspectorDock) qmlInspectorDock->show(); - if (consoleDock) - consoleDock->show(); } else { // CPP only threadsDock->show(); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index df09982af9..bbd6b33bdc 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -45,7 +45,6 @@ #include "breakpoint.h" #include "breakhandler.h" #include "breakwindow.h" -#include "qtmessagelogwindow.h" #include "disassemblerlines.h" #include "logwindow.h" #include "moduleswindow.h" @@ -94,6 +93,7 @@ #include <projectexplorer/abi.h> #include <projectexplorer/applicationrunconfiguration.h> #include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/buildmanager.h> #include <projectexplorer/devicesupport/deviceprocessesdialog.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorer.h> @@ -114,6 +114,7 @@ #include <texteditor/fontsettings.h> #include <texteditor/texteditorsettings.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/savedaction.h> #include <utils/styledbar.h> @@ -462,12 +463,12 @@ static QToolButton *toolButton(QAction *action) return button; } -static void setProxyAction(ProxyAction *proxy, const char *id) +static void setProxyAction(ProxyAction *proxy, Core::Id id) { proxy->setAction(ActionManager::command(id)->action()); } -static QToolButton *toolButton(const char *id) +static QToolButton *toolButton(Core::Id id) { return toolButton(ActionManager::command(id)->action()); } @@ -494,6 +495,7 @@ public: bool hasCapability(unsigned cap) const; bool acceptsBreakpoint(BreakpointModelId) const { return false; } bool acceptsDebuggerCommands() const { return false; } + void selectThread(ThreadId) {} }; bool DummyEngine::hasCapability(unsigned cap) const @@ -668,19 +670,21 @@ bool fillParameters(DebuggerStartParameters *sp, const Kit *kit /* = 0 */, QStri *errorMessage = DebuggerKitInformation::tr("No kit found."); return false; } - const QList<ProjectExplorer::Task> tasks = DebuggerKitInformation::validateDebugger(kit); - if (!tasks.isEmpty()) { - sp->startMode = NoStartMode; - if (errorMessage) { - foreach (const ProjectExplorer::Task &t, tasks) { - if (errorMessage->isEmpty()) - errorMessage->append(QLatin1Char('\n')); - errorMessage->append(t.description); + // validate debugger if C++ debugging is enabled + if (sp->languages & CppLanguage) { + const QList<ProjectExplorer::Task> tasks = DebuggerKitInformation::validateDebugger(kit); + if (!tasks.isEmpty()) { + sp->startMode = NoStartMode; + if (errorMessage) { + foreach (const ProjectExplorer::Task &t, tasks) { + if (errorMessage->isEmpty()) + errorMessage->append(QLatin1Char('\n')); + errorMessage->append(t.description); + } } + return false; } - return false; } - sp->cppEngineType = DebuggerKitInformation::engineType(kit); sp->sysRoot = SysRootKitInformation::sysRoot(kit).toString(); sp->debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); @@ -779,7 +783,8 @@ public slots: void selectThread(int index) { - currentEngine()->selectThread(index); + ThreadId id = m_currentEngine->threadsHandler()->threadAt(index); + m_currentEngine->selectThread(id); } void breakpointSetMarginActionTriggered() @@ -962,13 +967,14 @@ public slots: void aboutToSaveSession(); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); - bool evaluateScriptExpression(const QString &expression); void coreShutdown(); #ifdef WITH_TESTS public slots: void testLoadProject(const QString &proFile, const TestCallBack &cb); void testProjectLoaded(ProjectExplorer::Project *project); + void testProjectEvaluated(); + void testProjectBuilt(bool success); void testUnloadProject(); void testFinished(); @@ -986,6 +992,7 @@ public slots: void testBenchmark1(); public: + ProjectExplorer::Project *m_testProject; bool m_testSuccess; QList<TestCallBack> m_testCallbacks; @@ -1213,6 +1220,7 @@ public slots: QString stringSetting(int code) const; void showModuleSymbols(const QString &moduleName, const Symbols &symbols); + void showModuleSections(const QString &moduleName, const Sections §ions); bool parseArgument(QStringList::const_iterator &it, const QStringList::const_iterator &cend, QString *errorMessage); @@ -1276,7 +1284,6 @@ public: BaseWindow *m_breakWindow; BreakHandler *m_breakHandler; - QtMessageLogWindow *m_qtMessageLogWindow; WatchWindow *m_returnWindow; WatchWindow *m_localsWindow; WatchWindow *m_watchersWindow; @@ -1342,7 +1349,6 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) : m_threadsWindow = 0; m_logWindow = 0; m_localsAndExpressionsWindow = 0; - m_qtMessageLogWindow = 0; m_mainWindow = 0; m_snapshotHandler = 0; @@ -1556,7 +1562,7 @@ void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project) m_exitAction->setEnabled(false); m_startAction->setEnabled(true); m_debugWithoutDeployAction->setEnabled(true); - setProxyAction(m_visibleStartAction, Constants::DEBUG); + setProxyAction(m_visibleStartAction, Core::Id(Constants::DEBUG)); } void DebuggerPluginPrivate::languagesChanged() @@ -1691,14 +1697,15 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly) return; } - #ifdef Q_OS_WIN - if (isWinProcessBeingDebugged(process.pid)) { + bool isWindows = false; + if (const ProjectExplorer::ToolChain *tc = ToolChainKitInformation::toolChain(kit)) + isWindows = tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS; + if (isWindows && isWinProcessBeingDebugged(process.pid)) { QMessageBox::warning(ICore::mainWindow(), tr("Process Already Under Debugger Control"), tr("The process %1 is already under the control of a debugger.\n" "Qt Creator cannot attach to it.").arg(process.pid)); return; } - #endif if (device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) { DebuggerStartParameters sp; @@ -1793,7 +1800,7 @@ void DebuggerPluginPrivate::startRemoteEngine() sp.connParams.timeout = 5; sp.connParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationByPassword; sp.connParams.port = 22; - sp.connParams.proxyType = QSsh::SshConnectionParameters::NoProxy; + sp.connParams.options = QSsh::SshIgnoreDefaultProxy; sp.executable = dlg.inferiorPath(); sp.serverStartScript = dlg.enginePath(); @@ -2062,7 +2069,6 @@ void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine) m_threadsWindow->setModel(engine->threadsModel()); m_watchersWindow->setModel(engine->watchersModel()); m_inspectorWindow->setModel(engine->inspectorModel()); - m_qtMessageLogWindow->setModel(engine->qtMessageLogModel()); engine->watchHandler()->rebuildModel(); @@ -2190,7 +2196,6 @@ void DebuggerPluginPrivate::setInitialState() action(AutoDerefPointers)->setEnabled(true); action(ExpandStack)->setEnabled(false); - m_qtMessageLogWindow->setEnabled(true); } void DebuggerPluginPrivate::updateWatchersWindow(bool showWatch, bool showReturn) @@ -2206,7 +2211,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) QTC_ASSERT(m_returnWindow->model(), return); QTC_ASSERT(!engine->isSlaveEngine(), return); - m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThread()); + m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThreadIndex()); engine->watchHandler()->updateWatchersWindow(); const DebuggerState state = engine->state(); @@ -2228,7 +2233,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_exitAction->setEnabled(false); m_startAction->setEnabled(true); m_debugWithoutDeployAction->setEnabled(true); - setProxyAction(m_visibleStartAction, Constants::DEBUG); + setProxyAction(m_visibleStartAction, Core::Id(Constants::DEBUG)); m_hiddenStopAction->setAction(m_undisturbableAction); } else if (state == InferiorStopOk) { // F5 continues, Shift-F5 kills. It is "continuable". @@ -2237,7 +2242,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_exitAction->setEnabled(true); m_startAction->setEnabled(false); m_debugWithoutDeployAction->setEnabled(false); - setProxyAction(m_visibleStartAction, Constants::CONTINUE); + setProxyAction(m_visibleStartAction, Core::Id(Constants::CONTINUE)); m_hiddenStopAction->setAction(m_exitAction); m_localsAndExpressionsWindow->setShowLocals(true); } else if (state == InferiorRunOk) { @@ -2247,7 +2252,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_exitAction->setEnabled(true); m_startAction->setEnabled(false); m_debugWithoutDeployAction->setEnabled(false); - setProxyAction(m_visibleStartAction, Constants::INTERRUPT); + setProxyAction(m_visibleStartAction, Core::Id(Constants::INTERRUPT)); m_hiddenStopAction->setAction(m_interruptAction); m_localsAndExpressionsWindow->setShowLocals(false); } else if (state == DebuggerFinished) { @@ -2257,7 +2262,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_exitAction->setEnabled(false); m_startAction->setEnabled(true); m_debugWithoutDeployAction->setEnabled(true); - setProxyAction(m_visibleStartAction, Constants::DEBUG); + setProxyAction(m_visibleStartAction, Core::Id(Constants::DEBUG)); m_hiddenStopAction->setAction(m_undisturbableAction); m_codeModelSnapshot = CPlusPlus::Snapshot(); setBusyCursor(false); @@ -2483,11 +2488,6 @@ void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout) m_statusLabel->showStatusMessage(msg, timeout); } -bool DebuggerPluginPrivate::evaluateScriptExpression(const QString &expression) -{ - return currentEngine()->evaluateScriptExpression(expression); -} - void DebuggerPluginPrivate::openMemoryEditor() { AddressDialog dialog; @@ -2555,10 +2555,6 @@ void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int tim m_logWindow->showInput(LogError, QLatin1String("ERROR: ") + msg); m_logWindow->showOutput(LogError, QLatin1String("ERROR: ") + msg); break; - case QtMessageLogStatus: - QTC_ASSERT(m_qtMessageLogWindow, return); - m_qtMessageLogWindow->showStatus(msg, timeout); - break; default: m_logWindow->showOutput(channel, msg); break; @@ -2735,8 +2731,6 @@ void DebuggerPluginPrivate::extensionsInitialized() m_breakWindow->setObjectName(QLatin1String(DOCKWIDGET_BREAK)); m_breakWindow->setModel(m_breakHandler->model()); - m_qtMessageLogWindow = new QtMessageLogWindow(); - m_qtMessageLogWindow->setObjectName(QLatin1String(DOCKWIDGET_QML_SCRIPTCONSOLE)); m_modulesWindow = new ModulesWindow; m_modulesWindow->setObjectName(QLatin1String(DOCKWIDGET_MODULES)); m_logWindow = new LogWindow; @@ -2881,7 +2875,6 @@ void DebuggerPluginPrivate::extensionsInitialized() dock->setProperty(DOCKWIDGET_DEFAULT_AREA, Qt::TopDockWidgetArea); m_mainWindow->createDockWidget(CppLanguage, m_breakWindow); - m_mainWindow->createDockWidget(QmlLanguage, m_qtMessageLogWindow); m_mainWindow->createDockWidget(CppLanguage, m_snapshotWindow); m_mainWindow->createDockWidget(CppLanguage, m_stackWindow); m_mainWindow->createDockWidget(CppLanguage, m_threadsWindow); @@ -2945,11 +2938,11 @@ void DebuggerPluginPrivate::extensionsInitialized() act->setText(tr("Attach to QML Port...")); connect(act, SIGNAL(triggered()), SLOT(attachToQmlPort())); -#ifdef Q_OS_WIN - m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this); - connect(m_startRemoteCdbAction, SIGNAL(triggered()), - SLOT(startRemoteCdbSession())); -#endif + if (HostOsInfo::isWindowsHost()) { + m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this); + connect(m_startRemoteCdbAction, SIGNAL(triggered()), + SLOT(startRemoteCdbSession())); + } act = m_detachAction = new QAction(this); act->setText(tr("Detach Debugger")); @@ -3335,6 +3328,36 @@ void DebuggerPluginPrivate::showModuleSymbols(const QString &moduleName, createNewDock(w); } +void DebuggerPluginPrivate::showModuleSections(const QString &moduleName, + const Sections §ions) +{ + QTreeWidget *w = new QTreeWidget; + w->setUniformRowHeights(true); + w->setColumnCount(5); + w->setRootIsDecorated(false); + w->setAlternatingRowColors(true); + w->setSortingEnabled(true); + w->setObjectName(QLatin1String("Sections.") + moduleName); + QStringList header; + header.append(tr("Name")); + header.append(tr("From")); + header.append(tr("To")); + header.append(tr("Address")); + header.append(tr("Flags")); + w->setHeaderLabels(header); + w->setWindowTitle(tr("Sections in \"%1\"").arg(moduleName)); + foreach (const Section &s, sections) { + QTreeWidgetItem *it = new QTreeWidgetItem; + it->setData(0, Qt::DisplayRole, s.name); + it->setData(1, Qt::DisplayRole, s.from); + it->setData(2, Qt::DisplayRole, s.to); + it->setData(3, Qt::DisplayRole, s.address); + it->setData(4, Qt::DisplayRole, s.flags); + w->addTopLevelItem(it); + } + createNewDock(w); +} + void DebuggerPluginPrivate::aboutToShutdown() { m_plugin->removeObject(this); @@ -3442,10 +3465,13 @@ void DebuggerPluginPrivate::testLoadProject(const QString &proFile, const TestCa m_testCallbacks.append(cb); QString error; - if (pe->openProject(proFile, &error)) - return; // Will end up in callback. + if (pe->openProject(proFile, &error)) { + // Will end up in callback below due to the connections to + // signal currentProjectChanged(). + return; + } - // Eat the unused callback. + // Project opening failed. Eat the unused callback. qWarning("Cannot open %s: %s", qPrintable(proFile), qPrintable(error)); QVERIFY(false); m_testCallbacks.pop_back(); @@ -3457,14 +3483,25 @@ void DebuggerPluginPrivate::testProjectLoaded(Project *project) qWarning("Changed to null project."); return; } - ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance(); - disconnect(pe, SIGNAL(currentProjectChanged(ProjectExplorer::Project*)), - this, SLOT(testProjectLoaded(ProjectExplorer::Project*))); + m_testProject = project; + connect(project, SIGNAL(proFilesEvaluated()), SLOT(testProjectEvaluated())); + project->configureAsExampleProject(QStringList()); +} - QString fileName = project->document()->fileName(); +void DebuggerPluginPrivate::testProjectEvaluated() +{ + QString fileName = m_testProject->document()->fileName(); QVERIFY(!fileName.isEmpty()); qWarning("Project %s loaded", qPrintable(fileName)); + connect(ProjectExplorerPlugin::instance()->buildManager(), + SIGNAL(buildQueueFinished(bool)), + SLOT(testProjectBuilt(bool))); + ProjectExplorerPlugin::instance()->buildProject(m_testProject); +} +void DebuggerPluginPrivate::testProjectBuilt(bool success) +{ + QVERIFY(success); QVERIFY(!m_testCallbacks.isEmpty()); TestCallBack cb = m_testCallbacks.takeLast(); invoke<void>(cb.receiver, cb.slot); @@ -3487,12 +3524,13 @@ static Kit *currentKit() Target *t = activeTarget(); if (!t || !t->isEnabled()) return 0; - return activeTarget()->kit(); + return t->kit(); } static LocalApplicationRunConfiguration *activeLocalRunConfiguration() { - return qobject_cast<LocalApplicationRunConfiguration *>(activeTarget()->activeRunConfiguration()); + Target *t = activeTarget(); + return t ? qobject_cast<LocalApplicationRunConfiguration *>(t->activeRunConfiguration()) : 0; } void DebuggerPluginPrivate::testRunProject(const DebuggerStartParameters &sp, const TestCallBack &cb) diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 418affe8f8..565462c73a 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -53,6 +53,7 @@ #include <projectexplorer/project.h> #include <projectexplorer/projectexplorer.h> #include <projectexplorer/target.h> +#include <projectexplorer/taskhub.h> #include <projectexplorer/toolchain.h> #include <utils/outputformat.h> @@ -70,6 +71,7 @@ #include <QErrorMessage> #include <QFormLayout> #include <QLabel> +#include <QPointer> using namespace Debugger::Internal; using namespace ProjectExplorer; @@ -261,7 +263,7 @@ public: public: DebuggerRunControl *q; DebuggerEngine *m_engine; - const QWeakPointer<RunConfiguration> m_myRunConfiguration; + const QPointer<RunConfiguration> m_myRunConfiguration; bool m_running; }; @@ -595,6 +597,12 @@ DebuggerRunControl *DebuggerRunControlFactory::doCreate (const DebuggerStartParameters &sp0, RunConfiguration *rc, QString *errorMessage) { Q_UNUSED(errorMessage); + + TaskHub *th = ProjectExplorerPlugin::instance()->taskHub(); + th->clearTasks(Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO)); + th->clearTasks(Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_TEST)); + th->clearTasks(Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME)); + DebuggerStartParameters sp = sp0; if (!debuggerCore()->boolSetting(AutoEnrichParameters)) { const QString sysroot = sp.sysRoot; diff --git a/src/plugins/debugger/debuggerstreamops.cpp b/src/plugins/debugger/debuggerstreamops.cpp index ae178ccab4..c7ec18b054 100644 --- a/src/plugins/debugger/debuggerstreamops.cpp +++ b/src/plugins/debugger/debuggerstreamops.cpp @@ -40,7 +40,7 @@ namespace Internal { QDataStream &operator<<(QDataStream &stream, const ThreadData &d) { - stream << (qint64)d.id; + stream << d.id.raw(); stream << d.address; stream << d.function; stream << d.fileName; @@ -54,7 +54,7 @@ QDataStream &operator>>(QDataStream &stream, ThreadData &d) { qint64 id; stream >> id; - d.id = id; + d.id = ThreadId(id); stream >> d.address; stream >> d.function; stream >> d.fileName; diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp index 669374e10b..daecb17c3d 100644 --- a/src/plugins/debugger/gdb/classicgdbengine.cpp +++ b/src/plugins/debugger/gdb/classicgdbengine.cpp @@ -1230,8 +1230,8 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response) QStringList uninitializedVariables; if (debuggerCore()->action(UseCodeModel)->isChecked()) { const StackFrame frame = - qVariantCanConvert<Debugger::Internal::StackFrame>(response.cookie) - ? qVariantValue<Debugger::Internal::StackFrame>(response.cookie) + response.cookie.canConvert<Debugger::Internal::StackFrame>() + ? qvariant_cast<Debugger::Internal::StackFrame>(response.cookie) : stackHandler()->currentFrame(); if (frame.isUsable()) getUninitializedVariables(debuggerCore()->cppCodeModelSnapshot(), diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 9b63495d16..500724ebde 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -75,6 +75,7 @@ #include <projectexplorer/itaskhandler.h> #include <texteditor/itexteditor.h> #include <utils/elfreader.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/qtcprocess.h> #include <utils/savedaction.h> @@ -278,6 +279,8 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters) SLOT(reloadLocals())); connect(debuggerCore()->action(UseDynamicType), SIGNAL(valueChanged(QVariant)), SLOT(reloadLocals())); + connect(debuggerCore()->action(IntelFlavor), SIGNAL(valueChanged(QVariant)), + SLOT(reloadDisassembly())); } GdbEngine::~GdbEngine() @@ -343,24 +346,23 @@ static void dump(const char *first, const char *middle, const QString & to) // Parse "~:gdb: unknown target exception 0xc0000139 at 0x77bef04e\n" // and return an exception message -static inline QString msgWinException(const QByteArray &data) +static inline QString msgWinException(const QByteArray &data, unsigned *exCodeIn = 0) { + if (exCodeIn) + *exCodeIn = 0; const int exCodePos = data.indexOf("0x"); const int blankPos = exCodePos != -1 ? data.indexOf(' ', exCodePos + 1) : -1; const int addressPos = blankPos != -1 ? data.indexOf("0x", blankPos + 1) : -1; if (addressPos < 0) return GdbEngine::tr("An exception was triggered."); const unsigned exCode = data.mid(exCodePos, blankPos - exCodePos).toUInt(0, 0); + if (exCodeIn) + *exCodeIn = exCode; const quint64 address = data.mid(addressPos).trimmed().toULongLong(0, 0); QString rc; QTextStream str(&rc); str << GdbEngine::tr("An exception was triggered: "); -#ifdef Q_OS_WIN formatWindowsException(exCode, address, 0, 0, 0, str); -#else - Q_UNUSED(exCode) - Q_UNUSED(address) -#endif str << '.'; return rc; } @@ -466,6 +468,8 @@ void GdbEngine::handleResponse(const QByteArray &buff) m_pendingLogStreamOutput.clear(); m_pendingConsoleStreamOutput.clear(); } else if (asyncClass == "running") { + GdbMi threads = result.findChild("thread-id"); + threadsHandler()->notifyRunning(threads.data()); if (state() == InferiorRunOk || state() == InferiorSetupRequested) { // We get multiple *running after thread creation and in Windows terminals. showMessage(QString::fromLatin1("NOTE: INFERIOR STILL RUNNING IN STATE %1."). @@ -526,6 +530,10 @@ void GdbEngine::handleResponse(const QByteArray &buff) //"{id="1",group-id="28902"}" QByteArray id = result.findChild("id").data(); showStatusMessage(tr("Thread %1 created").arg(_(id)), 1000); + ThreadData thread; + thread.id = ThreadId(id.toLong()); + thread.groupId = result.findChild("group-id").data(); + threadsHandler()->updateThread(thread); } else if (asyncClass == "thread-group-exited") { // Archer has "{id="28902"}" QByteArray id = result.findChild("id").data(); @@ -537,6 +545,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) QByteArray groupid = result.findChild("group-id").data(); showStatusMessage(tr("Thread %1 in group %2 exited") .arg(_(id)).arg(_(groupid)), 1000); + threadsHandler()->removeThread(ThreadId(id.toLong())); } else if (asyncClass == "thread-selected") { QByteArray id = result.findChild("id").data(); showStatusMessage(tr("Thread %1 selected").arg(_(id)), 1000); @@ -689,8 +698,13 @@ void GdbEngine::handleResponse(const QByteArray &buff) // [Windows, most likely some DLL/Entry point not found]: // "gdb: unknown target exception 0xc0000139 at 0x77bef04e" // This may be fatal and cause the target to exit later - m_lastWinException = msgWinException(data); + unsigned exCode; + m_lastWinException = msgWinException(data, &exCode); showMessage(m_lastWinException, LogMisc); + const Task::TaskType type = isFatalWinException(exCode) ? Task::Error : Task::Warning; + const Task task(type, m_lastWinException, Utils::FileName(), 0, + Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME)); + taskHub()->addTask(task); } if (data.startsWith("QMLBP:")) { @@ -732,7 +746,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) Task task(Task::Warning, tr("Missing debug information for %1\nTry: %2") .arg(m_lastMissingDebugInfo).arg(cmd), - FileName(), 0, Core::Id("Debuginfo")); + FileName(), 0, Core::Id(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO)); taskHub()->addTask(task); @@ -1396,6 +1410,9 @@ void GdbEngine::handleStopResponse(const GdbMi &data) return; } + GdbMi threads = data.findChild("stopped-thread"); + threadsHandler()->notifyStopped(threads.data()); + const QByteArray reason = data.findChild("reason").data(); if (isExitedReason(reason)) { @@ -1747,10 +1764,6 @@ void GdbEngine::handleStop2(const GdbMi &data) // Let the event loop run before deciding whether to update the stack. m_stackNeeded = true; // setTokenBarrier() might reset this. - if (isStopperThread) - m_currentThreadId = 0; - else - m_currentThreadId = data.findChild("thread-id").data().toInt(); QTimer::singleShot(0, this, SLOT(handleStop2())); } @@ -1760,8 +1773,6 @@ void GdbEngine::handleStop2() if (!m_stackNeeded) return; - reloadStack(false); // Will trigger register reload. - if (supportsThreads()) { if (m_isMacGdb || m_gdbVersion < 70100) { postCommand("-thread-list-ids", Discardable, CB(handleThreadListIds)); @@ -1770,7 +1781,6 @@ void GdbEngine::handleStop2() postCommand("-thread-info", Discardable, CB(handleThreadInfo)); } } - } void GdbEngine::handleInfoProc(const GdbResponse &response) @@ -2120,6 +2130,7 @@ bool GdbEngine::hasCapability(unsigned cap) const | AddWatcherCapability | WatchWidgetsCapability | ShowModuleSymbolsCapability + | ShowModuleSectionsCapability | CatchCapability | OperateByInstructionCapability | RunToLineCapability @@ -3317,7 +3328,7 @@ void GdbEngine::handleShowModuleSymbols(const GdbResponse &response) const QString modulePath = cookie.section(QLatin1Char('@'), 0, 0); const QString fileName = cookie.section(QLatin1Char('@'), 1, 1); if (response.resultClass == GdbResultDone) { - Symbols rc; + Symbols symbols; QFile file(fileName); file.open(QIODevice::ReadOnly); // Object file /opt/dev/qt/lib/libQtNetworkMyns.so.4: @@ -3361,17 +3372,62 @@ void GdbEngine::handleShowModuleSymbols(const GdbResponse &response) symbol.name = _(line.mid(posName, lenName)); symbol.section = _(line.mid(posSection, lenSection)); symbol.demangled = _(line.mid(posDemangled, lenDemangled)); - rc.push_back(symbol); + symbols.push_back(symbol); } file.close(); file.remove(); - debuggerCore()->showModuleSymbols(modulePath, rc); + debuggerCore()->showModuleSymbols(modulePath, symbols); } else { showMessageBox(QMessageBox::Critical, tr("Cannot Read Symbols"), tr("Cannot read symbols for module \"%1\".").arg(fileName)); } } +void GdbEngine::requestModuleSections(const QString &moduleName) +{ + // There seems to be no way to get the symbols from a single .so. + postCommand("maint info section ALLOBJ", + NeedsStop, CB(handleShowModuleSections), moduleName); +} + +void GdbEngine::handleShowModuleSections(const GdbResponse &response) +{ + // ~" Object file: /usr/lib/i386-linux-gnu/libffi.so.6\n" + // ~" 0xb44a6114->0xb44a6138 at 0x00000114: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS\n" + if (response.resultClass == GdbResultDone) { + const QString moduleName = response.cookie.toString(); + const QStringList lines = QString::fromLocal8Bit(response.consoleStreamOutput).split(QLatin1Char('\n')); + const QString prefix = QLatin1String(" Object file: "); + const QString needle = prefix + moduleName; + Sections sections; + bool active = false; + foreach (const QString &line, lines) { + if (line.startsWith(prefix)) { + if (active) + break; + if (line == needle) + active = true; + } else { + if (active) { + QStringList items = line.split(QLatin1Char(' '), QString::SkipEmptyParts); + QString fromTo = items.value(0, QString()); + const int pos = fromTo.indexOf(QLatin1Char('-')); + QTC_ASSERT(pos >= 0, continue); + Section section; + section.from = fromTo.left(pos); + section.to = fromTo.mid(pos + 2); + section.address = items.value(2, QString()); + section.name = items.value(3, QString()); + section.flags = items.value(4, QString()); + sections.append(section); + } + } + } + if (!sections.isEmpty()) + debuggerCore()->showModuleSections(moduleName, sections); + } +} + void GdbEngine::reloadModules() { if (state() == InferiorRunOk || state() == InferiorStopOk) @@ -3488,15 +3544,12 @@ void GdbEngine::reloadSourceFilesInternal() // ////////////////////////////////////////////////////////////////////// -void GdbEngine::selectThread(int index) +void GdbEngine::selectThread(ThreadId threadId) { - threadsHandler()->setCurrentThread(index); - Threads threads = threadsHandler()->threads(); - QTC_ASSERT(index < threads.size(), return); - const int id = threads.at(index).id; + threadsHandler()->setCurrentThread(threadId); showStatusMessage(tr("Retrieving data for stack view thread 0x%1...") - .arg(id, 0, 16), 10000); - postCommand("-thread-select " + QByteArray::number(id), Discardable, + .arg(threadId.raw(), 0, 16), 10000); + postCommand("-thread-select " + QByteArray::number(threadId.raw()), Discardable, CB(handleStackSelectThread)); } @@ -3640,17 +3693,21 @@ void GdbEngine::handleStackSelectFrame(const GdbResponse &response) void GdbEngine::handleThreadInfo(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { - int currentThreadId; - const Threads threads = - ThreadsHandler::parseGdbmiThreads(response.data, ¤tThreadId); - threadsHandler()->setThreads(threads); - threadsHandler()->setCurrentThreadId(currentThreadId); + ThreadsHandler *handler = threadsHandler(); + handler->updateThreads(response.data); + // This is necessary as the current thread might not be in the list. + if (!handler->currentThread().isValid()) { + ThreadId other = handler->threadAt(0); + if (other.isValid()) + selectThread(other); + } updateViews(); // Adjust Threads combobox. if (m_hasInferiorThreadList && debuggerCore()->boolSetting(ShowThreadNames)) { postCommand("threadnames " + debuggerCore()->action(MaximalStackDepth)->value().toByteArray(), Discardable, CB(handleThreadNames)); } + reloadStack(false); // Will trigger register reload. } else { // Fall back for older versions: Try to get at least a list // of running threads. @@ -3662,37 +3719,29 @@ void GdbEngine::handleThreadListIds(const GdbResponse &response) { // "72^done,{thread-ids={thread-id="2",thread-id="1"},number-of-threads="2"} // In gdb 7.1+ additionally: current-thread-id="1" + ThreadsHandler *handler = threadsHandler(); const QList<GdbMi> items = response.data.findChild("thread-ids").children(); - Threads threads; for (int index = 0, n = items.size(); index != n; ++index) { ThreadData thread; - thread.id = items.at(index).data().toInt(); - threads.append(thread); + thread.id = ThreadId(items.at(index).data().toInt()); + handler->updateThread(thread); } - threadsHandler()->setThreads(threads); - threadsHandler()->setCurrentThreadId(m_currentThreadId); + reloadStack(false); // Will trigger register reload. } void GdbEngine::handleThreadNames(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { + ThreadsHandler *handler = threadsHandler(); GdbMi names; names.fromString(response.consoleStreamOutput); - - Threads threads = threadsHandler()->threads(); - foreach (const GdbMi &name, names.children()) { - int id = name.findChild("id").data().toInt(); - for (int index = 0, n = threads.size(); index != n; ++index) { - ThreadData &thread = threads[index]; - if (thread.id == quint64(id)) { - thread.name = decodeData(name.findChild("value").data(), - name.findChild("valueencoded").data().toInt()); - break; - } - } + ThreadData thread; + thread.id = ThreadId(name.findChild("id").data().toInt()); + thread.name = decodeData(name.findChild("value").data(), + name.findChild("valueencoded").data().toInt()); + handler->updateThread(thread); } - threadsHandler()->setThreads(threads); updateViews(); } } @@ -4535,6 +4584,12 @@ DisassemblerLines GdbEngine::parseDisassembler(const GdbResponse &response) return parseCliDisassembler(response.consoleStreamOutput); } +void GdbEngine::reloadDisassembly() +{ + setTokenBarrier(); + updateLocals(); +} + void GdbEngine::handleDisassemblerCheck(const GdbResponse &response) { m_disassembleUsesComma = response.resultClass != GdbResultDone; @@ -4726,10 +4781,10 @@ void GdbEngine::startGdb(const QStringList &args) postCommand("set width 0"); postCommand("set height 0"); - postCommand("set breakpoint always-inserted on", ConsoleCommand); + //postCommand("set breakpoint always-inserted on", ConsoleCommand); // displaced-stepping does not work in Thumb mode. //postCommand("set displaced-stepping on"); - postCommand("set trust-readonly-sections on", ConsoleCommand); + //postCommand("set trust-readonly-sections on", ConsoleCommand); postCommand("set remotecache on", ConsoleCommand); //postCommand("set non-stop on", ConsoleCommand); @@ -4794,6 +4849,11 @@ void GdbEngine::startGdb(const QStringList &args) // Dummy command to guarantee a roundtrip before the adapter proceed. postCommand("pwd", ConsoleCommand, CB(reportEngineSetupOk)); + + if (debuggerCore()->boolSetting(MultiInferior)) { + //postCommand("set follow-exec-mode new"); + postCommand("set detach-on-fork off"); + } } void GdbEngine::reportEngineSetupOk(const GdbResponse &response) @@ -4845,6 +4905,10 @@ void GdbEngine::loadPythonDumpers() postCommand("python execfile('" + dumperSourcePath + "qttypes.py')", ConsoleCommand|NonCriticalResponse); + postCommand("python qqStringCutOff = " + + debuggerCore()->action(MaximalStringLength)->value().toByteArray(), + ConsoleCommand|NonCriticalResponse); + loadInitScript(); postCommand("bbsetup", ConsoleCommand, CB(handleHasPython)); @@ -4947,6 +5011,11 @@ void GdbEngine::handleInferiorPrepared() QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); + if (debuggerCore()->boolSetting(IntelFlavor)) { + //postCommand("set follow-exec-mode new"); + postCommand("set disassembly-flavor intel"); + } + if (sp.breakOnMain) { QByteArray cmd = "tbreak "; cmd += sp.toolChainAbi.os() == Abi::WindowsOS ? "qMain" : "main"; @@ -4984,19 +5053,17 @@ void GdbEngine::finishInferiorSetup() void GdbEngine::handleDebugInfoLocation(const GdbResponse &response) { -#ifdef Q_OS_WIN - const char pathSep = ';'; -#else - const char pathSep = ':'; -#endif if (response.resultClass == GdbResultDone) { const QByteArray debugInfoLocation = startParameters().debugInfoLocation.toLocal8Bit(); if (QFile::exists(QString::fromLocal8Bit(debugInfoLocation))) { const QByteArray curDebugInfoLocations = response.consoleStreamOutput.split('"').value(1); - if (curDebugInfoLocations.isEmpty()) + if (curDebugInfoLocations.isEmpty()) { postCommand("set debug-file-directory " + debugInfoLocation); - else - postCommand("set debug-file-directory " + debugInfoLocation + pathSep + curDebugInfoLocations); + } else { + postCommand("set debug-file-directory " + debugInfoLocation + + HostOsInfo::pathListSeparator().toLatin1() + + curDebugInfoLocations); + } } } } diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index ed8f2f9cc3..5ae3da1d99 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -35,6 +35,7 @@ #include "stackframe.h" #include "watchhandler.h" #include "watchutils.h" +#include "threaddata.h" #include <QByteArray> #include <QProcess> @@ -437,7 +438,7 @@ private: ////////// Inferior Management ////////// private: ////////// View & Data Stuff ////////// protected: - void selectThread(int index); + void selectThread(ThreadId threadId); void activateFrame(int index); void resetLocation(); @@ -475,11 +476,13 @@ private: ////////// View & Data Stuff ////////// Q_SLOT void loadAllSymbols(); void loadSymbolsForStack(); void requestModuleSymbols(const QString &moduleName); + void requestModuleSections(const QString &moduleName); void reloadModules(); void examineModules(); void reloadModulesInternal(); void handleModulesList(const GdbResponse &response); void handleShowModuleSymbols(const GdbResponse &response); + void handleShowModuleSections(const GdbResponse &response); // // Snapshot specific stuff @@ -523,6 +526,7 @@ private: ////////// View & Data Stuff ////////// DisassemblerLines parseDisassembler(const GdbResponse &response); DisassemblerLines parseCliDisassembler(const QByteArray &response); DisassemblerLines parseMiDisassembler(const GdbMi &response); + Q_SLOT void reloadDisassembly(); bool m_disassembleUsesComma; @@ -661,10 +665,8 @@ protected: QString tooltipExpression() const; QScopedPointer<GdbToolTipContext> m_toolTipContext; - // For short-circuiting stack and thread list evaluation. bool m_stackNeeded; - int m_currentThreadId; // // Qml diff --git a/src/plugins/debugger/gdb/gdboptionspage.cpp b/src/plugins/debugger/gdb/gdboptionspage.cpp index 6861bce7a5..4aa5782eca 100644 --- a/src/plugins/debugger/gdb/gdboptionspage.cpp +++ b/src/plugins/debugger/gdb/gdboptionspage.cpp @@ -76,9 +76,13 @@ public: QCheckBox *checkBoxBreakOnAbort; QCheckBox *checkBoxEnableReverseDebugging; QCheckBox *checkBoxAttemptQuickStart; + QCheckBox *checkBoxMultiInferior; + QCheckBox *checkBoxIntelFlavor; QGroupBox *groupBoxStartupCommands; QTextEdit *textEditStartupCommands; + QGroupBox *groupBoxPostAttachCommands; + QTextEdit *textEditPostAttachCommands; //QGroupBox *groupBoxPluginDebugging; //QRadioButton *radioButtonAllPluginBreakpoints; @@ -207,13 +211,30 @@ GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent) "This can result in faster startup times at the price of not being able to " "set breakpoints by file and number.</body></html>")); + checkBoxMultiInferior = new QCheckBox(groupBoxGeneral); + checkBoxMultiInferior->setText(GdbOptionsPage::tr("Debug all children")); + checkBoxMultiInferior->setToolTip(GdbOptionsPage::tr( + "<html><head/><body>Keep debugging all children after a fork." + "</body></html>")); + + checkBoxIntelFlavor = new QCheckBox(groupBoxGeneral); + checkBoxIntelFlavor->setText(GdbOptionsPage::tr("Use Intel style disassembly")); + checkBoxIntelFlavor->setToolTip(GdbOptionsPage::tr( + "<html><head/><body>GDB shows by default AT&&T style disassembly." + "</body></html>")); + groupBoxStartupCommands = new QGroupBox(this); groupBoxStartupCommands->setTitle(GdbOptionsPage::tr("Additional Startup Commands")); groupBoxStartupCommands->setToolTip(GdbOptionsPage::tr( "<html><head/><body><p>GDB commands entered here will be executed after " "GDB has been started and the debugging helpers have been initialized.</p>" "<p>You can add commands to load further debugging helpers here, or " - "modify existing ones.</p><p>To execute arbitrary Python scripts, " + "modify existing ones.</p>" + "<p>To execute simple Python commands, prefix them with \"python\".</p>" + "<p>To execute sequences of Python commands spanning multiple lines " + "prepend the block with \"python\" on a separate line, and append " + "\"end\" on a separate line.</p>" + "<p>To execute arbitrary Python scripts, " "use <i>python execfile('/path/to/script.py')</i>.</p>" "</body></html>")); @@ -221,6 +242,19 @@ GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent) textEditStartupCommands->setAcceptRichText(false); textEditStartupCommands->setToolTip(groupBoxStartupCommands->toolTip()); + groupBoxPostAttachCommands = new QGroupBox(this); + groupBoxPostAttachCommands->setTitle(GdbOptionsPage::tr("Additional Attach Commands")); + groupBoxPostAttachCommands->setToolTip(GdbOptionsPage::tr( + "<html><head/><body><p>GDB commands entered here will be executed after " + "GDB has successfully attached to remote targets.</p>" + "<p>You can add commands to further set up the target here, " + "such as \"monitor reset\" or \"load\"." + "</body></html>")); + + textEditPostAttachCommands = new QTextEdit(groupBoxPostAttachCommands); + textEditPostAttachCommands->setAcceptRichText(false); + textEditPostAttachCommands->setToolTip(groupBoxPostAttachCommands->toolTip()); + /* groupBoxPluginDebugging = new QGroupBox(q); groupBoxPluginDebugging->setTitle(GdbOptionsPage::tr( @@ -255,6 +289,7 @@ GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent) formLayout->addRow(checkBoxUseDynamicType); formLayout->addRow(checkBoxLoadGdbInit); formLayout->addRow(checkBoxWarnOnReleaseBuilds); + formLayout->addRow(checkBoxIntelFlavor); formLayout->addRow(new QLabel(QString())); formLayout->addRow(labelDangerous); formLayout->addRow(checkBoxTargetAsync); @@ -264,18 +299,23 @@ GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent) formLayout->addRow(checkBoxBreakOnAbort); formLayout->addRow(checkBoxEnableReverseDebugging); formLayout->addRow(checkBoxAttemptQuickStart); + formLayout->addRow(checkBoxMultiInferior); QGridLayout *startLayout = new QGridLayout(groupBoxStartupCommands); startLayout->addWidget(textEditStartupCommands, 0, 0, 1, 1); + QGridLayout *postAttachLayout = new QGridLayout(groupBoxPostAttachCommands); + postAttachLayout->addWidget(textEditPostAttachCommands, 0, 0, 1, 1); + //QHBoxLayout *horizontalLayout = new QHBoxLayout(); //horizontalLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Preferred, QSizePolicy::Minimum)); //horizontalLayout->addWidget(labelSelectedPluginBreakpoints); //horizontalLayout->addWidget(lineEditSelectedPluginBreakpointsPattern); QGridLayout *gridLayout = new QGridLayout(this); - gridLayout->addWidget(groupBoxGeneral, 0, 0); - gridLayout->addWidget(groupBoxStartupCommands, 0, 1); + gridLayout->addWidget(groupBoxGeneral, 0, 0, 2, 1); + gridLayout->addWidget(groupBoxStartupCommands, 0, 1, 1, 1); + gridLayout->addWidget(groupBoxPostAttachCommands, 1, 1, 1, 1); //gridLayout->addWidget(groupBoxStartupCommands, 0, 1, 1, 1); //gridLayout->addWidget(radioButtonAllPluginBreakpoints, 0, 0, 1, 1); @@ -287,6 +327,7 @@ GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent) DebuggerCore *dc = debuggerCore(); group.insert(dc->action(GdbStartupCommands), textEditStartupCommands); + group.insert(dc->action(GdbPostAttachCommands), textEditPostAttachCommands); group.insert(dc->action(LoadGdbInit), checkBoxLoadGdbInit); group.insert(dc->action(AutoEnrichParameters), checkBoxAutoEnrichParameters); group.insert(dc->action(UseDynamicType), checkBoxUseDynamicType); @@ -298,6 +339,8 @@ GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent) group.insert(dc->action(BreakOnAbort), checkBoxBreakOnAbort); group.insert(dc->action(GdbWatchdogTimeout), spinBoxGdbWatchdogTimeout); group.insert(dc->action(AttemptQuickStart), checkBoxAttemptQuickStart); + group.insert(dc->action(MultiInferior), checkBoxMultiInferior); + group.insert(dc->action(IntelFlavor), checkBoxIntelFlavor); group.insert(dc->action(UseMessageBoxForSignals), checkBoxUseMessageBoxForSignals); group.insert(dc->action(SkipKnownFrames), checkBoxSkipKnownFrames); @@ -322,6 +365,7 @@ GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent) << sep << checkBoxUseMessageBoxForSignals->text() << sep << checkBoxAdjustBreakpointLocations->text() << sep << checkBoxAttemptQuickStart->text() + << sep << checkBoxMultiInferior->text() // << sep << groupBoxPluginDebugging->title() // << sep << radioButtonAllPluginBreakpoints->text() // << sep << radioButtonSelectedPluginBreakpoints->text() diff --git a/src/plugins/debugger/gdb/localplaingdbadapter.cpp b/src/plugins/debugger/gdb/localplaingdbadapter.cpp index abd6c310e6..a1db55c2de 100644 --- a/src/plugins/debugger/gdb/localplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/localplaingdbadapter.cpp @@ -37,6 +37,7 @@ #include <projectexplorer/abi.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QFileInfo> @@ -61,11 +62,8 @@ GdbLocalPlainEngine::GdbLocalPlainEngine(const DebuggerStartParameters &startPar GdbEngine::DumperHandling GdbLocalPlainEngine::dumperHandling() const { // LD_PRELOAD fails for System-Qt on Mac. -#if defined(Q_OS_WIN) || defined(Q_OS_MAC) - return DumperLoadedByGdb; -#else - return DumperLoadedByGdbPreload; -#endif + return Utils::HostOsInfo::isWindowsHost() || Utils::HostOsInfo::isMacHost() + ? DumperLoadedByGdb : DumperLoadedByGdbPreload; } void GdbLocalPlainEngine::setupEngine() diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index 9972585c4f..5c64c11dae 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -36,8 +36,10 @@ #include "gdbengine.h" #include "gdbmi.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/fancymainwindow.h> +#include <utils/qtcprocess.h> #include <projectexplorer/abi.h> #include <QFileInfo> @@ -84,7 +86,14 @@ void GdbRemoteServerEngine::setupEngine() QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("TRYING TO START ADAPTER")); if (!startParameters().serverStartScript.isEmpty()) { - m_uploadProc.start(_("/bin/sh ") + startParameters().serverStartScript); + + // Provide script information about the environment + QString arglist; + Utils::QtcProcess::addArg(&arglist, startParameters().serverStartScript); + Utils::QtcProcess::addArg(&arglist, startParameters().executable); + Utils::QtcProcess::addArg(&arglist, startParameters().remoteChannel); + + m_uploadProc.start(_("/bin/sh ") + arglist); m_uploadProc.waitForStarted(); } if (startParameters().remoteSetupNeeded) @@ -156,11 +165,6 @@ void GdbRemoteServerEngine::setupInferior() { QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); const DebuggerStartParameters &sp = startParameters(); -#ifdef Q_OS_WIN - #define PATHSEP ";" -#else - #define PATHSEP ":" -#endif QString executableFileName; if (!sp.executable.isEmpty()) { QFileInfo fi(sp.executable); @@ -178,7 +182,8 @@ void GdbRemoteServerEngine::setupInferior() // if (!remoteArch.isEmpty()) // postCommand("set architecture " + remoteArch); - const QString solibSearchPath = sp.solibSearchPath.join(QLatin1String(PATHSEP)); + const QString solibSearchPath + = sp.solibSearchPath.join(QString(Utils::HostOsInfo::pathListSeparator())); if (!solibSearchPath.isEmpty()) postCommand("set solib-search-path " + solibSearchPath.toLocal8Bit()); @@ -285,6 +290,11 @@ void GdbRemoteServerEngine::handleTargetRemote(const GdbResponse &record) // gdb server will stop the remote application itself. showMessage(_("INFERIOR STARTED")); showMessage(msgAttachedToStoppedInferior(), StatusBar); + QString postAttachCommands = debuggerCore()->stringSetting(GdbPostAttachCommands); + if (!postAttachCommands.isEmpty()) { + foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n'))) + postCommand(cmd.toLatin1()); + } handleInferiorPrepared(); } else { // 16^error,msg="hd:5555: Connection timed out." diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp index 26e3369b54..4d71e42ab8 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.cpp +++ b/src/plugins/debugger/gdb/termgdbadapter.cpp @@ -37,6 +37,7 @@ #include "debuggercore.h" #include "shared/hostutils.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <coreplugin/icore.h> @@ -79,11 +80,9 @@ GdbTermEngine::~GdbTermEngine() GdbEngine::DumperHandling GdbTermEngine::dumperHandling() const { // LD_PRELOAD fails for System-Qt on Mac. -#if defined(Q_OS_WIN) || defined(Q_OS_MAC) - return DumperLoadedByGdb; -#else - return DumperLoadedByAdapter; // Handles loading itself via LD_PRELOAD -#endif + return Utils::HostOsInfo::isWindowsHost() || Utils::HostOsInfo::isMacHost() + ? DumperLoadedByGdb + : DumperLoadedByAdapter; // Handles loading itself via LD_PRELOAD } void GdbTermEngine::setupEngine() @@ -146,25 +145,29 @@ void GdbTermEngine::setupInferior() void GdbTermEngine::handleStubAttached(const GdbResponse &response) { QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); -#ifdef Q_OS_WIN - QString errorMessage; -#endif // Q_OS_WIN + switch (response.resultClass) { case GdbResultDone: case GdbResultRunning: -#ifdef Q_OS_WIN - // Resume thread that was suspended by console stub process (see stub code). - if (winResumeThread(m_stubProc.applicationMainThreadID(), &errorMessage)) { - showMessage(QString::fromLatin1("Inferior attached, thread %1 resumed"). - arg(m_stubProc.applicationMainThreadID()), LogMisc); + if (startParameters().toolChainAbi.os() != ProjectExplorer::Abi::WindowsOS) { + showMessage(_("INFERIOR ATTACHED")); } else { - showMessage(QString::fromLatin1("Inferior attached, unable to resume thread %1: %2"). - arg(m_stubProc.applicationMainThreadID()).arg(errorMessage), - LogWarning); - } + QString errorMessage; + // Resume thread that was suspended by console stub process (see stub code). +#ifdef Q_OS_WIN + const qint64 mainThreadId = m_stubProc.applicationMainThreadID(); #else - showMessage(_("INFERIOR ATTACHED")); -#endif // Q_OS_WIN + const qint64 mainThreadId = -1; +#endif + if (winResumeThread(mainThreadId, &errorMessage)) { + showMessage(QString::fromLatin1("Inferior attached, thread %1 resumed"). + arg(mainThreadId), LogMisc); + } else { + showMessage(QString::fromLatin1("Inferior attached, unable to resume thread %1: %2"). + arg(mainThreadId).arg(errorMessage), + LogWarning); + } + } handleInferiorPrepared(); break; case GdbResultError: diff --git a/src/plugins/debugger/lldb/ipcenginehost.cpp b/src/plugins/debugger/lldb/ipcenginehost.cpp index 8145fa6391..84ac83e0cc 100644 --- a/src/plugins/debugger/lldb/ipcenginehost.cpp +++ b/src/plugins/debugger/lldb/ipcenginehost.cpp @@ -208,7 +208,6 @@ void IPCEngineHost::executeJumpToLine(const ContextData &data) rpcCall(ExecuteJumpToLine, p); } - void IPCEngineHost::activateFrame(int index) { resetLocation(); @@ -221,16 +220,15 @@ void IPCEngineHost::activateFrame(int index) rpcCall(ActivateFrame, p); } -void IPCEngineHost::selectThread(int index) +void IPCEngineHost::selectThread(ThreadId id) { resetLocation(); - Threads threads = threadsHandler()->threads(); - QTC_ASSERT(index < threads.size(), return); + QTC_ASSERT(id.isValid(), return); QByteArray p; { QDataStream s(&p, QIODevice::WriteOnly); SET_NATIVE_BYTE_ORDER(s); - s << quint64(threads.at(index).id); + s << id.raw(); } rpcCall(SelectThread, p); } @@ -442,7 +440,7 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) SET_NATIVE_BYTE_ORDER(s); quint64 token; s >> token; - threadsHandler()->setCurrentThreadId(token); + threadsHandler()->setCurrentThread(ThreadId(token)); } break; case IPCEngineGuest::ListFrames: diff --git a/src/plugins/debugger/lldb/ipcenginehost.h b/src/plugins/debugger/lldb/ipcenginehost.h index c70672bc31..fd89ee4458 100644 --- a/src/plugins/debugger/lldb/ipcenginehost.h +++ b/src/plugins/debugger/lldb/ipcenginehost.h @@ -104,7 +104,7 @@ public: void executeRunToFunction(const QString &functionName); void executeJumpToLine(const ContextData &data); void activateFrame(int index); - void selectThread(int index); + void selectThread(ThreadId index); void fetchDisassembler(DisassemblerAgent *); bool acceptsBreakpoint(BreakpointModelId) const { return true; } // FIXME void insertBreakpoint(BreakpointModelId id); diff --git a/src/plugins/debugger/localsandexpressionswindow.cpp b/src/plugins/debugger/localsandexpressionswindow.cpp index 0211c3c6ca..5e1bf28006 100644 --- a/src/plugins/debugger/localsandexpressionswindow.cpp +++ b/src/plugins/debugger/localsandexpressionswindow.cpp @@ -35,6 +35,9 @@ #include <QSplitter> #include <QStackedWidget> +const int LOCAL_WIDGET_INDEX = 0; +const int INSPECTOR_WIDGET_INDEX = 1; + namespace Debugger { namespace Internal { @@ -79,7 +82,13 @@ void LocalsAndExpressionsWindow::setShowLocals(bool showLocals) void LocalsAndExpressionsWindow::showLocals() { - m_localsAndInspector->setCurrentIndex(m_showLocals ? 0 : 1); + m_localsAndInspector->setCurrentIndex(m_showLocals ? LOCAL_WIDGET_INDEX + : INSPECTOR_WIDGET_INDEX); +} + +QWidget *LocalsAndExpressionsWindow::inspectorWidget() const +{ + return m_localsAndInspector->widget(INSPECTOR_WIDGET_INDEX); } } // namespace Internal diff --git a/src/plugins/debugger/localsandexpressionswindow.h b/src/plugins/debugger/localsandexpressionswindow.h index bf59a2618f..ec7df5dcfe 100644 --- a/src/plugins/debugger/localsandexpressionswindow.h +++ b/src/plugins/debugger/localsandexpressionswindow.h @@ -50,6 +50,7 @@ public: QWidget *returnWidget, QWidget *watchers, QWidget *parent = 0); void setShowLocals(bool showLocals); + QWidget *inspectorWidget() const; private slots: void showLocals(); diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp index 507d644914..f2245eab01 100644 --- a/src/plugins/debugger/moduleshandler.cpp +++ b/src/plugins/debugger/moduleshandler.cpp @@ -194,15 +194,17 @@ QVariant ModulesModel::data(const QModelIndex &index, int role) const void ModulesModel::setModules(const Modules &m) { + beginResetModel(); m_modules = m; - reset(); + endResetModel(); } void ModulesModel::clearModel() { if (!m_modules.isEmpty()) { + beginResetModel(); m_modules.clear(); - reset(); + endResetModel(); } } diff --git a/src/plugins/debugger/moduleshandler.h b/src/plugins/debugger/moduleshandler.h index f72c34e016..1b71c1b633 100644 --- a/src/plugins/debugger/moduleshandler.h +++ b/src/plugins/debugger/moduleshandler.h @@ -68,6 +68,24 @@ typedef QVector<Symbol> Symbols; ////////////////////////////////////////////////////////////////// // +// Section +// +////////////////////////////////////////////////////////////////// + +class Section +{ +public: + QString from; + QString to; + QString address; + QString name; + QString flags; +}; + +typedef QVector<Section> Sections; + +////////////////////////////////////////////////////////////////// +// // Module // ////////////////////////////////////////////////////////////////// diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp index 09a3ad8684..05e0dc383e 100644 --- a/src/plugins/debugger/moduleswindow.cpp +++ b/src/plugins/debugger/moduleswindow.cpp @@ -34,6 +34,7 @@ #include "debuggercore.h" #include "debuggerengine.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/savedaction.h> @@ -111,6 +112,7 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) QAction *actLoadSymbolsForModule = 0; QAction *actEditFile = 0; QAction *actShowModuleSymbols = 0; + QAction *actShowModuleSections = 0; QAction *actShowDependencies = 0; // Show dependencies by running 'depends.exe' if (name.isEmpty()) { actLoadSymbolsForModule = new QAction(tr("Load Symbols for Module"), &menu); @@ -119,6 +121,8 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) actEditFile->setEnabled(false); actShowModuleSymbols = new QAction(tr("Show Symbols"), &menu); actShowModuleSymbols->setEnabled(false); + actShowModuleSections = new QAction(tr("Show Sections"), &menu); + actShowModuleSections->setEnabled(false); actShowDependencies = new QAction(tr("Show Dependencies"), &menu); actShowDependencies->setEnabled(false); } else { @@ -130,12 +134,14 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) actShowModuleSymbols = new QAction(tr("Show Symbols in File \"%1\"").arg(name), &menu); actShowModuleSymbols->setEnabled(engine->hasCapability(ShowModuleSymbolsCapability)); + actShowModuleSections + = new QAction(tr("Show Sections in File \"%1\"").arg(name), &menu); + actShowModuleSections->setEnabled(engine->hasCapability(ShowModuleSymbolsCapability)); actShowDependencies = new QAction(tr("Show Dependencies of \"%1\"").arg(name), &menu); actShowDependencies->setEnabled(!fileName.isEmpty()); -#ifndef Q_OS_WIN - // FIXME: Dependencies only available on Windows, when "depends" is installed. - actShowDependencies->setEnabled(false); -#endif + if (!Utils::HostOsInfo::isWindowsHost()) + // FIXME: Dependencies only available on Windows, when "depends" is installed. + actShowDependencies->setEnabled(false); } menu.addAction(actUpdateModuleList); @@ -146,6 +152,7 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) menu.addAction(actLoadSymbolsForModule); menu.addAction(actEditFile); menu.addAction(actShowModuleSymbols); + menu.addAction(actShowModuleSections); addBaseContextActions(&menu); QAction *act = menu.exec(ev->globalPos()); @@ -164,6 +171,8 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) engine->gotoLocation(fileName); else if (act == actShowModuleSymbols) engine->requestModuleSymbols(fileName); + else if (act == actShowModuleSections) + engine->requestModuleSections(fileName); else if (actShowDependencies && act == actShowDependencies) QProcess::startDetached(QLatin1String("depends"), QStringList(fileName)); else diff --git a/src/plugins/debugger/namedemangler/namedemangler.cpp b/src/plugins/debugger/namedemangler/namedemangler.cpp index 88e35ebbb1..840b1bd483 100644 --- a/src/plugins/debugger/namedemangler/namedemangler.cpp +++ b/src/plugins/debugger/namedemangler/namedemangler.cpp @@ -55,7 +55,7 @@ bool NameDemanglerPrivate::demangle(const QString &mangledName) { bool success; try { - m_parseState.m_mangledName = mangledName.toAscii(); + m_parseState.m_mangledName = mangledName.toLatin1(); m_parseState.m_pos = 0; m_demangledName.clear(); diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index 551f712bd6..8539d99048 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -321,9 +321,9 @@ void PdbEngine::activateFrame(int frameIndex) gotoLocation(handler->currentFrame()); } -void PdbEngine::selectThread(int index) +void PdbEngine::selectThread(ThreadId threadId) { - Q_UNUSED(index) + Q_UNUSED(threadId) } bool PdbEngine::acceptsBreakpoint(BreakpointModelId id) const diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h index 6c8365a0a3..82cdd81ac7 100644 --- a/src/plugins/debugger/pdb/pdbengine.h +++ b/src/plugins/debugger/pdb/pdbengine.h @@ -86,7 +86,7 @@ private: void executeJumpToLine(const ContextData &data); void activateFrame(int index); - void selectThread(int index); + void selectThread(ThreadId threadId); bool acceptsBreakpoint(BreakpointModelId id) const; void insertBreakpoint(BreakpointModelId id); diff --git a/src/plugins/debugger/procinterrupt.cpp b/src/plugins/debugger/procinterrupt.cpp index 49c003972b..c52f2f400f 100644 --- a/src/plugins/debugger/procinterrupt.cpp +++ b/src/plugins/debugger/procinterrupt.cpp @@ -78,7 +78,7 @@ static BOOL isWow64Process(HANDLE hproc) } // Open the process and break into it -bool Debugger::Internal::interruptProcess(int pID, int engineType, QString *errorMessage) +bool Debugger::Internal::interruptProcess(int pID, int engineType, QString *errorMessage, const bool engineExecutableIs64Bit) { bool ok = false; HANDLE inferior = NULL; @@ -98,9 +98,10 @@ bool Debugger::Internal::interruptProcess(int pID, int engineType, QString *erro // Qt-Creator compiled 64 bit // Windows must be 64 bit // CDB 64 bit: use DebugBreakProcess for 32 an 64 bit processes. - // CDB 32 bit: untested + // TODO: CDB 32 bit: inferior 32 bit can not use DebugBreakProcess, we need a win32interrupt.exe // GDB: not supported const bool useDebugBreakApi= true; + Q_UNUSED(engineExecutableIs64Bit) #else // Qt-Creator compiled 32 bit: @@ -115,8 +116,9 @@ bool Debugger::Internal::interruptProcess(int pID, int engineType, QString *erro // works in theory for other WOW64 processes, the break appears // as a WOW64 breakpoint, which CDB is configured to ignore since // it also triggers on module loading. - // CDB 32 bit: untested - useDebugBreakApi = false; + // CDB 32 bit: 32 bit applications can not be interrupted using the win64interrupt.exe + // So we need to find out which bitness the currently used cdb has. + useDebugBreakApi = !engineExecutableIs64Bit; } else { // GDB: Use win64interrupt for native 64bit processes only (it fails // for WOW64 processes. @@ -165,7 +167,7 @@ bool Debugger::Internal::interruptProcess(int pID, int engineType, QString *erro #include <string.h> bool Debugger::Internal::interruptProcess(int pID, int /* engineType */, - QString *errorMessage) + QString *errorMessage, const bool /*engineExecutableIs64Bit*/) { if (pID <= 0) { *errorMessage = msgCannotInterrupt(pID, QString::fromLatin1("Invalid process id.")); diff --git a/src/plugins/debugger/procinterrupt.h b/src/plugins/debugger/procinterrupt.h index 4382682716..df3c1facbb 100644 --- a/src/plugins/debugger/procinterrupt.h +++ b/src/plugins/debugger/procinterrupt.h @@ -35,7 +35,8 @@ namespace Debugger { namespace Internal { -bool interruptProcess(int pID, int engineType, QString *errorMessage); +bool interruptProcess(int pID, int engineType, QString *errorMessage, + const bool engineExecutableIs64Bit = false); } // Internal } // GdbDebugger diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index ca9f835cb4..f1e789d55c 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -33,7 +33,6 @@ #include "debuggerstartparameters.h" #include "stackhandler.h" #include "qmlengine.h" -#include "qtmessageloghandler.h" #include "watchdata.h" #include <coreplugin/icore.h> @@ -41,6 +40,7 @@ #include <texteditor/itexteditor.h> #include <qmljseditor/qmljseditorconstants.h> #include <cppeditor/cppeditorconstants.h> +#include <qmljs/consolemanagerinterface.h> #include <QTimer> @@ -267,9 +267,9 @@ bool QmlCppEngine::acceptsBreakpoint(BreakpointModelId id) const || d->m_qmlEngine->acceptsBreakpoint(id); } -void QmlCppEngine::selectThread(int index) +void QmlCppEngine::selectThread(ThreadId threadId) { - d->m_activeEngine->selectThread(index); + d->m_activeEngine->selectThread(threadId); } void QmlCppEngine::assignValueInDebugger(const WatchData *data, @@ -401,11 +401,6 @@ void QmlCppEngine::executeDebuggerCommand(const QString &command, DebuggerLangua d->m_cppEngine->executeDebuggerCommand(command, languages); } -bool QmlCppEngine::evaluateScriptExpression(const QString &expression) -{ - return d->m_qmlEngine->evaluateScriptExpression(expression); -} - ///////////////////////////////////////////////////////// void QmlCppEngine::setupEngine() @@ -467,6 +462,9 @@ void QmlCppEngine::shutdownEngine() { EDEBUG("\nMASTER SHUTDOWN ENGINE"); d->m_cppEngine->shutdownSlaveEngine(); + QmlJS::ConsoleManagerInterface *consoleManager = QmlJS::ConsoleManagerInterface::instance(); + if (consoleManager) + consoleManager->setScriptEvaluator(0); } void QmlCppEngine::quitDebugger() @@ -793,11 +791,6 @@ void QmlCppEngine::resetLocation() DebuggerEngine::resetLocation(); } -Internal::QtMessageLogHandler *QmlCppEngine::qtMessageLogHandler() const -{ - return d->m_qmlEngine->qtMessageLogHandler(); -} - DebuggerEngine *QmlCppEngine::cppEngine() const { return d->m_cppEngine; diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index e2596875a2..64f531277d 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -77,7 +77,7 @@ public: void attemptBreakpointSynchronization(); bool acceptsBreakpoint(BreakpointModelId id) const; - void selectThread(int index); + void selectThread(ThreadId threadId); void assignValueInDebugger(const WatchData *data, const QString &expr, const QVariant &value); @@ -92,8 +92,6 @@ public: int timeout = -1) const; void resetLocation(); - Internal::QtMessageLogHandler *qtMessageLogHandler() const; - void notifyInferiorIll(); protected: @@ -112,7 +110,6 @@ protected: void executeRunToFunction(const QString &functionName); void executeJumpToLine(const ContextData &data); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); - bool evaluateScriptExpression(const QString &expression); void setupEngine(); void setupInferior(); diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index e142e7bddc..c2274c5e68 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -41,6 +41,8 @@ #include "debuggerrunner.h" #include "debuggerstringutils.h" #include "debuggertooltipmanager.h" +#include "localsandexpressionswindow.h" +#include "watchwindow.h" #include "breakhandler.h" #include "moduleshandler.h" @@ -49,13 +51,13 @@ #include "watchhandler.h" #include "sourcefileshandler.h" #include "watchutils.h" -#include "qtmessageloghandler.h" -#include <extensionsystem/pluginmanager.h> #include <qmldebug/baseenginedebugclient.h> #include <qmljseditor/qmljseditorconstants.h> #include <qmljs/parser/qmljsast_p.h> #include <qmljs/qmljsmodelmanagerinterface.h> +#include <qmljs/consolemanagerinterface.h> +#include <qmljs/consoleitem.h> #include <utils/environment.h> #include <utils/qtcassert.h> @@ -82,6 +84,8 @@ #include <QTcpSocket> #include <QHostAddress> +#include <QDockWidget> + #define DEBUG_QML 1 #if DEBUG_QML # define SDEBUG(s) qDebug() << s @@ -259,6 +263,11 @@ public: quint32 *column; }; +QmlJS::ConsoleManagerInterface *qmlConsoleManager() +{ + return QmlJS::ConsoleManagerInterface::instance(); +} + /////////////////////////////////////////////////////////////////////// // // QmlEngine @@ -274,8 +283,6 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters) { setObjectName(QLatin1String("QmlEngine")); - ExtensionSystem::PluginManager::addObject(this); - connect(&m_adapter, SIGNAL(connectionError(QAbstractSocket::SocketError)), SLOT(connectionError(QAbstractSocket::SocketError))); connect(&m_adapter, SIGNAL(serviceConnectionError(QString)), @@ -289,7 +296,7 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters) SLOT(updateCurrentContext())); connect(this->stackHandler(), SIGNAL(currentIndexChanged()), SLOT(updateCurrentContext())); - connect(&m_inspectorAdapter, SIGNAL(selectionChanged()), + connect(inspectorTreeView(), SIGNAL(currentIndexChanged(QModelIndex)), SLOT(updateCurrentContext())); connect(m_inspectorAdapter.agent(), SIGNAL( expressionResult(quint32,QVariant)), @@ -329,27 +336,23 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters) m_noDebugOutputTimer.setInterval(8000); connect(&m_noDebugOutputTimer, SIGNAL(timeout()), this, SLOT(tryToConnect())); - qtMessageLogHandler()->setHasEditableRow(true); - - connect(ModelManagerInterface::instance(), - SIGNAL(documentUpdated(QmlJS::Document::Ptr)), - this, - SLOT(documentUpdated(QmlJS::Document::Ptr))); - + ModelManagerInterface *mmIface = ModelManagerInterface::instance(); + if (mmIface) { + connect(ModelManagerInterface::instance(), SIGNAL(documentUpdated(QmlJS::Document::Ptr)), + this, SLOT(documentUpdated(QmlJS::Document::Ptr))); + } // we won't get any debug output if (startParameters.useTerminal) { m_noDebugOutputTimer.setInterval(0); m_retryOnConnectFail = true; m_automaticConnect = true; } + if (qmlConsoleManager()) + qmlConsoleManager()->setScriptEvaluator(this); } QmlEngine::~QmlEngine() { - if (ExtensionSystem::PluginManager::allObjects().contains(this)) { - ExtensionSystem::PluginManager::removeObject(this); - } - QList<Core::IEditor *> editorsToClose; QHash<QString, QWeakPointer<TextEditor::ITextEditor> >::iterator iter; @@ -653,6 +656,8 @@ void QmlEngine::shutdownInferior() void QmlEngine::shutdownEngine() { + if (qmlConsoleManager()) + qmlConsoleManager()->setScriptEvaluator(0); m_noDebugOutputTimer.stop(); // double check (ill engine?): @@ -781,9 +786,9 @@ void QmlEngine::activateFrame(int index) gotoLocation(stackHandler()->frames().value(index)); } -void QmlEngine::selectThread(int index) +void QmlEngine::selectThread(ThreadId threadId) { - Q_UNUSED(index) + Q_UNUSED(threadId) } void QmlEngine::insertBreakpoint(BreakpointModelId id) @@ -1033,14 +1038,61 @@ void QmlEngine::synchronizeWatchers() } } +QmlJS::ConsoleItem *constructLogItemTree(QmlJS::ConsoleItem *parent, + const QVariant &result, + const QString &key = QString()) +{ + using namespace QmlJS; + bool sorted = debuggerCore()->boolSetting(SortStructMembers); + if (!result.isValid()) + return 0; + + ConsoleItem *item = new ConsoleItem(parent); + if (result.type() == QVariant::Map) { + if (key.isEmpty()) + item->setText(_("Object")); + else + item->setText(key + _(" : Object")); + + QMapIterator<QString, QVariant> i(result.toMap()); + while (i.hasNext()) { + i.next(); + ConsoleItem *child = constructLogItemTree(item, i.value(), i.key()); + if (child) + item->insertChild(child, sorted); + } + } else if (result.type() == QVariant::List) { + if (key.isEmpty()) + item->setText(_("List")); + else + item->setText(QString(_("[%1] : List")).arg(key)); + QVariantList resultList = result.toList(); + for (int i = 0; i < resultList.count(); i++) { + ConsoleItem *child = constructLogItemTree(item, resultList.at(i), + QString::number(i)); + if (child) + item->insertChild(child, sorted); + } + } else if (result.canConvert(QVariant::String)) { + item->setText(result.toString()); + } else { + item->setText(_("Unknown Value")); + } + + return item; +} + void QmlEngine::expressionEvaluated(quint32 queryId, const QVariant &result) { if (queryIds.contains(queryId)) { queryIds.removeOne(queryId); - QtMessageLogItem *item = constructLogItemTree(qtMessageLogHandler()->root(), - result); - if (item) - qtMessageLogHandler()->appendItem(item); + using namespace QmlJS; + ConsoleManagerInterface *consoleManager = qmlConsoleManager(); + if (consoleManager) { + ConsoleItem *item = constructLogItemTree(consoleManager->rootItem(), result); + if (item) + consoleManager->printToConsolePane(item); + } } } @@ -1093,36 +1145,55 @@ void QmlEngine::documentUpdated(QmlJS::Document::Ptr doc) void QmlEngine::updateCurrentContext() { - const QString context = state() == InferiorStopOk ? - stackHandler()->currentFrame().function : - m_inspectorAdapter.currentSelectedDisplayName(); - showMessage(tr("Context: ").append(context), QtMessageLogStatus); + QString context; + if (state() == InferiorStopOk) { + context = stackHandler()->currentFrame().function; + } else { + QModelIndex currentIndex = inspectorTreeView()->currentIndex(); + const WatchData *currentData = watchHandler()->watchData(currentIndex); + const WatchData *parentData = watchHandler()->watchData(currentIndex.parent()); + const WatchData *grandParentData = watchHandler()->watchData( + currentIndex.parent().parent()); + if (currentData->id != parentData->id) + context = currentData->name; + else if (parentData->id != grandParentData->id) + context = parentData->name; + else + context = grandParentData->name; + } + + QmlJS::ConsoleManagerInterface *consoleManager = qmlConsoleManager(); + if (consoleManager) + consoleManager->setContext(tr("Context: ").append(context)); } void QmlEngine::appendDebugOutput(QtMsgType type, const QString &message, const QmlDebug::QDebugContextInfo &info) { - QtMessageLogHandler::ItemType itemType; + using namespace QmlJS; + ConsoleItem::ItemType itemType; switch (type) { case QtDebugMsg: - itemType = QtMessageLogHandler::DebugType; + itemType = ConsoleItem::DebugType; break; case QtWarningMsg: - itemType = QtMessageLogHandler::WarningType; + itemType = ConsoleItem::WarningType; break; case QtCriticalMsg: case QtFatalMsg: - itemType = QtMessageLogHandler::ErrorType; + itemType = ConsoleItem::ErrorType; break; default: //This case is not possible return; } - QtMessageLogItem *item = new QtMessageLogItem(qtMessageLogHandler()->root(), - itemType, message); - item->file = info.file; - item->line = info.line; - qtMessageLogHandler()->appendItem(item); + ConsoleManagerInterface *consoleManager = qmlConsoleManager(); + if (consoleManager) { + ConsoleItem *item = new ConsoleItem(consoleManager->rootItem(), itemType, message); + item->file = info.file; + item->line = info.line; + consoleManager->printToConsolePane(item); + } } void QmlEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages languages) @@ -1132,40 +1203,29 @@ void QmlEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages } } -bool QmlEngine::evaluateScriptExpression(const QString &expression) +bool QmlEngine::evaluateScript(const QString &expression) { bool didEvaluate = true; - //Check if string is only white spaces - if (!expression.trimmed().isEmpty()) { - //check if it can be evaluated - if (canEvaluateScript(expression)) { - //Evaluate expression based on engine state - //When engine->state() == InferiorStopOk, the expression - //is sent to V8DebugService. In all other cases, the - //expression is evaluated by QDeclarativeEngine. - if (state() != InferiorStopOk) { - QmlInspectorAgent *agent = m_inspectorAdapter.agent(); - quint32 queryId - = agent->queryExpressionResult( - m_inspectorAdapter.currentSelectedDebugId(), - expression); - if (queryId) { - queryIds << queryId; - } else { - didEvaluate = false; - qtMessageLogHandler()-> - appendItem( - new QtMessageLogItem( - qtMessageLogHandler()->root(), - QtMessageLogHandler::ErrorType, - _("Error evaluating expression."))); - } - } else { - executeDebuggerCommand(expression, QmlLanguage); - } + // Evaluate expression based on engine state + // When engine->state() == InferiorStopOk, the expression is sent to debuggerClient. + if (state() != InferiorStopOk) { + QModelIndex currentIndex = inspectorTreeView()->currentIndex(); + QmlInspectorAgent *agent = m_inspectorAdapter.agent(); + quint32 queryId = agent->queryExpressionResult(watchHandler()->watchData(currentIndex)->id, + expression); + if (queryId) { + queryIds << queryId; } else { didEvaluate = false; + using namespace QmlJS; + ConsoleManagerInterface *consoleManager = qmlConsoleManager(); + if (consoleManager) { + consoleManager->printToConsolePane(ConsoleItem::ErrorType, + _("Error evaluating expression.")); + } } + } else { + executeDebuggerCommand(expression, QmlLanguage); } return didEvaluate; } @@ -1272,69 +1332,39 @@ bool QmlEngine::canEvaluateScript(const QString &script) return m_interpreter.canEvaluate(); } -QtMessageLogItem *QmlEngine::constructLogItemTree( - QtMessageLogItem *parent, const QVariant &result, const QString &key) -{ - if (!result.isValid()) - return 0; - - QtMessageLogItem *item = new QtMessageLogItem(parent); - if (result.type() == QVariant::Map) { - if (key.isEmpty()) - item->setText(_("Object")); - else - item->setText(key + _(" : Object")); - - QMapIterator<QString, QVariant> i(result.toMap()); - while (i.hasNext()) { - i.next(); - QtMessageLogItem *child = constructLogItemTree(item, - i.value(), i.key()); - if (child) - item->insertChild(child); - } - } else if (result.type() == QVariant::List) { - if (key.isEmpty()) - item->setText(_("List")); - else - item->setText(QString(_("[%1] : List")).arg(key)); - QVariantList resultList = result.toList(); - for (int i = 0; i < resultList.count(); i++) { - QtMessageLogItem *child = constructLogItemTree(item, resultList.at(i), - QString::number(i)); - if (child) - item->insertChild(child); - } - } else if (result.canConvert(QVariant::String)) { - item->setText(result.toString()); - } else { - item->setText(_("Unknown Value")); - } - - return item; -} - bool QmlEngine::adjustBreakpointLineAndColumn( const QString &filePath, quint32 *line, quint32 *column, bool *valid) { - bool success = true; + bool success = false; //check if file is in the latest snapshot //ignoring documentChangedOnDisk //TODO:: update breakpoints if document is changed. - Document::Ptr doc = ModelManagerInterface::instance()->newestSnapshot(). - document(filePath); - if (doc.isNull()) { - ModelManagerInterface::instance()->updateSourceFiles( - QStringList() << filePath, false); - success = false; - } else { - ASTWalker walker; - walker(doc->ast(), line, column); - *valid = walker.done; + 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; } +WatchTreeView *QmlEngine::inspectorTreeView() const +{ + DebuggerMainWindow *dw = qobject_cast<DebuggerMainWindow *>(debuggerCore()->mainWindow()); + LocalsAndExpressionsWindow *leW = qobject_cast<LocalsAndExpressionsWindow *>( + dw->dockWidget(QLatin1String(Constants::DOCKWIDGET_WATCHERS))->widget()); + WatchWindow *inspectorWindow = qobject_cast<WatchWindow *>(leW->inspectorWidget()); + return qobject_cast<WatchTreeView *>(inspectorWindow->treeView()); +} + DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp) { return new QmlEngine(sp); diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 8cef4dc3ed..fa1f312383 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -39,6 +39,7 @@ #include <qmldebug/qdebugmessageclient.h> #include <qmldebug/qmloutputparser.h> #include <qmljs/qmljsdocument.h> +#include <qmljs/iscriptevaluator.h> #include <utils/outputformat.h> #include <QAbstractSocket> @@ -52,9 +53,9 @@ namespace Debugger { namespace Internal { class QmlAdapter; -class QtMessageLogItem; +class WatchTreeView; -class QmlEngine : public DebuggerEngine +class QmlEngine : public DebuggerEngine, QmlJS::IScriptEvaluator { Q_OBJECT @@ -139,7 +140,7 @@ private: void executeJumpToLine(const ContextData &data); void activateFrame(int index); - void selectThread(int index); + void selectThread(ThreadId threadId); void attemptBreakpointSynchronization(); void removeBreakpoint(BreakpointModelId id); @@ -162,7 +163,7 @@ private: void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); - bool evaluateScriptExpression(const QString &expression); + bool evaluateScript(const QString &expression); bool hasCapability(unsigned) const; void quitDebugger(); @@ -180,12 +181,11 @@ private: void updateEditor(Core::IEditor *editor, const QTextDocument *document); bool canEvaluateScript(const QString &script); - QtMessageLogItem *constructLogItemTree(QtMessageLogItem *parent, - const QVariant &result, - const QString &key = QString()); bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line, quint32 *column, bool *valid); + WatchTreeView *inspectorTreeView() const; + QmlAdapter m_adapter; QmlInspectorAdapter m_inspectorAdapter; ProjectExplorer::ApplicationLauncher m_applicationLauncher; diff --git a/src/plugins/debugger/qml/qmlinspectoradapter.cpp b/src/plugins/debugger/qml/qmlinspectoradapter.cpp index 164d77258c..aac3a9da83 100644 --- a/src/plugins/debugger/qml/qmlinspectoradapter.cpp +++ b/src/plugins/debugger/qml/qmlinspectoradapter.cpp @@ -303,40 +303,42 @@ void QmlInspectorAdapter::createPreviewForEditor(Core::IEditor *newEditor) QString filename = newEditor->document()->fileName(); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); - QmlJS::Document::Ptr doc = modelManager->snapshot().document(filename); - if (!doc) { - if (filename.endsWith(QLatin1String(".qml")) || filename.endsWith(QLatin1String(".js"))) { - // add to list of docs that we have to update when - // snapshot figures out that there's a new document - m_pendingPreviewDocumentNames.append(filename); + if (modelManager) { + QmlJS::Document::Ptr doc = modelManager->snapshot().document(filename); + if (!doc) { + if (filename.endsWith(QLatin1String(".qml")) || filename.endsWith(QLatin1String(".js"))) { + // add to list of docs that we have to update when + // snapshot figures out that there's a new document + m_pendingPreviewDocumentNames.append(filename); + } + return; + } + if (!doc->qmlProgram() && !filename.endsWith(QLatin1String(".js"))) + return; + + QmlJS::Document::Ptr initdoc = m_loadedSnapshot.document(filename); + if (!initdoc) + initdoc = doc; + + if (m_textPreviews.contains(filename)) { + QmlLiveTextPreview *preview = m_textPreviews.value(filename); + preview->associateEditor(newEditor); + } else { + QmlLiveTextPreview *preview + = new QmlLiveTextPreview(doc, initdoc, this, this); + connect(preview, + SIGNAL(selectedItemsChanged(QList<int>)), + SLOT(selectObjectsFromEditor(QList<int>))); + + preview->setApplyChangesToQmlInspector( + debuggerCore()->action(QmlUpdateOnSave)->isChecked()); + connect(preview, SIGNAL(reloadRequest()), + this, SLOT(onReload())); + + m_textPreviews.insert(newEditor->document()->fileName(), preview); + preview->associateEditor(newEditor); + preview->updateDebugIds(); } - return; - } - if (!doc->qmlProgram() && !filename.endsWith(QLatin1String(".js"))) - return; - - QmlJS::Document::Ptr initdoc = m_loadedSnapshot.document(filename); - if (!initdoc) - initdoc = doc; - - if (m_textPreviews.contains(filename)) { - QmlLiveTextPreview *preview = m_textPreviews.value(filename); - preview->associateEditor(newEditor); - } else { - QmlLiveTextPreview *preview - = new QmlLiveTextPreview(doc, initdoc, this, this); - connect(preview, - SIGNAL(selectedItemsChanged(QList<int>)), - SLOT(selectObjectsFromEditor(QList<int>))); - - preview->setApplyChangesToQmlInspector( - debuggerCore()->action(QmlUpdateOnSave)->isChecked()); - connect(preview, SIGNAL(reloadRequest()), - this, SLOT(onReload())); - - m_textPreviews.insert(newEditor->document()->fileName(), preview); - preview->associateEditor(newEditor); - preview->updateDebugIds(); } } @@ -427,15 +429,17 @@ void QmlInspectorAdapter::setActiveEngineClient(BaseEngineDebugClient *client) m_engineClient->status() == QmlDebug::Enabled) { QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); - QmlJS::Snapshot snapshot = modelManager->snapshot(); - for (QHash<QString, QmlLiveTextPreview *>::const_iterator it - = m_textPreviews.constBegin(); - it != m_textPreviews.constEnd(); ++it) { - QmlJS::Document::Ptr doc = snapshot.document(it.key()); - it.value()->resetInitialDoc(doc); + if (modelManager) { + QmlJS::Snapshot snapshot = modelManager->snapshot(); + for (QHash<QString, QmlLiveTextPreview *>::const_iterator it + = m_textPreviews.constBegin(); + it != m_textPreviews.constEnd(); ++it) { + QmlJS::Document::Ptr doc = snapshot.document(it.key()); + it.value()->resetInitialDoc(doc); + } + + initializePreviews(); } - - initializePreviews(); } } @@ -444,22 +448,24 @@ void QmlInspectorAdapter::initializePreviews() Core::EditorManager *em = Core::EditorManager::instance(); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); - m_loadedSnapshot = modelManager->snapshot(); - - if (!m_listeningToEditorManager) { - m_listeningToEditorManager = true; - connect(em, SIGNAL(editorAboutToClose(Core::IEditor*)), - this, SLOT(removePreviewForEditor(Core::IEditor*))); - connect(em, SIGNAL(editorOpened(Core::IEditor*)), - this, SLOT(createPreviewForEditor(Core::IEditor*))); - connect(modelManager, - SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), - this, SLOT(updatePendingPreviewDocuments(QmlJS::Document::Ptr))); - } + if (modelManager) { + m_loadedSnapshot = modelManager->snapshot(); + + if (!m_listeningToEditorManager) { + m_listeningToEditorManager = true; + connect(em, SIGNAL(editorAboutToClose(Core::IEditor*)), + this, SLOT(removePreviewForEditor(Core::IEditor*))); + connect(em, SIGNAL(editorOpened(Core::IEditor*)), + this, SLOT(createPreviewForEditor(Core::IEditor*))); + connect(modelManager, + SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), + this, SLOT(updatePendingPreviewDocuments(QmlJS::Document::Ptr))); + } - // initial update - foreach (Core::IEditor *editor, em->openedEditors()) - createPreviewForEditor(editor); + // initial update + foreach (Core::IEditor *editor, em->openedEditors()) + createPreviewForEditor(editor); + } } void QmlInspectorAdapter::showConnectionStatusMessage(const QString &message) @@ -504,12 +510,7 @@ void QmlInspectorAdapter::selectObject(const ObjectReference &obj, if (target == EditorTarget) gotoObjectReferenceDefinition(obj.source()); - if (!agent()->selectObjectInTree(obj.debugId())) - return; - - m_currentSelectedDebugId = obj.debugId(); - m_currentSelectedDebugName = agent()->displayName(obj.debugId()); - emit selectionChanged(); + agent()->selectObjectInTree(obj.debugId()); } void QmlInspectorAdapter::deletePreviews() @@ -543,13 +544,15 @@ void QmlInspectorAdapter::onReloaded() { QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); - QmlJS::Snapshot snapshot = modelManager->snapshot(); - m_loadedSnapshot = snapshot; - for (QHash<QString, QmlLiveTextPreview *>::const_iterator it - = m_textPreviews.constBegin(); - it != m_textPreviews.constEnd(); ++it) { - QmlJS::Document::Ptr doc = snapshot.document(it.key()); - it.value()->resetInitialDoc(doc); + if (modelManager) { + QmlJS::Snapshot snapshot = modelManager->snapshot(); + m_loadedSnapshot = snapshot; + for (QHash<QString, QmlLiveTextPreview *>::const_iterator it + = m_textPreviews.constBegin(); + it != m_textPreviews.constEnd(); ++it) { + QmlJS::Document::Ptr doc = snapshot.document(it.key()); + it.value()->resetInitialDoc(doc); + } } m_agent->reloadEngines(); } diff --git a/src/plugins/debugger/qml/qmlinspectoradapter.h b/src/plugins/debugger/qml/qmlinspectoradapter.h index dc5272d782..11833e3173 100644 --- a/src/plugins/debugger/qml/qmlinspectoradapter.h +++ b/src/plugins/debugger/qml/qmlinspectoradapter.h @@ -75,7 +75,6 @@ public: signals: void expressionResult(); - void selectionChanged(); private slots: void clientStatusChanged(QmlDebug::ClientStatus status); diff --git a/src/plugins/debugger/qml/qmllivetextpreview.cpp b/src/plugins/debugger/qml/qmllivetextpreview.cpp index 0eb5497e73..64f6a22852 100644 --- a/src/plugins/debugger/qml/qmllivetextpreview.cpp +++ b/src/plugins/debugger/qml/qmllivetextpreview.cpp @@ -363,10 +363,10 @@ QmlLiveTextPreview::QmlLiveTextPreview(const QmlJS::Document::Ptr &doc, QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); - - connect(modelManager, SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), - SLOT(documentChanged(QmlJS::Document::Ptr))); - + if (modelManager) { + connect(modelManager, SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), + SLOT(documentChanged(QmlJS::Document::Ptr))); + } connect(m_inspectorAdapter->agent(), SIGNAL(objectTreeUpdated()), SLOT(updateDebugIds())); connect(this, @@ -714,7 +714,7 @@ void QmlLiveTextPreview::showSyncWarning( foreach (TextEditor::BaseTextEditorWidget *editor, m_editors) { if (editor) { Core::InfoBar *infoBar = editor->editorDocument()->infoBar(); - Core::InfoBarEntry info(QLatin1String(INFO_OUT_OF_SYNC), errorMessage); + Core::InfoBarEntry info(Core::Id(INFO_OUT_OF_SYNC), errorMessage); BaseToolsClient *toolsClient = m_inspectorAdapter->toolsClient(); if (toolsClient && toolsClient->supportReload()) info.setCustomButtonInfo(tr("Reload QML"), this, @@ -735,7 +735,7 @@ void QmlLiveTextPreview::removeOutofSyncInfo() foreach (TextEditor::BaseTextEditorWidget *editor, m_editors) { if (editor) { Core::InfoBar *infoBar = editor->editorDocument()->infoBar(); - infoBar->removeInfo(QLatin1String(INFO_OUT_OF_SYNC)); + infoBar->removeInfo(Core::Id(INFO_OUT_OF_SYNC)); } } } diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index 79360a6b16..588ad937fe 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -36,12 +36,16 @@ #include "breakhandler.h" #include "qmlengine.h" #include "stackhandler.h" -#include "qtmessageloghandler.h" +#include "debuggercore.h" +#include "debuggeractions.h" #include <utils/qtcassert.h> #include <coreplugin/editormanager/editormanager.h> #include <texteditor/basetexteditor.h> +#include <qmljs/consolemanagerinterface.h> +#include <qmljs/consoleitem.h> + #include <QTextBlock> #include <QVariant> #include <QStack> @@ -116,19 +120,14 @@ public: void version(); //void profile(ProfileCommand command); //NOT SUPPORTED void gc(); - - QmlV8ObjectData extractData(const QVariant &data, const QVariant &refsVal); void clearCache(); void logSendMessage(const QString &msg) const; void logReceiveMessage(const QString &msg) const; - QtMessageLogItem *constructLogItemTree(QtMessageLogItem *parent, - const QmlV8ObjectData &objectData, const QVariant &refsVal); private: QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray()); QScriptValue initObject(); - QVariant valueFromRef(int handle, const QVariant &refsVal, bool *success); public: QmlV8DebuggerClient *q; @@ -761,8 +760,23 @@ void QmlV8DebuggerClientPrivate::gc() q->sendMessage(packMessage(V8REQUEST, jsonMessage.toString().toUtf8())); } -QmlV8ObjectData QmlV8DebuggerClientPrivate::extractData(const QVariant &data, - const QVariant &refsVal) +QVariant valueFromRef(int handle, const QVariant &refsVal, bool *success) +{ + *success = false; + QVariant variant; + const QVariantList refs = refsVal.toList(); + foreach (const QVariant &ref, refs) { + const QVariantMap refData = ref.toMap(); + if (refData.value(_(HANDLE)).toInt() == handle) { + variant = refData; + *success = true; + break; + } + } + return variant; +} + +QmlV8ObjectData extractData(const QVariant &data, const QVariant &refsVal) { // { "handle" : <handle>, // "type" : <"undefined", "null", "boolean", "number", "string", "object", "function" or "frame"> @@ -900,24 +914,6 @@ QScriptValue QmlV8DebuggerClientPrivate::initObject() return jsonVal; } -QVariant QmlV8DebuggerClientPrivate::valueFromRef(int handle, - const QVariant &refsVal, - bool *success) -{ - *success = false; - QVariant variant; - const QVariantList refs = refsVal.toList(); - foreach (const QVariant &ref, refs) { - const QVariantMap refData = ref.toMap(); - if (refData.value(_(HANDLE)).toInt() == handle) { - variant = refData; - *success = true; - break; - } - } - return variant; -} - void QmlV8DebuggerClientPrivate::logSendMessage(const QString &msg) const { if (engine) @@ -930,34 +926,6 @@ void QmlV8DebuggerClientPrivate::logReceiveMessage(const QString &msg) const engine->logMessage(QLatin1String("V8DebuggerClient"), QmlEngine::LogReceive, msg); } -QtMessageLogItem *QmlV8DebuggerClientPrivate::constructLogItemTree( - QtMessageLogItem *parent, - const QmlV8ObjectData &objectData, - const QVariant &refsVal) -{ - if (!objectData.value.isValid()) - return 0; - - QString text; - if (objectData.name.isEmpty()) - text = objectData.value.toString(); - else - text = QString(_("%1: %2")).arg(QString::fromAscii(objectData.name)) - .arg(objectData.value.toString()); - - QtMessageLogItem *item = new QtMessageLogItem(parent, - QtMessageLogHandler::UndefinedType, text); - - foreach (const QVariant &property, objectData.properties) { - QtMessageLogItem *child = constructLogItemTree( - item, extractData(property, refsVal), refsVal); - if (child) - item->insertChild(child); - } - - return item; -} - /////////////////////////////////////////////////////////////////////// // // QmlV8DebuggerClient @@ -1125,9 +1093,8 @@ void QmlV8DebuggerClient::assignValueInDebugger(const WatchData * /*data*/, d->evaluate(expression, false, false, stackHandler->currentIndex()); d->updateLocalsAndWatchers.append(d->sequence); } else { - d->engine->showMessage(QString(_("Cannot evaluate" - "%1 in current stack frame")). - arg(expression), QtMessageLogOutput); + d->engine->showMessage(QString(_("Cannot evaluate %1 in current stack frame")).arg( + expression), ConsoleOutput); } } @@ -1144,9 +1111,8 @@ void QmlV8DebuggerClient::executeDebuggerCommand(const QString &command) d->debuggerCommands.append(d->sequence); } else { //Currently cannot evaluate if not in a javascript break - d->engine->showMessage(QString(_("Cannot evaluate %1" - "in current stack frame")). - arg(command), QtMessageLogOutput); + d->engine->showMessage(QString(_("Cannot evaluate %1 in current stack frame")).arg( + command), ConsoleOutput); } } @@ -1630,17 +1596,17 @@ StackFrame QmlV8DebuggerClient::extractStackFrame(const QVariant &bodyVal, const return stackFrame; } - QmlV8ObjectData objectData = d->extractData(body.value(_("func")), refsVal); + QmlV8ObjectData objectData = extractData(body.value(_("func")), refsVal); QString functionName = objectData.value.toString(); if (functionName.isEmpty()) functionName = tr("Anonymous Function"); stackFrame.function = functionName; - objectData = d->extractData(body.value(_("script")), refsVal); + objectData = extractData(body.value(_("script")), refsVal); stackFrame.file = d->engine->toFileInProject(objectData.value.toString()); stackFrame.usable = QFileInfo(stackFrame.file).isReadable(); - objectData = d->extractData(body.value(_("receiver")), refsVal); + objectData = extractData(body.value(_("receiver")), refsVal); stackFrame.to = objectData.value.toString(); stackFrame.line = body.value(_("line")).toInt() + 1; @@ -1700,8 +1666,7 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const data.exp = QByteArray("this"); data.name = QLatin1String(data.exp); data.iname = QByteArray("local.") + data.exp; - QmlV8ObjectData objectData = d->extractData( - currentFrame.value(_("receiver")), refsVal); + QmlV8ObjectData objectData = extractData(currentFrame.value(_("receiver")), refsVal); data.id = objectData.handle; data.type = objectData.type; data.value = objectData.value.toString(); @@ -1759,12 +1724,12 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r if (bodyMap.value(_("frameIndex")).toInt() != stackHandler->currentIndex()) return; - QmlV8ObjectData objectData = d->extractData(bodyMap.value(_("object")), refsVal); + QmlV8ObjectData objectData = extractData(bodyMap.value(_("object")), refsVal); QList<int> handlesToLookup; QList<WatchData> locals; foreach (const QVariant &property, objectData.properties) { - QmlV8ObjectData localData = d->extractData(property, refsVal); + QmlV8ObjectData localData = extractData(property, refsVal); WatchData data; data.exp = localData.name; //Check for v8 specific local data @@ -1794,9 +1759,37 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r d->engine->watchHandler()->insertData(locals); } -void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, const QVariant &bodyVal, +QmlJS::ConsoleItem *constructLogItemTree(QmlJS::ConsoleItem *parent, + const QmlV8ObjectData &objectData, const QVariant &refsVal) { + using namespace QmlJS; + bool sorted = debuggerCore()->boolSetting(SortStructMembers); + if (!objectData.value.isValid()) + return 0; + + QString text; + if (objectData.name.isEmpty()) + text = objectData.value.toString(); + else + text = QString(_("%1: %2")).arg(QString::fromAscii(objectData.name)) + .arg(objectData.value.toString()); + + ConsoleItem *item = new ConsoleItem(parent, ConsoleItem::UndefinedType, text); + + foreach (const QVariant &property, objectData.properties) { + ConsoleItem *child = constructLogItemTree(item, extractData(property, refsVal), + refsVal); + if (child) + item->insertChild(child, sorted); + } + + return item; +} + +void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, + const QVariant &bodyVal, const QVariant &refsVal) +{ // { "seq" : <number>, // "type" : "response", // "request_seq" : <number>, @@ -1819,17 +1812,20 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, con } else if (d->debuggerCommands.contains(sequence)) { d->updateLocalsAndWatchers.removeOne(sequence); - QmlV8ObjectData body = d->extractData(bodyVal, refsVal); - QtMessageLogItem *item = d->constructLogItemTree(d->engine->qtMessageLogHandler()->root(), - body, refsVal); - if (item) - d->engine->qtMessageLogHandler()->appendItem(item); + QmlV8ObjectData body = extractData(bodyVal, refsVal); + using namespace QmlJS; + ConsoleManagerInterface *consoleManager = ConsoleManagerInterface::instance(); + if (consoleManager) { + ConsoleItem *item = constructLogItemTree(consoleManager->rootItem(), body, refsVal); + if (item) + consoleManager->printToConsolePane(item); + } //Update the locals foreach (int index, d->currentFrameScopes) d->scope(index); } else { - QmlV8ObjectData body = d->extractData(bodyVal, refsVal); + QmlV8ObjectData body = extractData(bodyVal, refsVal); if (d->evaluatingExpression.contains(sequence)) { QString exp = d->evaluatingExpression.take(sequence); QList<WatchData> watchDataList; @@ -1928,7 +1924,7 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const QStringList handlesList = body.keys(); WatchHandler *watchHandler = d->engine->watchHandler(); foreach (const QString &handle, handlesList) { - QmlV8ObjectData bodyObjectData = d->extractData( + QmlV8ObjectData bodyObjectData = extractData( body.value(handle), refsVal); QByteArray prepend = d->localsAndWatchers.take(handle.toInt()); @@ -1965,7 +1961,7 @@ QList<WatchData> QmlV8DebuggerClient::createWatchDataList(const WatchData *paren if (properties.count()) { QTC_ASSERT(parent, return watchDataList); foreach (const QVariant &property, properties) { - QmlV8ObjectData propertyData = d->extractData(property, refsVal); + QmlV8ObjectData propertyData = extractData(property, refsVal); WatchData data; data.name = QString::fromUtf8(propertyData.name); @@ -2031,7 +2027,7 @@ void QmlV8DebuggerClient::highlightExceptionCode(int lineNumber, QString message = QString(_("%1: %2: %3")).arg(filePath).arg(lineNumber) .arg(errorMessage); - d->engine->showMessage(message, QtMessageLogOutput); + d->engine->showMessage(message, ConsoleOutput); } } } diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp index 85183f3fc6..4a595475fa 100644 --- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp +++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp @@ -488,7 +488,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) if (iname.startsWith("watch.")) { watchHandler->insertData(data); } else if (iname == "console") { - d->engine->showMessage(data.value, QtMessageLogOutput); + d->engine->showMessage(data.value, ConsoleOutput); } else if (iname.startsWith("local.")) { data.name = data.name.left(data.name.indexOf(QLatin1Char(' '))); watchHandler->insertData(data); diff --git a/src/plugins/debugger/qtmessageloghandler.cpp b/src/plugins/debugger/qtmessageloghandler.cpp deleted file mode 100644 index 2247200a61..0000000000 --- a/src/plugins/debugger/qtmessageloghandler.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qtmessageloghandler.h" -#include "debuggercore.h" -#include "debuggeractions.h" - -#include <utils/qtcassert.h> - -#include <QFontMetrics> - -namespace Debugger { -namespace Internal { - -/////////////////////////////////////////////////////////////////////// -// -// QtMessageLogItem -// -/////////////////////////////////////////////////////////////////////// - -QtMessageLogItem::QtMessageLogItem(QtMessageLogItem *parent, - QtMessageLogHandler::ItemType itemType, const QString &text) - : m_parentItem(parent), - itemType(itemType), - line(-1) - -{ - setText(text); -} - -QtMessageLogItem::~QtMessageLogItem() -{ - qDeleteAll(m_childItems); -} - -QtMessageLogItem *QtMessageLogItem::child(int number) -{ - return m_childItems.value(number); -} - -int QtMessageLogItem::childCount() const -{ - return m_childItems.size(); -} - -int QtMessageLogItem::childNumber() const -{ - if (m_parentItem) - return m_parentItem->m_childItems.indexOf( - const_cast<QtMessageLogItem *>(this)); - - return 0; -} - -bool QtMessageLogItem::insertChildren(int position, int count) -{ - if (position < 0 || position > m_childItems.size()) - return false; - - for (int row = 0; row < count; ++row) { - QtMessageLogItem *item = new - QtMessageLogItem(this , QtMessageLogHandler::UndefinedType, - QString()); - m_childItems.insert(position, item); - } - - return true; -} - -void QtMessageLogItem::insertChild(QtMessageLogItem *item) -{ - if (!debuggerCore()->boolSetting(SortStructMembers)) { - m_childItems.insert(m_childItems.count(), item); - return; - } - - int i = 0; - for (; i < m_childItems.count(); i++) { - if (item->m_text < m_childItems[i]->m_text) { - break; - } - } - m_childItems.insert(i, item); -} - -bool QtMessageLogItem::insertChild(int position, QtMessageLogItem *item) -{ - if (position < 0 || position > m_childItems.size()) - return false; - - m_childItems.insert(position, item); - - return true; -} - -QtMessageLogItem *QtMessageLogItem::parent() -{ - return m_parentItem; -} - -bool QtMessageLogItem::removeChildren(int position, int count) -{ - if (position < 0 || position + count > m_childItems.size()) - return false; - - for (int row = 0; row < count; ++row) - delete m_childItems.takeAt(position); - - return true; -} - -bool QtMessageLogItem::detachChild(int position) -{ - if (position < 0 || position > m_childItems.size()) - return false; - - m_childItems.removeAt(position); - - return true; -} - -void QtMessageLogItem::setText(const QString &text) -{ - m_text = text; - for (int i = 0; i < m_text.length(); ++i) { - if (m_text.at(i).isPunct()) - m_text.insert(++i, QChar(0x200b)); // ZERO WIDTH SPACE - } -} - -const QString &QtMessageLogItem::text() const -{ - return m_text; -} - -/////////////////////////////////////////////////////////////////////// -// -// QtMessageLogHandler -// -/////////////////////////////////////////////////////////////////////// - -QtMessageLogHandler::QtMessageLogHandler(QObject *parent) : - QAbstractItemModel(parent), - m_hasEditableRow(false), - m_rootItem(new QtMessageLogItem(0)), - m_maxSizeOfFileName(0) -{ -} - -QtMessageLogHandler::~QtMessageLogHandler() -{ - delete m_rootItem; -} - -void QtMessageLogHandler::clear() -{ - beginResetModel(); - reset(); - delete m_rootItem; - m_rootItem = new QtMessageLogItem(0); - endResetModel(); - - if (m_hasEditableRow) - appendEditableRow(); -} - -bool QtMessageLogHandler::appendItem(QtMessageLogItem *item, int position) -{ - if (position < 0) - position = m_rootItem->childCount() - 1; - - beginInsertRows(QModelIndex(), position, position); - bool success = m_rootItem->insertChild(position, item); - endInsertRows(); - - return success; -} - -bool QtMessageLogHandler::appendMessage(QtMessageLogHandler::ItemType itemType, - const QString &message, int position) -{ - return appendItem(new QtMessageLogItem(m_rootItem, itemType, message), position); -} - -void QtMessageLogHandler::setHasEditableRow(bool hasEditableRow) -{ - if (m_hasEditableRow && !hasEditableRow) - removeEditableRow(); - - if (!m_hasEditableRow && hasEditableRow) - appendEditableRow(); - - m_hasEditableRow = hasEditableRow; -} - -bool QtMessageLogHandler::hasEditableRow() const -{ - return m_hasEditableRow; -} - -void QtMessageLogHandler::appendEditableRow() -{ - int position = m_rootItem->childCount(); - if (appendItem(new QtMessageLogItem(m_rootItem, QtMessageLogHandler::InputType), position)) - emit selectEditableRow(index(position, 0), - QItemSelectionModel::ClearAndSelect); -} - -void QtMessageLogHandler::removeEditableRow() -{ - if (m_rootItem->child(m_rootItem->childCount() - 1)->itemType == - QtMessageLogHandler::InputType) - removeRow(m_rootItem->childCount() - 1); -} - -int QtMessageLogHandler::sizeOfFile(const QFont &font) -{ - int lastReadOnlyRow = m_rootItem->childCount(); - if (m_hasEditableRow) - lastReadOnlyRow -= 2; - else - lastReadOnlyRow -= 1; - if (lastReadOnlyRow < 0) - return 0; - QString filename = m_rootItem->child(lastReadOnlyRow)->file; - const int pos = filename.lastIndexOf(QLatin1Char('/')); - if (pos != -1) - filename = filename.mid(pos + 1); - - QFontMetrics fm(font); - m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename)); - - return m_maxSizeOfFileName; -} - -int QtMessageLogHandler::sizeOfLineNumber(const QFont &font) -{ - QFontMetrics fm(font); - return fm.width(QLatin1String("88888")); -} - -QVariant QtMessageLogHandler::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - QtMessageLogItem *item = getItem(index); - - if (role == Qt::DisplayRole ) - return item->text(); - else if (role == QtMessageLogHandler::TypeRole) - return int(item->itemType); - else if (role == QtMessageLogHandler::FileRole) - return item->file; - else if (role == QtMessageLogHandler::LineRole) - return item->line; - else - return QVariant(); -} - -QModelIndex QtMessageLogHandler::index(int row, int column, - const QModelIndex &parent) const -{ - if (parent.isValid() && parent.column() != 0) - return QModelIndex(); - - if (column > 0) - return QModelIndex(); - - QtMessageLogItem *parentItem = getItem(parent); - - QtMessageLogItem *childItem = parentItem->child(row); - if (childItem) - return createIndex(row, column, childItem); - else - return QModelIndex(); -} - -QModelIndex QtMessageLogHandler::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - QtMessageLogItem *childItem = getItem(index); - QtMessageLogItem *parentItem = childItem->parent(); - - if (parentItem == m_rootItem) - return QModelIndex(); - - //can parentItem be 0? - if (!parentItem) - return QModelIndex(); - return createIndex(parentItem->childNumber(), 0, parentItem); -} - -int QtMessageLogHandler::rowCount(const QModelIndex &parent) const -{ - QtMessageLogItem *parentItem = getItem(parent); - - return parentItem->childCount(); -} - -int QtMessageLogHandler::columnCount(const QModelIndex & /* parent */) const -{ - return 1; -} - -Qt::ItemFlags QtMessageLogHandler::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return 0; - - QtMessageLogItem *item = getItem(index); - if (m_hasEditableRow && item->parent() == m_rootItem - && index.row() == m_rootItem->childCount() - 1) - return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} - -bool QtMessageLogHandler::setData(const QModelIndex &index, const QVariant &value, - int role) -{ - QtMessageLogItem *item = getItem(index); - bool result = false; - if (role == Qt::DisplayRole) { - item->setText(value.toString()); - result = true; - } else if (role == QtMessageLogHandler::TypeRole) { - item->itemType = (QtMessageLogHandler::ItemType)value.toInt(); - result = true; - } else if (role == QtMessageLogHandler::FileRole) { - item->file = value.toString(); - result = true; - } else if (role == QtMessageLogHandler::LineRole) { - item->line = value.toInt(); - result = true; - } - - if (result) - emit dataChanged(index, index); - - return result; -} - -bool QtMessageLogHandler::insertRows(int position, int rows, const QModelIndex &parent) -{ - QtMessageLogItem *parentItem = getItem(parent); - bool success; - - beginInsertRows(parent, position, position + rows - 1); - success = parentItem->insertChildren(position, rows); - endInsertRows(); - - return success; -} - -bool QtMessageLogHandler::removeRows(int position, int rows, const QModelIndex &parent) -{ - QtMessageLogItem *parentItem = getItem(parent); - bool success = true; - - beginRemoveRows(parent, position, position + rows - 1); - success = parentItem->removeChildren(position, rows); - endRemoveRows(); - - return success; -} - -QtMessageLogItem *QtMessageLogHandler::getItem(const QModelIndex &index) const -{ - if (index.isValid()) { - QtMessageLogItem *item = static_cast<QtMessageLogItem*>(index.internalPointer()); - if (item) return item; - } - return m_rootItem; -} - -} //Internal -} //Debugger diff --git a/src/plugins/debugger/qtmessagelogwindow.cpp b/src/plugins/debugger/qtmessagelogwindow.cpp deleted file mode 100644 index a617cf080a..0000000000 --- a/src/plugins/debugger/qtmessagelogwindow.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qtmessagelogwindow.h" -#include "qtmessagelogview.h" -#include "qtmessageloghandler.h" -#include "qtmessagelogitemdelegate.h" -#include "debuggerstringutils.h" -#include "qtmessagelogproxymodel.h" - -#include <utils/statuslabel.h> -#include <utils/styledbar.h> -#include <utils/savedaction.h> - -#include <coreplugin/icore.h> -#include <coreplugin/coreconstants.h> -#include <coreplugin/findplaceholder.h> - -#include <aggregation/aggregate.h> -#include <find/treeviewfind.h> - -#include <QSettings> -#include <QHBoxLayout> -#include <QVBoxLayout> -#include <QToolButton> - -static const char CONSOLE[] = "Console"; -static const char SHOW_LOG[] = "showLog"; -static const char SHOW_WARNING[] = "showWarning"; -static const char SHOW_ERROR[] = "showError"; - -namespace Debugger { -namespace Internal { - -///////////////////////////////////////////////////////////////////// -// -// QtMessageLogWindow -// -///////////////////////////////////////////////////////////////////// - -QtMessageLogWindow::QtMessageLogWindow(QWidget *parent) - : QWidget(parent) -{ - setWindowTitle(tr(CONSOLE)); - setObjectName(_(CONSOLE)); - - const int statusBarHeight = 25; - - QVBoxLayout *vbox = new QVBoxLayout(this); - vbox->setMargin(0); - vbox->setSpacing(0); - - QWidget *statusbarContainer = new Utils::StyledBar(); - statusbarContainer->setStyleSheet(QLatin1String("background: #9B9B9B")); - statusbarContainer->setFixedHeight(statusBarHeight); - QHBoxLayout *hbox = new QHBoxLayout(statusbarContainer); - hbox->setMargin(0); - hbox->setSpacing(0); - - hbox->addSpacing(5); - - //Status Label - m_statusLabel = new Utils::StatusLabel; - hbox->addWidget(m_statusLabel); - hbox->addWidget(new Utils::StyledSeparator); - - const int buttonWidth = 25; - //Filters - QToolButton *button = new QToolButton(this); - button->setAutoRaise(true); - button->setFixedWidth(buttonWidth); - m_showLogAction = new Utils::SavedAction(this); - m_showLogAction->setDefaultValue(true); - m_showLogAction->setSettingsKey(_(CONSOLE), _(SHOW_LOG)); - m_showLogAction->setText(tr("Log")); - m_showLogAction->setToolTip(tr("Show debug, log, and info messages.")); - m_showLogAction->setCheckable(true); - m_showLogAction->setIcon(QIcon(_(":/debugger/images/log.png"))); - button->setDefaultAction(m_showLogAction); - hbox->addWidget(button); - - button = new QToolButton(this); - button->setAutoRaise(true); - button->setFixedWidth(buttonWidth); - m_showWarningAction = new Utils::SavedAction(this); - m_showWarningAction->setDefaultValue(true); - m_showWarningAction->setSettingsKey(_(CONSOLE), _(SHOW_WARNING)); - m_showWarningAction->setText(tr("Warning")); - m_showWarningAction->setToolTip(tr("Show warning messages.")); - m_showWarningAction->setCheckable(true); - m_showWarningAction->setIcon(QIcon(_(":/debugger/images/warning.png"))); - button->setDefaultAction(m_showWarningAction); - hbox->addWidget(button); - - button = new QToolButton(this); - button->setAutoRaise(true); - button->setFixedWidth(buttonWidth); - m_showErrorAction = new Utils::SavedAction(this); - m_showErrorAction->setDefaultValue(true); - m_showErrorAction->setSettingsKey(_(CONSOLE), _(SHOW_ERROR)); - m_showErrorAction->setText(tr("Error")); - m_showErrorAction->setToolTip(tr("Show error and fatal messages.")); - m_showErrorAction->setCheckable(true); - m_showErrorAction->setIcon(QIcon(_(":/debugger/images/error.png"))); - button->setDefaultAction(m_showErrorAction); - hbox->addWidget(button); - hbox->addWidget(new Utils::StyledSeparator); - - //Clear Button - button = new QToolButton; - button->setAutoRaise(true); - button->setFixedWidth(buttonWidth); - m_clearAction = new QAction(tr("Clear Console"), this); - m_clearAction->setIcon(QIcon(_(Core::Constants::ICON_CLEAN_PANE))); - button->setDefaultAction(m_clearAction); - hbox->addWidget(button); - hbox->addWidget(new Utils::StyledSeparator); - - m_treeView = new QtMessageLogView(this); - m_treeView->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::MinimumExpanding); - - m_proxyModel = new QtMessageLogProxyModel(this); - connect(m_showLogAction, SIGNAL(toggled(bool)), - m_proxyModel, SLOT(setShowLogs(bool))); - connect(m_showWarningAction, SIGNAL(toggled(bool)), - m_proxyModel, SLOT(setShowWarnings(bool))); - connect(m_showErrorAction, SIGNAL(toggled(bool)), - m_proxyModel, SLOT(setShowErrors(bool))); - - m_treeView->setModel(m_proxyModel); - connect(m_proxyModel, - SIGNAL(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags)), - m_treeView->selectionModel(), - SLOT(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags))); - connect(m_proxyModel, - SIGNAL(scrollToBottom()), - m_treeView, - SLOT(onScrollToBottom())); - - m_itemDelegate = new QtMessageLogItemDelegate(this); - connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), - m_itemDelegate, SLOT(currentChanged(QModelIndex,QModelIndex))); - m_treeView->setItemDelegate(m_itemDelegate); - - vbox->addWidget(statusbarContainer); - vbox->addWidget(m_treeView); - vbox->addWidget(new Core::FindToolBarPlaceHolder(this)); - - readSettings(); - connect(Core::ICore::instance(), - SIGNAL(saveSettingsRequested()), SLOT(writeSettings())); - - Aggregation::Aggregate *aggregate = new Aggregation::Aggregate(); - aggregate->add(m_treeView); - aggregate->add(new Find::TreeViewFind(m_treeView)); -} - -QtMessageLogWindow::~QtMessageLogWindow() -{ - writeSettings(); -} - -void QtMessageLogWindow::readSettings() -{ - QSettings *settings = Core::ICore::settings(); - m_showLogAction->readSettings(settings); - m_showWarningAction->readSettings(settings); - m_showErrorAction->readSettings(settings); -} - -void QtMessageLogWindow::showStatus(const QString &context, int timeout) -{ - m_statusLabel->showStatusMessage(context, timeout); -} - -void QtMessageLogWindow::writeSettings() const -{ - QSettings *settings = Core::ICore::settings(); - m_showLogAction->writeSettings(settings); - m_showWarningAction->writeSettings(settings); - m_showErrorAction->writeSettings(settings); -} - -void QtMessageLogWindow::setModel(QAbstractItemModel *model) -{ - QtMessageLogHandler *oldHandler = qobject_cast<QtMessageLogHandler *>( - m_proxyModel->sourceModel()); - if (oldHandler) { - disconnect(m_clearAction, SIGNAL(triggered()), oldHandler, SLOT(clear())); - disconnect(oldHandler, - SIGNAL(selectEditableRow( - QModelIndex,QItemSelectionModel::SelectionFlags)), - m_proxyModel, - SLOT(selectEditableRow( - QModelIndex,QItemSelectionModel::SelectionFlags))); - disconnect(oldHandler, - SIGNAL(rowsInserted(QModelIndex,int,int)), - m_proxyModel, - SLOT(onRowsInserted(QModelIndex,int,int))); - } - - QtMessageLogHandler *newHandler = qobject_cast<QtMessageLogHandler *>(model); - m_proxyModel->setSourceModel(newHandler); - m_itemDelegate->setItemModel(newHandler); - - if (newHandler) { - connect(m_clearAction, SIGNAL(triggered()), newHandler, SLOT(clear())); - connect(newHandler, - SIGNAL(selectEditableRow( - QModelIndex,QItemSelectionModel::SelectionFlags)), - m_proxyModel, - SLOT(selectEditableRow( - QModelIndex,QItemSelectionModel::SelectionFlags))); - - //Scroll to bottom when rows matching current filter settings are inserted - //Not connecting rowsRemoved as the only way to remove rows is to clear the - //model which will automatically reset the view. - connect(newHandler, - SIGNAL(rowsInserted(QModelIndex,int,int)), - m_proxyModel, - SLOT(onRowsInserted(QModelIndex,int,int))); - } -} - -} // namespace Internal -} // namespace Debugger diff --git a/src/plugins/debugger/registerhandler.cpp b/src/plugins/debugger/registerhandler.cpp index 315830c910..c2dbe42701 100644 --- a/src/plugins/debugger/registerhandler.cpp +++ b/src/plugins/debugger/registerhandler.cpp @@ -485,8 +485,9 @@ Qt::ItemFlags RegisterHandler::flags(const QModelIndex &idx) const void RegisterHandler::removeAll() { + beginResetModel(); m_registers.clear(); - reset(); + endResetModel(); } bool RegisterHandler::isEmpty() const @@ -508,12 +509,13 @@ static inline bool compareRegisterSet(const Registers &r1, const Registers &r2) void RegisterHandler::setRegisters(const Registers ®isters) { + beginResetModel(); m_registers = registers; const int size = m_registers.size(); for (int r = 0; r < size; r++) m_registers[r].changed = false; calculateWidth(); - reset(); + endResetModel(); } void RegisterHandler::setAndMarkRegisters(const Registers ®isters) @@ -549,9 +551,10 @@ void RegisterHandler::calculateWidth() void RegisterHandler::setNumberBase(int base) { if (m_base != base) { + beginResetModel(); m_base = base; calculateWidth(); - emit reset(); + endResetModel(); } } diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp index f13542ed95..5ea054604d 100644 --- a/src/plugins/debugger/script/scriptengine.cpp +++ b/src/plugins/debugger/script/scriptengine.cpp @@ -438,9 +438,9 @@ void ScriptEngine::activateFrame(int index) Q_UNUSED(index) } -void ScriptEngine::selectThread(int index) +void ScriptEngine::selectThread(ThreadId threadId) { - Q_UNUSED(index) + Q_UNUSED(threadId) } bool ScriptEngine::acceptsBreakpoint(BreakpointModelId id) const diff --git a/src/plugins/debugger/script/scriptengine.h b/src/plugins/debugger/script/scriptengine.h index 669ef21abb..72a912db14 100644 --- a/src/plugins/debugger/script/scriptengine.h +++ b/src/plugins/debugger/script/scriptengine.h @@ -85,7 +85,7 @@ private: void executeJumpToLine(const ContextData &data); void activateFrame(int index); - void selectThread(int index); + void selectThread(ThreadId threadId); bool acceptsBreakpoint(BreakpointModelId id) const; void attemptBreakpointSynchronization(); diff --git a/src/plugins/debugger/shared/hostutils.cpp b/src/plugins/debugger/shared/hostutils.cpp index e645a716e2..aa38d72611 100644 --- a/src/plugins/debugger/shared/hostutils.cpp +++ b/src/plugins/debugger/shared/hostutils.cpp @@ -82,11 +82,6 @@ bool winResumeThread(unsigned long dwThreadId, QString *errorMessage) return ok; } -unsigned long winGetCurrentProcessId() -{ - return GetCurrentProcessId(); -} - bool isWinProcessBeingDebugged(unsigned long pid) { HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); @@ -228,7 +223,16 @@ bool isFatalWinException(long code) return true; } -#endif // Q_OS_WIN +#else // Q_OS_WIN + +bool winResumeThread(unsigned long, QString *) { return false; } +bool isWinProcessBeingDebugged(unsigned long) { return false; } +void formatWindowsException(unsigned long , quint64, unsigned long, + quint64, quint64, QTextStream &) { } +bool isFatalWinException(long) { return false; } +bool isDebuggerWinException(unsigned long) { return false; } + +#endif // !Q_OS_WIN } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/shared/hostutils.h b/src/plugins/debugger/shared/hostutils.h index 1b052c92a4..511b4ea720 100644 --- a/src/plugins/debugger/shared/hostutils.h +++ b/src/plugins/debugger/shared/hostutils.h @@ -40,13 +40,9 @@ QT_END_NAMESPACE namespace Debugger { namespace Internal { -#ifdef Q_OS_WIN - // Resume a suspended thread by id. bool winResumeThread(unsigned long dwThreadId, QString *errorMessage); -unsigned long winGetCurrentProcessId(); - bool isWinProcessBeingDebugged(unsigned long pid); // Special exception codes. @@ -75,8 +71,6 @@ bool isFatalWinException(long code); // Check for EXCEPTION_BREAKPOINT, EXCEPTION_SINGLE_STEP bool isDebuggerWinException(unsigned long code); -#endif // defined(Q_OS_WIN) - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/snapshothandler.cpp b/src/plugins/debugger/snapshothandler.cpp index 4f0b439449..303d85779d 100644 --- a/src/plugins/debugger/snapshothandler.cpp +++ b/src/plugins/debugger/snapshothandler.cpp @@ -213,10 +213,11 @@ Qt::ItemFlags SnapshotHandler::flags(const QModelIndex &index) const void SnapshotHandler::activateSnapshot(int index) { + beginResetModel(); m_currentIndex = index; //qDebug() << "ACTIVATING INDEX: " << m_currentIndex << " OF " << size(); debuggerCore()->displayDebugger(at(index), true); - reset(); + endResetModel(); } void SnapshotHandler::createSnapshot(int index) @@ -239,28 +240,31 @@ void SnapshotHandler::removeSnapshot(int index) //QString fileName = engine->startParameters().coreFile; //if (!fileName.isEmpty()) // QFile::remove(fileName); + beginResetModel(); m_snapshots.removeAt(index); if (index == m_currentIndex) m_currentIndex = -1; else if (index < m_currentIndex) --m_currentIndex; //engine->quitDebugger(); - reset(); + endResetModel(); } void SnapshotHandler::removeAll() { + beginResetModel(); m_snapshots.clear(); m_currentIndex = -1; - reset(); + endResetModel(); } void SnapshotHandler::appendSnapshot(DebuggerEngine *engine) { + beginResetModel(); m_snapshots.append(engine); m_currentIndex = size() - 1; - reset(); + endResetModel(); } void SnapshotHandler::removeSnapshot(DebuggerEngine *engine) @@ -273,8 +277,9 @@ void SnapshotHandler::removeSnapshot(DebuggerEngine *engine) void SnapshotHandler::setCurrentIndex(int index) { + beginResetModel(); m_currentIndex = index; - reset(); + endResetModel(); } DebuggerEngine *SnapshotHandler::at(int i) const diff --git a/src/plugins/debugger/snapshothandler.h b/src/plugins/debugger/snapshothandler.h index aad1e1bfa1..9df2636c76 100644 --- a/src/plugins/debugger/snapshothandler.h +++ b/src/plugins/debugger/snapshothandler.h @@ -75,7 +75,7 @@ private: QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; - Q_SLOT void resetModel() { reset(); } + Q_SLOT void resetModel() { beginResetModel(); endResetModel(); } int m_currentIndex; QList< QPointer<DebuggerEngine> > m_snapshots; diff --git a/src/plugins/debugger/sourcefileshandler.cpp b/src/plugins/debugger/sourcefileshandler.cpp index b933a6ab9c..5a1ede17d8 100644 --- a/src/plugins/debugger/sourcefileshandler.cpp +++ b/src/plugins/debugger/sourcefileshandler.cpp @@ -48,9 +48,10 @@ void SourceFilesHandler::clearModel() { if (m_shortNames.isEmpty()) return; + beginResetModel(); m_shortNames.clear(); m_fullNames.clear(); - reset(); + endResetModel(); } QVariant SourceFilesHandler::headerData(int section, @@ -100,6 +101,7 @@ QVariant SourceFilesHandler::data(const QModelIndex &index, int role) const void SourceFilesHandler::setSourceFiles(const QMap<QString, QString> &sourceFiles) { + beginResetModel(); m_shortNames.clear(); m_fullNames.clear(); QMap<QString, QString>::ConstIterator it = sourceFiles.begin(); @@ -108,7 +110,7 @@ void SourceFilesHandler::setSourceFiles(const QMap<QString, QString> &sourceFile m_shortNames.append(it.key()); m_fullNames.append(it.value()); } - reset(); + endResetModel(); } void SourceFilesHandler::removeAll() diff --git a/src/plugins/debugger/sourcefileshandler.h b/src/plugins/debugger/sourcefileshandler.h index 75a81047c3..67f4a27292 100644 --- a/src/plugins/debugger/sourcefileshandler.h +++ b/src/plugins/debugger/sourcefileshandler.h @@ -55,7 +55,6 @@ public: Qt::ItemFlags flags(const QModelIndex &index) const; void clearModel(); - void update() { reset(); } void setSourceFiles(const QMap<QString, QString> &sourceFiles); void removeAll(); diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index cd024b9a01..2ee866fc98 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -183,13 +183,15 @@ void StackHandler::setCurrentIndex(int level) void StackHandler::removeAll() { + beginResetModel(); m_stackFrames.clear(); setCurrentIndex(-1); - reset(); + endResetModel(); } void StackHandler::setFrames(const StackFrames &frames, bool canExpand) { + beginResetModel(); m_resetLocationScheduled = false; m_contentsValid = true; m_canExpand = canExpand; @@ -198,7 +200,7 @@ void StackHandler::setFrames(const StackFrames &frames, bool canExpand) setCurrentIndex(0); else m_currentIndex = -1; - reset(); + endResetModel(); emit stackChanged(); } @@ -216,8 +218,9 @@ void StackHandler::scheduleResetLocation() void StackHandler::resetLocation() { if (m_resetLocationScheduled) { + beginResetModel(); m_resetLocationScheduled = false; - reset(); + endResetModel(); } } diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h index fc9969ce5c..d130da7275 100644 --- a/src/plugins/debugger/stackhandler.h +++ b/src/plugins/debugger/stackhandler.h @@ -93,7 +93,7 @@ private: QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; - Q_SLOT void resetModel() { reset(); } + Q_SLOT void resetModel() { beginResetModel(); endResetModel(); } StackFrames m_stackFrames; int m_currentIndex; diff --git a/src/plugins/debugger/threaddata.h b/src/plugins/debugger/threaddata.h index b0cf286dc9..516ad9ab73 100644 --- a/src/plugins/debugger/threaddata.h +++ b/src/plugins/debugger/threaddata.h @@ -30,24 +30,49 @@ #ifndef THREADDATA_H #define THREADDATA_H -#include <QVector> #include <QString> +#include <QVector> namespace Debugger { namespace Internal { //////////////////////////////////////////////////////////////////////// // +// ThreadId +// +//////////////////////////////////////////////////////////////////////// + +/*! A typesafe identifier. */ +class ThreadId +{ +public: + ThreadId() : m_id(-1) {} + explicit ThreadId(qint64 id) : m_id(id) {} + + bool isValid() const { return m_id != -1; } + qint64 raw() const { return m_id; } + bool operator==(const ThreadId other) const { return m_id == other.m_id; } + +private: + qint64 m_id; +}; + +//////////////////////////////////////////////////////////////////////// +// // ThreadData // //////////////////////////////////////////////////////////////////////// -/*! A structure containing information about a single thread */ +/*! A structure containing information about a single thread. */ struct ThreadData { - ThreadData(quint64 threadid = 0) - : id(threadid), frameLevel(-1), address (0), lineNumber(-1) - {} + ThreadData() + { + frameLevel = -1; + lineNumber = -1; + address = 0; + stopped = true; + } enum { IdColumn, @@ -58,9 +83,12 @@ struct ThreadData StateColumn, NameColumn, TargetIdColumn, + DetailsColumn, CoreColumn, ComboNameColumn, - ColumnCount = CoreColumn + ColumnCount = CoreColumn, + + IdRole = Qt::UserRole }; void notifyRunning() // Clear state information. @@ -71,21 +99,25 @@ struct ThreadData frameLevel = -1; state.clear(); lineNumber = -1; + stopped = false; } // Permanent data. - quint64 id; + ThreadId id; + QByteArray groupId; QString targetId; QString core; + bool stopped; // State information when stopped. qint32 frameLevel; + qint32 lineNumber; quint64 address; QString function; QString module; QString fileName; + QString details; QString state; - qint32 lineNumber; QString name; }; diff --git a/src/plugins/debugger/threadshandler.cpp b/src/plugins/debugger/threadshandler.cpp index d0761ae5bc..de41be2ba9 100644 --- a/src/plugins/debugger/threadshandler.cpp +++ b/src/plugins/debugger/threadshandler.cpp @@ -34,6 +34,8 @@ #include "debuggerconstants.h" #include "debuggercore.h" +#include <utils/qtcassert.h> + #include <QDebug> #include <QTextStream> #include <QSortFilterProxyModel> @@ -41,6 +43,32 @@ namespace Debugger { namespace Internal { +void mergeThreadData(ThreadData &data, const ThreadData &other) +{ + if (!other.core.isEmpty()) + data.core = other.core; + if (!other.fileName.isEmpty()) + data.fileName = other.fileName; + if (!other.targetId.isEmpty()) + data.targetId = other.targetId; + if (!other.name.isEmpty()) + data.name = other.name; + if (other.frameLevel != -1) + data.frameLevel = other.frameLevel; + if (!other.function.isEmpty()) + data.function = other.function; + if (!other.address) + data.address = other.address; + if (!other.module.isEmpty()) + data.module = other.module; + if (!other.details.isEmpty()) + data.details = other.details; + if (!other.state.isEmpty()) + data.state = other.state; + if (other.lineNumber != -1) + data.lineNumber = other.lineNumber; +} + //////////////////////////////////////////////////////////////////////// // // ThreadsHandler @@ -56,10 +84,13 @@ static QString threadToolTip(const ThreadData &thread) QTextStream str(&rc); str << "<html><head/><body><table>" << start << ThreadsHandler::tr("Thread id:") - << sep << thread.id << end; + << sep << thread.id.raw() << end; if (!thread.targetId.isEmpty()) str << start << ThreadsHandler::tr("Target id:") << sep << thread.targetId << end; + if (!thread.groupId.isEmpty()) + str << start << ThreadsHandler::tr("Group id:") + << sep << thread.groupId << end; if (!thread.name.isEmpty()) str << start << ThreadsHandler::tr("Name:") << sep << thread.name << end; @@ -98,14 +129,13 @@ static QString threadToolTip(const ThreadData &thread) */ ThreadsHandler::ThreadsHandler() - : m_currentIndex(0), + : m_currentIndex(-1), m_positionIcon(QLatin1String(":/debugger/images/location_16.png")), m_emptyIcon(QLatin1String(":/debugger/images/debugger_empty_14.png")) { m_resetLocationScheduled = false; - m_contentsValid = false; - m_proxyModel = new QSortFilterProxyModel(this); - m_proxyModel->setSourceModel(this); +// m_proxyModel = new QSortFilterProxyModel(this); +// m_proxyModel->setSourceModel(this); } int ThreadsHandler::rowCount(const QModelIndex &parent) const @@ -132,7 +162,7 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case ThreadData::IdColumn: - return thread.id; + return thread.id.raw(); case ThreadData::FunctionColumn: return thread.function; case ThreadData::FileColumn: @@ -154,8 +184,10 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const return thread.targetId; case ThreadData::NameColumn: return thread.name; + case ThreadData::DetailsColumn: + return thread.details; case ThreadData::ComboNameColumn: - return QString::fromLatin1("#%1 %2").arg(thread.id).arg(thread.name); + return QString::fromLatin1("#%1 %2").arg(thread.id.raw()).arg(thread.name); } case Qt::ToolTipRole: return threadToolTip(thread); @@ -164,6 +196,8 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const if (index.column() == 0) return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon; break; + case ThreadData::IdRole: + return thread.id.raw(); default: break; } @@ -192,6 +226,8 @@ QVariant ThreadsHandler::headerData return tr("State"); case ThreadData::TargetIdColumn: return tr("Target ID"); + case ThreadData::DetailsColumn: + return tr("Details"); case ThreadData::NameColumn: return tr("Name"); } @@ -200,60 +236,87 @@ QVariant ThreadsHandler::headerData Qt::ItemFlags ThreadsHandler::flags(const QModelIndex &index) const { - return m_contentsValid ? QAbstractTableModel::flags(index) : Qt::ItemFlags(0); + const int row = index.row(); + const bool stopped = row >= 0 && row < m_threads.size() + && m_threads.at(row).stopped; + return stopped ? QAbstractTableModel::flags(index) : Qt::ItemFlags(0); } -int ThreadsHandler::currentThreadId() const +ThreadId ThreadsHandler::currentThread() const { if (m_currentIndex < 0 || m_currentIndex >= m_threads.size()) - return -1; + return ThreadId(); return m_threads[m_currentIndex].id; } -void ThreadsHandler::setCurrentThread(int index) +ThreadId ThreadsHandler::threadAt(int index) const +{ + QTC_ASSERT(index >= 0 && index < m_threads.size(), return ThreadId()); + return m_threads[index].id; +} + +void ThreadsHandler::setCurrentThread(ThreadId id) { + const int index = indexOf(id); if (index == m_currentIndex) return; + if (index == -1) { + qWarning("ThreadsHandler::setCurrentThreadId: No such thread %d.", int(id.raw())); + return; + } + // Emit changed for previous frame. - QModelIndex i = ThreadsHandler::index(m_currentIndex, 0); - emit dataChanged(i, i); + if (m_currentIndex != -1) + dataChanged(m_currentIndex); m_currentIndex = index; // Emit changed for new frame. - i = ThreadsHandler::index(m_currentIndex, 0); - emit dataChanged(i, i); + dataChanged(m_currentIndex); updateThreadBox(); } -void ThreadsHandler::setCurrentThreadId(int id) -{ - const int index = indexOf(id); - if (index != -1) - setCurrentThread(index); - else - qWarning("ThreadsHandler::setCurrentThreadId: No such thread %d.", id); -} - -int ThreadsHandler::indexOf(quint64 threadId) const +int ThreadsHandler::indexOf(ThreadId threadId) const { - const int count = m_threads.size(); - for (int i = 0; i < count; ++i) + for (int i = m_threads.size(); --i >= 0; ) if (m_threads.at(i).id == threadId) return i; return -1; } +void ThreadsHandler::updateThread(const ThreadData &thread) +{ + const int i = indexOf(thread.id); + if (i == -1) { + beginInsertRows(QModelIndex(), m_threads.size(), m_threads.size()); + m_threads.append(thread); + endInsertRows(); + } else { + mergeThreadData(m_threads[i], thread); + dataChanged(i); + } +} + +void ThreadsHandler::removeThread(ThreadId threadId) +{ + const int i = indexOf(threadId); + if (i == -1) + return; + beginRemoveRows(QModelIndex(), i, i); + m_threads.remove(i); + endRemoveRows(); +} + void ThreadsHandler::setThreads(const Threads &threads) { + beginResetModel(); m_threads = threads; if (m_currentIndex >= m_threads.size()) m_currentIndex = -1; m_resetLocationScheduled = false; - m_contentsValid = true; - reset(); + endResetModel(); updateThreadBox(); } @@ -261,53 +324,123 @@ void ThreadsHandler::updateThreadBox() { QStringList list; foreach (const ThreadData &thread, m_threads) - list.append(QString::fromLatin1("#%1 %2").arg(thread.id).arg(thread.name)); + list.append(QString::fromLatin1("#%1 %2").arg(thread.id.raw()).arg(thread.name)); debuggerCore()->setThreads(list, m_currentIndex); } +void ThreadsHandler::dataChanged(int index) +{ + Q_UNUSED(index); + layoutChanged(); +} + Threads ThreadsHandler::threads() const { return m_threads; } +ThreadData ThreadsHandler::thread(ThreadId id) const +{ + const int i = indexOf(id); + return i == -1 ? ThreadData() : m_threads.at(i); +} + void ThreadsHandler::removeAll() { + beginResetModel(); m_threads.clear(); - m_currentIndex = 0; - reset(); + m_currentIndex = -1; + endResetModel(); } -void ThreadsHandler::notifyRunning() +void ThreadsHandler::notifyRunning(const QByteArray &data) { - // Threads stopped (that is, address != 0 showing)? - if (m_threads.empty()) - return; - if (m_threads.front().address == 0) - return; - const Threads::iterator end = m_threads.end(); - for (Threads::iterator it = m_threads.begin(); it != end; ++it) - it->notifyRunning(); - emit dataChanged(index(0, 1), - index(m_threads.size() - 1, ThreadData::ColumnCount - 1)); + if (data.isEmpty() || data == "all") { + notifyAllRunning(); + } else { + bool ok; + qlonglong id = data.toLongLong(&ok); + if (ok) + notifyRunning(ThreadId(id)); + else // FIXME + notifyAllRunning(); + } +} + +void ThreadsHandler::notifyAllRunning() +{ + for (int i = m_threads.size(); --i >= 0; ) + m_threads[i].notifyRunning(); + layoutChanged(); +} + +void ThreadsHandler::notifyRunning(ThreadId id) +{ + int i = indexOf(id); + if (i >= 0) { + m_threads[i].notifyRunning(); + dataChanged(i); + } +} + +void ThreadsHandler::notifyStopped(const QByteArray &data) +{ + if (data.isEmpty() || data == "all") { + notifyAllStopped(); + } else { + bool ok; + qlonglong id = data.toLongLong(&ok); + if (ok) + notifyRunning(ThreadId(id)); + else // FIXME + notifyAllStopped(); + } +} + +void ThreadsHandler::notifyAllStopped() +{ + for (int i = m_threads.size(); --i >= 0; ) + m_threads[i].stopped = true; + layoutChanged(); +} + +void ThreadsHandler::notifyStopped(ThreadId id) +{ + int i = indexOf(id); + if (i >= 0) { + m_threads[i].stopped = true; + dataChanged(i); + } } -Threads ThreadsHandler::parseGdbmiThreads(const GdbMi &data, int *currentThread) +void ThreadsHandler::updateThreads(const GdbMi &data) { // ^done,threads=[{id="1",target-id="Thread 0xb7fdc710 (LWP 4264)", // frame={level="0",addr="0x080530bf",func="testQString",args=[], // file="/.../app.cpp",fullname="/../app.cpp",line="1175"}, // state="stopped",core="0"}],current-thread-id="1" + + // Emit changed for previous frame. + if (m_currentIndex != -1) { + dataChanged(m_currentIndex); + m_currentIndex = -1; + } + + ThreadId currentId; + const GdbMi current = data.findChild("current-thread-id"); + if (current.isValid()) + currentId = ThreadId(current.data().toLongLong()); + const QList<GdbMi> items = data.findChild("threads").children(); const int n = items.size(); - Threads threads; - threads.reserve(n); for (int index = 0; index != n; ++index) { bool ok = false; const GdbMi item = items.at(index); const GdbMi frame = item.findChild("frame"); ThreadData thread; - thread.id = item.findChild("id").data().toInt(); + thread.id = ThreadId(item.findChild("id").data().toInt()); thread.targetId = QString::fromLatin1(item.findChild("target-id").data()); + thread.details = QString::fromLatin1(item.findChild("details").data()); thread.core = QString::fromLatin1(item.findChild("core").data()); thread.state = QString::fromLatin1(item.findChild("state").data()); thread.address = frame.findChild("addr").data().toULongLong(&ok, 0); @@ -315,32 +448,39 @@ Threads ThreadsHandler::parseGdbmiThreads(const GdbMi &data, int *currentThread) thread.fileName = QString::fromLatin1(frame.findChild("fullname").data()); thread.lineNumber = frame.findChild("line").data().toInt(); thread.module = QString::fromLocal8Bit(frame.findChild("from").data()); + thread.stopped = true; // Non-GDB (Cdb2) output name here. thread.name = QString::fromLatin1(frame.findChild("name").data()); - threads.append(thread); + if (thread.state == QLatin1String("running")) + thread.stopped = false; + if (thread.id == currentId) + m_currentIndex = index; + updateThread(thread); } - if (currentThread) - *currentThread = data.findChild("current-thread-id").data().toInt(); - return threads; + + if (m_currentIndex != -1) + dataChanged(m_currentIndex); + + updateThreadBox(); } void ThreadsHandler::scheduleResetLocation() { m_resetLocationScheduled = true; - m_contentsValid = false; } void ThreadsHandler::resetLocation() { if (m_resetLocationScheduled) { m_resetLocationScheduled = false; - reset(); + layoutChanged(); } } QAbstractItemModel *ThreadsHandler::model() { - return m_proxyModel; + return this; + //return m_proxyModel; } } // namespace Internal diff --git a/src/plugins/debugger/threadshandler.h b/src/plugins/debugger/threadshandler.h index 30d3fbdd46..3949c86c2c 100644 --- a/src/plugins/debugger/threadshandler.h +++ b/src/plugins/debugger/threadshandler.h @@ -57,26 +57,35 @@ class ThreadsHandler : public QAbstractTableModel public: ThreadsHandler(); - int currentThread() const { return m_currentIndex; } - void setCurrentThread(int index); - int currentThreadId() const; - void setCurrentThreadId(int id); - int indexOf(quint64 threadId) const; + int currentThreadIndex() const { return m_currentIndex; } + ThreadId currentThread() const; + ThreadId threadAt(int index) const; + void setCurrentThread(ThreadId id); + void updateThread(const ThreadData &thread); + void updateThreads(const GdbMi &data); + + void removeThread(ThreadId threadId); void setThreads(const Threads &threads); void removeAll(); Threads threads() const; + ThreadData thread(ThreadId id) const; QAbstractItemModel *model(); // Clear out all frame information - void notifyRunning(); + void notifyRunning(const QByteArray &data); + void notifyRunning(ThreadId id); + void notifyAllRunning(); - static Threads parseGdbmiThreads(const GdbMi &data, int *currentThread = 0); + void notifyStopped(const QByteArray &data); + void notifyStopped(ThreadId id); + void notifyAllStopped(); void resetLocation(); void scheduleResetLocation(); private: + int indexOf(ThreadId threadId) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; @@ -84,6 +93,7 @@ private: int role = Qt::DisplayRole) const; Qt::ItemFlags flags(const QModelIndex &index) const; void updateThreadBox(); + void dataChanged(int index); Threads m_threads; int m_currentIndex; @@ -91,9 +101,8 @@ private: const QIcon m_emptyIcon; bool m_resetLocationScheduled; - bool m_contentsValid; - QSortFilterProxyModel *m_proxyModel; + //QSortFilterProxyModel *m_proxyModel; }; } // namespace Internal diff --git a/src/plugins/debugger/threadswindow.cpp b/src/plugins/debugger/threadswindow.cpp index 5030665d59..2a764c4031 100644 --- a/src/plugins/debugger/threadswindow.cpp +++ b/src/plugins/debugger/threadswindow.cpp @@ -53,7 +53,8 @@ ThreadsTreeView::ThreadsTreeView() void ThreadsTreeView::rowActivated(const QModelIndex &index) { - debuggerCore()->currentEngine()->selectThread(index.row()); + ThreadId id = ThreadId(index.data(ThreadData::IdRole).toLongLong()); + debuggerCore()->currentEngine()->selectThread(id); } void ThreadsTreeView::setModel(QAbstractItemModel *model) @@ -64,6 +65,7 @@ void ThreadsTreeView::setModel(QAbstractItemModel *model) resizeColumnToContents(ThreadData::NameColumn); resizeColumnToContents(ThreadData::StateColumn); resizeColumnToContents(ThreadData::TargetIdColumn); + resizeColumnToContents(ThreadData::DetailsColumn); } void ThreadsTreeView::contextMenuEvent(QContextMenuEvent *ev) diff --git a/src/plugins/debugger/watchdelegatewidgets.cpp b/src/plugins/debugger/watchdelegatewidgets.cpp index e970c60b02..487a6e0dfa 100644 --- a/src/plugins/debugger/watchdelegatewidgets.cpp +++ b/src/plugins/debugger/watchdelegatewidgets.cpp @@ -90,10 +90,10 @@ IntegerValidator::IntegerValidator(QObject *parent) : bool IntegerValidator::isCharAcceptable(const QChar &c, int base) { if (c.isLetter()) - return base == 16 && c.toLower().toAscii() <= 'f'; + return base == 16 && c.toLower().toLatin1() <= 'f'; if (!c.isDigit()) return false; - const int digit = c.toAscii() - '0'; + const int digit = c.toLatin1() - '0'; if (base == 8 && digit > 7) return false; if (base == 2 && digit > 1) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 58fa111b31..dffb00d306 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -1618,7 +1618,8 @@ void WatchHandler::showEditValue(const WatchData &data) if (data.editformat == 0x0) { m_model->m_editHandlers.remove(data.iname); delete w; - } else if (data.editformat == 1 || data.editformat == 3) { + } else if (data.editformat == DisplayImageData + || data.editformat == DisplayImageFile) { // QImage QLabel *l = qobject_cast<QLabel *>(w); if (!l) { @@ -1633,8 +1634,8 @@ void WatchHandler::showEditValue(const WatchData &data) } int width, height, format; QByteArray ba; - uchar *bits; - if (data.editformat == 1) { + uchar *bits = 0; + if (data.editformat == DisplayImageData) { ba = QByteArray::fromHex(data.editvalue); const int *header = (int *)(ba.data()); swapEndian(ba.data(), ba.size()); @@ -1642,7 +1643,7 @@ void WatchHandler::showEditValue(const WatchData &data) width = header[0]; height = header[1]; format = header[2]; - } else { // data.editformat == 3 + } else if (data.editformat == DisplayImageFile) { QTextStream ts(data.editvalue); QString fileName; ts >> width >> height >> format >> fileName; @@ -1652,18 +1653,13 @@ void WatchHandler::showEditValue(const WatchData &data) bits = (uchar*)ba.data(); } QImage im(bits, width, height, QImage::Format(format)); - -#if 1 - // Qt bug. Enforce copy of image data. - QImage im2(im); - im.detach(); -#endif - l->setPixmap(QPixmap::fromImage(im)); l->resize(width, height); l->show(); - } else if (data.editformat == 2) { - // Display QString in a separate widget. + } else if (data.editformat == DisplayUtf16String + || data.editformat == DisplayLatin1String + || data.editformat == DisplayUtf16String) { + // String data. QTextEdit *t = qobject_cast<QTextEdit *>(w); if (!t) { delete w; @@ -1671,7 +1667,13 @@ void WatchHandler::showEditValue(const WatchData &data) m_model->m_editHandlers[key] = t; } QByteArray ba = QByteArray::fromHex(data.editvalue); - QString str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2); + QString str; + if (data.editformat == DisplayUtf16String) + str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2); + else if (data.editformat == DisplayLatin1String) + str = QString::fromLatin1(ba.constData(), ba.size()); + else if (data.editformat == DisplayUtf8String) + str = QString::fromUtf8(ba.constData(), ba.size()); t->setText(str); t->resize(400, 200); t->show(); diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index d810bc56a8..f8e14bd16a 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -281,7 +281,7 @@ bool isKeyWord(const QString &exp) { // FIXME: incomplete QTC_ASSERT(!exp.isEmpty(), return false); - switch (exp.at(0).toAscii()) { + switch (exp.at(0).toLatin1()) { case 'a': return exp == QLatin1String("auto"); case 'b': diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h index 7a132cd7f4..29d93fef07 100644 --- a/src/plugins/debugger/watchutils.h +++ b/src/plugins/debugger/watchutils.h @@ -83,6 +83,17 @@ enum DebuggerEncoding Hex2EncodedFloat8 = 26 }; +// Keep in sync with dumper.py +enum DebuggerDisplay { + StopDisplay = 0, + DisplayImageData = 1, + DisplayUtf16String = 2, + DisplayImageFile = 3, + DisplayProcess = 4, + DisplayLatin1String = 5, + DisplayUtf8String = 6 +}; + bool isEditorDebuggable(Core::IEditor *editor); QByteArray dotEscape(QByteArray str); QString currentTime(); diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index 1ba4882c9c..89c66839ac 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -43,6 +43,8 @@ #include "debuggertooltipmanager.h" #include "memoryagent.h" +#include <texteditor/syntaxhighlighter.h> + #include <utils/qtcassert.h> #include <utils/savedaction.h> @@ -301,6 +303,7 @@ static MemoryMarkupList MemoryMarkupList result; int colorNumber = 0; ColorNumberToolTips ranges(size, ColorNumberToolTip(colorNumber, rootToolTip)); + colorNumber++; const int childCount = memberVariableRecursion(model, modelIndex, rootName, address, address + size, &colorNumber, &ranges); @@ -331,30 +334,19 @@ static MemoryMarkupList } } - // Condense ranges of identical color into markup ranges. Assign member colors - // interchangeably. - const QColor baseColor = sizeIsEstimate ? defaultBackground : Qt::lightGray; + // Assign colors from a list, use base color for 0 (contrast to black text). + // Overwrite the first color (which is usually very bright) by the base color. + QList<QColor> colors = TextEditor::SyntaxHighlighter::generateColors(colorNumber + 2, + QColor(Qt::black)); + colors[0] = sizeIsEstimate ? defaultBackground : Qt::lightGray; const QColor registerColor = Qt::green; - QColor memberColor1 = QColor(Qt::yellow).lighter(); - QColor memberColor2 = QColor(Qt::cyan).lighter(); - int lastColorNumber = 0; - int childNumber = 0; for (unsigned i = 0; i < size; ++i) { const ColorNumberToolTip &range = ranges.at(i); if (result.isEmpty() || lastColorNumber != range.first) { lastColorNumber = range.first; - // Base colors: Parent/register - QColor color = range.first == registerColorNumber ? registerColor : baseColor; - if (range.first && range.first != registerColorNumber) { - if (childNumber++ & 1) { // Alternating member colors. - color = memberColor1; - memberColor1 = memberColor1.darker(120); - } else { - color = memberColor2; - memberColor2 = memberColor2.darker(120); - } - } // color switch + const QColor color = range.first == registerColorNumber ? + registerColor : colors.at(range.first); result.push_back(MemoryMarkup(address + i, 1, color, range.second)); } else { result.back().length++; @@ -972,6 +964,11 @@ bool WatchTreeView::event(QEvent *ev) return BaseTreeView::event(ev); } +void WatchTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &) +{ + emit currentIndexChanged(current); +} + void WatchTreeView::editItem(const QModelIndex &idx) { Q_UNUSED(idx) // FIXME diff --git a/src/plugins/debugger/watchwindow.h b/src/plugins/debugger/watchwindow.h index 72912cd280..16aaf5c9e2 100644 --- a/src/plugins/debugger/watchwindow.h +++ b/src/plugins/debugger/watchwindow.h @@ -58,6 +58,9 @@ public slots: void watchExpression(const QString &exp, const QString &name); void handleItemIsExpanded(const QModelIndex &idx); +signals: + void currentIndexChanged(const QModelIndex ¤tIndex); + private: Q_SLOT void resetHelper(); Q_SLOT void expandNode(const QModelIndex &idx); @@ -70,6 +73,7 @@ private: void dragMoveEvent(QDragMoveEvent *ev); void mouseDoubleClickEvent(QMouseEvent *ev); bool event(QEvent *ev); + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); void editItem(const QModelIndex &idx); void resetHelper(const QModelIndex &idx); diff --git a/src/plugins/designer/designer.pro b/src/plugins/designer/designer.pro index 463adfa1ee..e1175df8a2 100644 --- a/src/plugins/designer/designer.pro +++ b/src/plugins/designer/designer.pro @@ -10,7 +10,7 @@ include(designer_dependencies.pri) INCLUDEPATH += ../../tools/utils greaterThan(QT_MAJOR_VERSION, 4) { - QT += printsupport designer + QT += printsupport designer designercomponents } else { # -- figure out shared dir location !exists($$[QT_INSTALL_HEADERS]/QtDesigner/private/qdesigner_integration_p.h) { @@ -19,12 +19,11 @@ greaterThan(QT_MAJOR_VERSION, 4) { } INCLUDEPATH += $$QMAKE_INCDIR_QT/QtDesigner qtAddLibrary(QtDesigner) + qtAddLibrary(QtDesignerComponents) } QT += xml -qtAddLibrary(QtDesignerComponents) - HEADERS += formeditorplugin.h \ formeditorfactory.h \ formwindoweditor.h \ diff --git a/src/plugins/designer/designer.qbs b/src/plugins/designer/designer.qbs index 19769a0ad7..f30940b731 100644 --- a/src/plugins/designer/designer.qbs +++ b/src/plugins/designer/designer.qbs @@ -14,78 +14,73 @@ QtcPlugin { Depends { name: "cpp" } cpp.defines: base.concat(["CPP_ENABLED"]) - cpp.includePaths: [ + cpp.includePaths: base.concat([ "../../libs/3rdparty", "cpp", - "../../shared/designerintegrationv2", - ".", - "..", - "../../libs", - buildDirectory - ] + "../../shared/designerintegrationv2" + ]) files: [ - "../../shared/designerintegrationv2/widgethost.h", - "../../shared/designerintegrationv2/sizehandlerect.h", - "../../shared/designerintegrationv2/formresizer.h", - "../../shared/designerintegrationv2/widgethostconstants.h", - "cpp/formclasswizardpage.h", - "cpp/formclasswizarddialog.h", - "cpp/formclasswizard.h", - "cpp/formclasswizardparameters.h", - "cpp/cppsettingspage.h", - "formeditorplugin.h", - "formeditorfactory.h", - "formwindoweditor.h", - "formwindowfile.h", - "formwizard.h", - "qtcreatorintegration.h", - "designerconstants.h", - "settingspage.h", - "editorwidget.h", - "formeditorw.h", - "settingsmanager.h", - "formtemplatewizardpage.h", - "formwizarddialog.h", + "Designer.mimetypes.xml", + "README.txt", + "codemodelhelpers.cpp", "codemodelhelpers.h", + "designer.qrc", "designer_export.h", - "designerxmleditor.h", + "designerconstants.h", + "designercontext.cpp", "designercontext.h", - "formeditorstack.h", + "designerxmleditor.cpp", + "designerxmleditor.h", "editordata.h", - "resourcehandler.h", - "qtdesignerformclasscodegenerator.h", - "../../shared/designerintegrationv2/widgethost.cpp", - "../../shared/designerintegrationv2/sizehandlerect.cpp", - "../../shared/designerintegrationv2/formresizer.cpp", - "cpp/formclasswizardpage.cpp", - "cpp/formclasswizarddialog.cpp", - "cpp/formclasswizard.cpp", - "cpp/formclasswizardparameters.cpp", - "cpp/cppsettingspage.cpp", - "formeditorplugin.cpp", + "editorwidget.cpp", + "editorwidget.h", "formeditorfactory.cpp", + "formeditorfactory.h", + "formeditorplugin.cpp", + "formeditorplugin.h", + "formeditorstack.cpp", + "formeditorstack.h", + "formeditorw.cpp", + "formeditorw.h", + "formtemplatewizardpage.cpp", + "formtemplatewizardpage.h", "formwindoweditor.cpp", + "formwindoweditor.h", "formwindowfile.cpp", + "formwindowfile.h", "formwizard.cpp", - "qtcreatorintegration.cpp", - "settingspage.cpp", - "editorwidget.cpp", - "formeditorw.cpp", - "settingsmanager.cpp", - "formtemplatewizardpage.cpp", + "formwizard.h", "formwizarddialog.cpp", - "codemodelhelpers.cpp", - "designerxmleditor.cpp", - "designercontext.cpp", - "formeditorstack.cpp", - "resourcehandler.cpp", + "formwizarddialog.h", + "qtcreatorintegration.cpp", + "qtcreatorintegration.h", "qtdesignerformclasscodegenerator.cpp", - "cpp/formclasswizardpage.ui", + "qtdesignerformclasscodegenerator.h", + "resourcehandler.cpp", + "resourcehandler.h", + "settingsmanager.cpp", + "settingsmanager.h", + "settingspage.cpp", + "settingspage.h", + "../../shared/designerintegrationv2/formresizer.cpp", + "../../shared/designerintegrationv2/formresizer.h", + "../../shared/designerintegrationv2/sizehandlerect.cpp", + "../../shared/designerintegrationv2/sizehandlerect.h", + "../../shared/designerintegrationv2/widgethost.cpp", + "../../shared/designerintegrationv2/widgethost.h", + "../../shared/designerintegrationv2/widgethostconstants.h", + "cpp/cppsettingspage.cpp", + "cpp/cppsettingspage.h", "cpp/cppsettingspagewidget.ui", - "designer.qrc", - "Designer.mimetypes.xml", - "README.txt" + "cpp/formclasswizard.cpp", + "cpp/formclasswizard.h", + "cpp/formclasswizarddialog.cpp", + "cpp/formclasswizarddialog.h", + "cpp/formclasswizardpage.cpp", + "cpp/formclasswizardpage.h", + "cpp/formclasswizardpage.ui", + "cpp/formclasswizardparameters.cpp", + "cpp/formclasswizardparameters.h", ] } - diff --git a/src/plugins/designer/formeditorfactory.cpp b/src/plugins/designer/formeditorfactory.cpp index 08fb224af7..833849ae67 100644 --- a/src/plugins/designer/formeditorfactory.cpp +++ b/src/plugins/designer/formeditorfactory.cpp @@ -61,7 +61,7 @@ FormEditorFactory::FormEditorFactory() Core::Id FormEditorFactory::id() const { - return K_DESIGNER_XML_EDITOR_ID; + return Core::Id(K_DESIGNER_XML_EDITOR_ID); } QString FormEditorFactory::displayName() const @@ -75,7 +75,7 @@ Core::IDocument *FormEditorFactory::open(const QString &fileName) if (!iface) return 0; if (qobject_cast<FormWindowEditor *>(iface)) { - Core::InfoBarEntry info(QLatin1String(Constants::INFO_READ_ONLY), + Core::InfoBarEntry info(Core::Id(Constants::INFO_READ_ONLY), tr("This file can only be edited in <b>Design</b> mode.")); info.setCustomButtonInfo(tr("Switch mode"), this, SLOT(designerModeClicked())); iface->document()->infoBar()->addInfo(info); diff --git a/src/plugins/designer/formwindoweditor.cpp b/src/plugins/designer/formwindoweditor.cpp index dc6251234e..509d57feb2 100644 --- a/src/plugins/designer/formwindoweditor.cpp +++ b/src/plugins/designer/formwindoweditor.cpp @@ -178,7 +178,7 @@ bool FormWindowEditor::open(QString *errorString, const QString &fileName, const d->m_file.setFileName(absfileName); d->m_file.setShouldAutoSave(false); - if (Internal::ResourceHandler *rh = qFindChild<Designer::Internal::ResourceHandler*>(form)) + if (Internal::ResourceHandler *rh = form->findChild<Designer::Internal::ResourceHandler*>()) rh->updateResources(); emit changed(); @@ -208,7 +208,7 @@ Core::IDocument *FormWindowEditor::document() Core::Id FormWindowEditor::id() const { - return Designer::Constants::K_DESIGNER_XML_EDITOR_ID; + return Core::Id(Designer::Constants::K_DESIGNER_XML_EDITOR_ID); } QString FormWindowEditor::displayName() const @@ -278,7 +278,7 @@ TextEditor::PlainTextEditor *FormWindowEditor::textEditor() Core::Id FormWindowEditor::preferredModeType() const { - return Core::Constants::MODE_DESIGN_TYPE; + return Core::Id(Core::Constants::MODE_DESIGN_TYPE); } } // namespace Designer diff --git a/src/plugins/fakevim/fakevim.pro b/src/plugins/fakevim/fakevim.pro index 442e7a7206..44e3c48c20 100644 --- a/src/plugins/fakevim/fakevim.pro +++ b/src/plugins/fakevim/fakevim.pro @@ -16,3 +16,7 @@ HEADERS += fakevimactions.h \ fakevimhandler.h \ fakevimplugin.h FORMS += fakevimoptions.ui + +equals(TEST, 1) { + SOURCES += fakevim_test.cpp +} diff --git a/src/plugins/fakevim/fakevim.qbs b/src/plugins/fakevim/fakevim.qbs index 600bd96ff0..218897eb2e 100644 --- a/src/plugins/fakevim/fakevim.qbs +++ b/src/plugins/fakevim/fakevim.qbs @@ -1,6 +1,7 @@ import qbs.base 1.0 import "../QtcPlugin.qbs" as QtcPlugin +import "../../../qbs/defaults.js" as Defaults QtcPlugin { name: "FakeVim" @@ -8,23 +9,20 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "TextEditor" } Depends { name: "Find" } - Depends { name: "cpp" } Depends { name: "Qt.widgets" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ "fakevimactions.cpp", - "fakevimhandler.cpp", - "fakevimplugin.cpp", "fakevimactions.h", + "fakevimhandler.cpp", "fakevimhandler.h", + "fakevimoptions.ui", + "fakevimplugin.cpp", "fakevimplugin.h", - "fakevimoptions.ui" ] -} + Group { + condition: Defaults.testsEnabled(qbs) + files: ["fakevim_test.cpp"] + } +} diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp new file mode 100644 index 0000000000..5fcdd37918 --- /dev/null +++ b/src/plugins/fakevim/fakevim_test.cpp @@ -0,0 +1,2464 @@ +/************************************************************************** +** +** Copyright (C) 2012 Lukas Holecek <hluk@email.cz> +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +/*! + * Tests for FakeVim plugin. + * All test are based on Vim behaviour. + */ + +#include "fakevimplugin.h" +#include "fakevimhandler.h" + +#include <coreplugin/editormanager/editormanager.h> +#include <texteditor/basetexteditor.h> + +#include <QtTest> +#include <QTextEdit> +#include <QTextDocument> +#include <QTextBlock> + +//TESTED_COMPONENT=src/plugins/fakevim + +/*! + * Tests after this macro will be skipped and warning printed. + * Uncomment it to test a feature -- if tests succeeds it should be removed from the test. + */ +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# define NOT_IMPLEMENTED QSKIP("Not fully implemented!", SkipSingle); +#else +# define NOT_IMPLEMENTED QSKIP("Not fully implemented!"); +#endif + +// Text cursor representation in comparisons. +#define X "|" + +// More distinct line separator in code. +#define N "\n" + +// Document line start and end string in error text. +#define LINE_START "\t\t<" +#define LINE_END ">\n" + +// Format of message after comparison fails (used by KEYS, COMMAND). +static const QString helpFormat = + "\n\tBefore command [%1]:\n" \ + LINE_START "%2" LINE_END \ + "\n\tAfter the command:\n" \ + LINE_START "%3" LINE_END \ + "\n\tShould be:\n" \ + LINE_START "%4" LINE_END; + +// Compare document contents with a expectedText. +// Also check cursor position if the expectedText contains | chracter. +#define COMPARE(beforeText, beforePosition, afterText, afterPosition, expectedText, cmd) \ + do { \ + QString before(beforeText); \ + QString actual(afterText); \ + QString expected(expectedText); \ + data.oldPosition = beforePosition; \ + data.oldText = before; \ + if (expected.contains(X)) {\ + before = textWithCursor(before, beforePosition); \ + actual = textWithCursor(actual, afterPosition); \ + } \ + QString help = helpFormat \ + .arg(QString(cmd)) \ + .arg(before.replace('\n', LINE_END LINE_START)) \ + .arg(actual.replace('\n', LINE_END LINE_START)) \ + .arg(expected.replace('\n', LINE_END LINE_START)); \ + QVERIFY2(actual == expected, help.toLatin1().constData()); \ + } while (false) + +// Send keys and check if the expected result is same as document contents. +// Escape is always prepended to keys so that previous command is cancelled. +#define KEYS(keys, expected) \ + do { \ + QString beforeText(data.text()); \ + int beforePosition = data.position(); \ + data.doKeys("<ESC>"); \ + data.doKeys(keys); \ + COMPARE(beforeText, beforePosition, data.text(), data.position(), (expected), (keys)); \ + } while (false) + +// Run Ex command and check if the expected result is same as document contents. +#define COMMAND(cmd, expected) \ + do { \ + QString beforeText(data.text()); \ + int beforePosition = data.position(); \ + data.doCommand(cmd); \ + COMPARE(beforeText, beforePosition, data.text(), data.position(), (expected), (":" cmd)); \ + } while (false) + +// Test undo, redo and repeat of last single command. This doesn't test cursor position. +// Set afterEnd to true if cursor position after undo and redo differs at the end of line +// (e.g. undoing 'A' operation moves cursor at the end of line and redo moves it one char right). +#define INTEGRITY(afterEnd) \ + do { \ + data.doKeys("<ESC>"); \ + const int newPosition = data.position(); \ + const int oldPosition = data.oldPosition; \ + const QString redo = data.text(); \ + KEYS("u", data.oldText); \ + const QTextCursor tc = data.cursor(); \ + const int pos = tc.position(); \ + const int col = tc.positionInBlock() \ + + ((afterEnd && tc.positionInBlock() + 2 == tc.block().length()) ? 1 : 0); \ + const int line = tc.block().blockNumber(); \ + const QTextDocument *doc = data.editor()->document(); \ + KEYS("<c-r>", textWithCursor(redo, doc->findBlockByNumber(line), col)); \ + KEYS("u", textWithCursor(data.oldText, pos)); \ + data.setPosition(oldPosition); \ + KEYS(".", textWithCursor(redo, newPosition)); \ + } while (false) + +using namespace FakeVim::Internal; +using namespace TextEditor; + +static QString textWithCursor(const QString &text, int position) +{ + return (position == -1) ? text : (text.left(position) + X + text.mid(position)); +} + +static QString textWithCursor(const QString &text, const QTextBlock &block, int column) +{ + const int pos = block.position() + qMin(column, qMax(0, block.length() - 2)); + return text.left(pos) + X + text.mid(pos); +} + +const QString testLines = + /* 0 1 2 3 4 */ + /* 0123456789012345678901234567890123457890 */ + "\n" + "#include <QtCore>\n" + "#include <QtGui>\n" + "\n" + "int main(int argc, char *argv[])\n" + "{\n" + " QApplication app(argc, argv);\n" + "\n" + " return app.exec();\n" + "}\n"; + +const QStringList l = testLines.split('\n'); + +// Insert cursor char at pos, negative counts from back. +static QString cursor(int line, int column) +{ + const int col = column >= 0 ? column : l[line].size() + column; + QStringList res = l.mid(0, line) << textWithCursor(l[line], col); + res.append(l.mid(line + 1)); + return res.join("\n"); +} + +static QString lmid(int i, int n = -1) { return QStringList(l.mid(i, n)).join("\n"); } + +// Data for tests containing BaseTextEditorWidget and FakeVimHAndler. +struct FakeVimPlugin::TestData +{ + FakeVimHandler *handler; + QWidget *edit; + QString title; + + int oldPosition; + QString oldText; + + BaseTextEditorWidget *editor() const { return qobject_cast<BaseTextEditorWidget *>(edit); } + + QTextCursor cursor() const { return editor()->textCursor(); } + + int position() const + { + return cursor().position(); + } + + void setPosition(int position) + { + handler->setTextCursorPosition(position); + } + + QString text() const { return editor()->toPlainText(); } + + void doCommand(const QString &cmd) { handler->handleCommand(cmd); } + void doKeys(const QString &keys) { handler->handleInput(keys); } + + void setText(const QString &text) + { + doKeys("<ESC>"); + QString str = text; + int i = str.indexOf(X); + if (i != -1) + str.remove(i, 1); + editor()->document()->setPlainText(str); + setPosition(i); + } + + int lines() const + { + QTextDocument *doc = editor()->document(); + Q_ASSERT(doc != 0); + return doc->lineCount(); + } +}; + +void FakeVimPlugin::setup(TestData *data) +{ + setupTest(&data->title, &data->handler, &data->edit); + data->handler->handleInput("<ESC><ESC>gg"); +} + + +void FakeVimPlugin::cleanup() +{ + Core::EditorManager::instance()->closeAllEditors(false); +} + + +void FakeVimPlugin::test_vim_indentation() +{ + TestData data; + setup(&data); + + data.doCommand("set expandtab"); + data.doCommand("set tabstop=4"); + data.doCommand("set shiftwidth=4"); + QCOMPARE(data.handler->physicalIndentation(" \t\t\tx"), 6 + 3); + QCOMPARE(data.handler->logicalIndentation (" \t\t\tx"), 4 + 3 * 4); + QCOMPARE(data.handler->physicalIndentation(" \t\t\tx"), 5 + 3); + QCOMPARE(data.handler->logicalIndentation (" \t\t\tx"), 4 + 3 * 4); + + QCOMPARE(data.handler->tabExpand(3), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(4), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(5), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(6), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(7), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(8), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(9), QLatin1String(" ")); + + data.doCommand("set expandtab"); + data.doCommand("set tabstop=8"); + data.doCommand("set shiftwidth=4"); + QCOMPARE(data.handler->physicalIndentation(" \t\t\tx"), 6 + 3); + QCOMPARE(data.handler->logicalIndentation (" \t\t\tx"), 0 + 3 * 8); + QCOMPARE(data.handler->physicalIndentation(" \t\t\tx"), 5 + 3); + QCOMPARE(data.handler->logicalIndentation (" \t\t\tx"), 0 + 3 * 8); + + QCOMPARE(data.handler->tabExpand(3), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(4), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(5), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(6), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(7), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(8), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(9), QLatin1String(" ")); + + data.doCommand("set noexpandtab"); + data.doCommand("set tabstop=4"); + data.doCommand("set shiftwidth=4"); + QCOMPARE(data.handler->physicalIndentation(" \t\t\tx"), 6 + 3); + QCOMPARE(data.handler->logicalIndentation (" \t\t\tx"), 4 + 3 * 4); + QCOMPARE(data.handler->physicalIndentation(" \t\t\tx"), 5 + 3); + QCOMPARE(data.handler->logicalIndentation (" \t\t\tx"), 4 + 3 * 4); + + QCOMPARE(data.handler->tabExpand(3), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(4), QLatin1String("\t")); + QCOMPARE(data.handler->tabExpand(5), QLatin1String("\t ")); + QCOMPARE(data.handler->tabExpand(6), QLatin1String("\t ")); + QCOMPARE(data.handler->tabExpand(7), QLatin1String("\t ")); + QCOMPARE(data.handler->tabExpand(8), QLatin1String("\t\t")); + QCOMPARE(data.handler->tabExpand(9), QLatin1String("\t\t ")); + + data.doCommand("set noexpandtab"); + data.doCommand("set tabstop=8"); + data.doCommand("set shiftwidth=4"); + QCOMPARE(data.handler->physicalIndentation(" \t\t\tx"), 6 + 3); + QCOMPARE(data.handler->logicalIndentation (" \t\t\tx"), 0 + 3 * 8); + QCOMPARE(data.handler->physicalIndentation(" \t\t\tx"), 5 + 3); + QCOMPARE(data.handler->logicalIndentation (" \t\t\tx"), 0 + 3 * 8); + + QCOMPARE(data.handler->tabExpand(3), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(4), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(5), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(6), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(7), QLatin1String(" ")); + QCOMPARE(data.handler->tabExpand(8), QLatin1String("\t")); + QCOMPARE(data.handler->tabExpand(9), QLatin1String("\t ")); +} + +void FakeVimPlugin::test_vim_movement() +{ + TestData data; + setup(&data); + + // vertical movement + data.setText("123" N "456" N "789" N "abc"); + KEYS("", X "123" N "456" N "789" N "abc"); + KEYS("j", "123" N X "456" N "789" N "abc"); + KEYS("G", "123" N "456" N "789" N X "abc"); + KEYS("k", "123" N "456" N X "789" N "abc"); + KEYS("2k", X "123" N "456" N "789" N "abc"); + KEYS("k", X "123" N "456" N "789" N "abc"); + KEYS("jj", "123" N "456" N X "789" N "abc"); + KEYS("gg", X "123" N "456" N "789" N "abc"); + + // horizontal movement + data.setText(" " X "x" "x" "x" "x"); + KEYS("", " " X "x" "x" "x" "x"); + KEYS("h", X " " "x" "x" "x" "x"); + KEYS("l", " " X "x" "x" "x" "x"); + KEYS("3l", " " "x" "x" "x" X "x"); + KEYS("2h", " " "x" X "x" "x" "x"); + KEYS("$", " " "x" "x" "x" X "x"); + KEYS("^", " " X "x" "x" "x" "x"); + KEYS("0", X " " "x" "x" "x" "x"); + + // skip words + data.setText("123 " "456" "." "789 " "abc"); + KEYS("b", X "123 " "456" "." "789 " "abc"); + KEYS("w", "123 " X "456" "." "789 " "abc"); + KEYS("2w", "123 " "456" "." X "789 " "abc"); + KEYS("3w", "123 " "456" "." "789 " "ab" X "c"); + KEYS("3b", "123 " "456" X "." "789 " "abc"); + + data.setText("123 " "456.789 " "abc " "def"); + KEYS("B", X "123 " "456.789 " "abc " "def"); + KEYS("W", "123 " X "456.789 " "abc " "def"); + KEYS("2W", "123 " "456.789 " "abc " X "def"); + KEYS("B", "123 " "456.789 " X "abc " "def"); + KEYS("2B", X "123 " "456.789 " "abc " "def"); + KEYS("4W", "123 " "456.789 " "abc " "de" X "f"); + + data.setText("123" N "45." "6" N "" N " " N "789"); + KEYS("3w", "123" N "45." X "6" N "" N " " N "789"); + // From Vim help (motion.txt): An empty line is also considered to be a word. + KEYS("w", "123" N "45." "6" N X "" N " " N "789"); + KEYS("w", "123" N "45." "6" N "" N " " N X "789"); + + KEYS("b", "123" N "45." "6" N X "" N " " N "789"); + KEYS("4b", X "123" N "45." "6" N "" N " " N "789"); + + KEYS("3e", "123" N "45" X "." "6" N "" N " " N "789"); + KEYS("e", "123" N "45" "." X "6" N "" N " " N "789"); + // Command "e" does not stop on empty lines ("ge" does). + KEYS("e", "123" N "45" "." "6" N "" N " " N "78" X "9"); + KEYS("ge", "123" N "45" "." "6" N X "" N " " N "789"); + KEYS("2ge", "123" N "45" X "." "6" N "" N " " N "789"); + + // do not move behind end of line in normal mode + data.setText("abc def" N "ghi"); + KEYS("$h", "abc d" X "ef" N "ghi"); + data.setText("abc def" N "ghi"); + KEYS("4e", "abc def" N "gh" X "i"); + data.setText("abc def" N "ghi"); + KEYS("$i", "abc de" X "f" N "ghi"); + + // move behind end of line in insert mode + data.setText("abc def" N "ghi"); + KEYS("i<end>", "abc def" X N "ghi"); + data.setText("abc def" N "ghi"); + KEYS("A", "abc def" X N "ghi"); + data.setText("abc def" N "ghi"); + KEYS("$a", "abc def" X N "ghi"); +} + +void FakeVimPlugin::test_vim_insert() +{ + TestData data; + setup(&data); + + // basic insert text + data.setText("ab" X "c" N "def"); + KEYS("i 123", "ab 123" X "c" N "def"); + INTEGRITY(false); + + data.setText("ab" X "c" N "def"); + KEYS("a 123", "abc 123" X N "def"); + INTEGRITY(true); + + data.setText("ab" X "c" N "def"); + KEYS("I 123", " 123" X "abc" N "def"); + INTEGRITY(false); + + data.setText("abc" N "def"); + KEYS("A 123", "abc 123" X N "def"); + INTEGRITY(true); + + data.setText("abc" N "def"); + KEYS("o 123", "abc" N " 123" X N "def"); + INTEGRITY(false); + + data.setText("abc" N "def"); + KEYS("O 123", " 123" X N "abc" N "def"); + INTEGRITY(false); + + // insert text [count] times + data.setText("ab" X "c" N "def"); + KEYS("3i 123<esc>", "ab 123 123 12" X "3c" N "def"); + INTEGRITY(false); + + data.setText("ab" X "c" N "def"); + KEYS("3a 123<esc>", "abc 123 123 12" X "3" N "def"); + INTEGRITY(true); + + data.setText("ab" X "c" N "def"); + KEYS("3I 123<esc>", " 123 123 12" X "3abc" N "def"); + INTEGRITY(false); + + data.setText("abc" N "def"); + KEYS("3A 123<esc>", "abc 123 123 12" X "3" N "def"); + INTEGRITY(true); + + data.setText("abc" N "def"); + KEYS("3o 123<esc>", "abc" N " 123" N " 123" N " 12" X "3" N "def"); + INTEGRITY(false); + + data.setText("abc" N "def"); + KEYS("3O 123<esc>", " 123" N " 123" N " 12" X "3" N "abc" N "def"); + INTEGRITY(false); + + // <C-O> + data.setText("abc" N "d" X "ef"); + KEYS("i<c-o>xX", "abc" N "dX" X "f"); + KEYS("i<c-o><end>", "abc" N "dXf" X); + data.setText("ab" X "c" N "def"); + KEYS("i<c-o>rX", "ab" X "X" N "def"); + data.setText("abc" N "def"); + KEYS("A<c-o>x", "ab" X N "def"); + data.setText("abc" N "de" X "f"); + KEYS("i<c-o>0x", "abc" N "x" X "def"); + data.setText("abc" N "de" X "f"); + KEYS("i<c-o>ggx", "x" X "abc" N "def"); + + // <INSERT> to toggle between insert and replace mode + data.setText("abc" N "def"); + KEYS("<insert>XYZ<insert>xyz<esc>", "XYZxy" X "z" N "def"); + KEYS("<insert><insert>" "<c-o>0<c-o>j" "XY<insert>Z", "XYZxyz" N "XYZ" X "f"); +} + +void FakeVimPlugin::test_vim_fFtT() +{ + TestData data; + setup(&data); + + data.setText("123()456" N "a(b(c)d)e"); + KEYS("t(", "12" X "3()456" N "a(b(c)d)e"); + KEYS("lt(", "123" X "()456" N "a(b(c)d)e"); + KEYS("0j2t(", "123()456" N "a(" X "b(c)d)e"); + KEYS("l2T(", "123()456" N "a(b" X "(c)d)e"); + KEYS("l2T(", "123()456" N "a(" X "b(c)d)e"); + KEYS("T(", "123()456" N "a(" X "b(c)d)e"); + + KEYS("ggf(", "123" X "()456" N "a(b(c)d)e"); + KEYS("lf(", "123(" X ")456" N "a(b(c)d)e"); + KEYS("0j2f(", "123()456" N "a(b" X "(c)d)e"); + KEYS("2F(", "123()456" N "a(b" X "(c)d)e"); + KEYS("l2F(", "123()456" N "a" X "(b(c)d)e"); + KEYS("F(", "123()456" N "a" X "(b(c)d)e"); +} + +void FakeVimPlugin::test_vim_transform_numbers() +{ + TestData data; + setup(&data); + + data.setText("8"); + KEYS("<c-a>", X "9"); + INTEGRITY(false); + KEYS("<c-x>", X "8"); + INTEGRITY(false); + KEYS("<c-a>", X "9"); + KEYS("<c-a>", "1" X "0"); + KEYS("<c-a>", "1" X "1"); + KEYS("5<c-a>", "1" X "6"); + INTEGRITY(false); + KEYS("10<c-a>", "2" X "6"); + KEYS("h100<c-a>", "12" X "6"); + KEYS("100<c-x>", "2" X "6"); + INTEGRITY(false); + KEYS("10<c-x>", "1" X "6"); + KEYS("5<c-x>", "1" X "1"); + KEYS("5<c-x>", X "6"); + KEYS("6<c-x>", X "0"); + KEYS("<c-x>", "-" X "1"); + KEYS("h10<c-x>", "-1" X "1"); + KEYS("h100<c-x>", "-11" X "1"); + KEYS("h889<c-x>", "-100" X "0"); + + // increase nearest number + data.setText("x-x+x: 1 2 3 -4 5"); + KEYS("8<c-a>", "x-x+x: " X "9 2 3 -4 5"); + KEYS("l8<c-a>", "x-x+x: 9 1" X "0 3 -4 5"); + KEYS("l8<c-a>", "x-x+x: 9 10 1" X "1 -4 5"); + KEYS("l16<c-a>", "x-x+x: 9 10 11 1" X "2 5"); + KEYS("w18<c-x>", "x-x+x: 9 10 11 12 -1" X "3"); + KEYS("hh13<c-a>", "x-x+x: 9 10 11 12 " X "0"); + KEYS("B12<c-x>", "x-x+x: 9 10 11 " X "0 0"); + KEYS("B11<c-x>", "x-x+x: 9 10 " X "0 0 0"); + KEYS("B10<c-x>", "x-x+x: 9 " X "0 0 0 0"); + KEYS("B9<c-x>", "x-x+x: " X "0 0 0 0 0"); + KEYS("B9<c-x>", "x-x+x: -" X "9 0 0 0 0"); + + data.setText("-- 1 --"); + KEYS("<c-x>", "-- " X "0 --"); + KEYS("<c-x><c-x>", "-- -" X "2 --"); + KEYS("2<c-a><c-a>", "-- " X "1 --"); + KEYS("<c-a>2<c-a>", "-- " X "4 --"); + KEYS(".", "-- " X "6 --"); +} + +void FakeVimPlugin::test_vim_delete() +{ + TestData data; + setup(&data); + + data.setText("123" N "456"); + KEYS("x", "23" N "456"); + INTEGRITY(false); + KEYS("dd", "456"); + INTEGRITY(false); + KEYS("2x", "6"); + INTEGRITY(false); + KEYS("dd", ""); + INTEGRITY(false); + + data.setText("void main()"); + KEYS("dt(", "()"); + INTEGRITY(false); + + data.setText("void main()"); + KEYS("df(", ")"); + INTEGRITY(false); + + data.setText("void " X "main()"); + KEYS("D", "void "); + INTEGRITY(false); + KEYS("ggd$", ""); + + data.setText("abc def ghi"); + KEYS("2dw", X "ghi"); + INTEGRITY(false); + data.setText("abc def ghi"); + KEYS("d2w", X "ghi"); + INTEGRITY(false); + + data.setText("abc " N " def" N " ghi" N "jkl"); + KEYS("3dw", X "jkl"); + data.setText("abc " N " def" N " ghi" N "jkl"); + KEYS("d3w", X "jkl"); + + // delete empty line + data.setText("a" N X "" N " b"); + KEYS("dd", "a" N " " X "b"); + + // delete on an empty line + data.setText("a" N X "" N " b"); + KEYS("d$", "a" N X "" N " b"); + INTEGRITY(false); + + // delete in empty document + data.setText(""); + KEYS("dd", X); + + // delete to start of line + data.setText(" abc" N " de" X "f" N " ghi"); + KEYS("d0", " abc" N X "f" N " ghi"); + INTEGRITY(false); + data.setText(" abc" N " de" X "f" N " ghi"); + KEYS("d^", " abc" N " " X "f" N " ghi"); + INTEGRITY(false); + + // delete to mark + data.setText("abc " X "def ghi"); + KEYS("ma" "3l" "d`a", "abc " X " ghi"); + KEYS("u" "gg" "d`a", X "def ghi"); + + // delete lines + data.setText(" abc" N " de" X "f" N " ghi" N " jkl"); + KEYS("dj", " abc" N " " X "jkl"); + INTEGRITY(false); + data.setText(" abc" N " def" N " gh" X "i" N " jkl"); + KEYS("dk", " abc" N " " X "jkl"); + INTEGRITY(false); +} + +void FakeVimPlugin::test_vim_delete_inner_word() +{ + TestData data; + setup(&data); + + data.setText("abc def ghi"); + KEYS("wlldiw", "abc " X " ghi"); + + data.setText("abc def ghi jkl"); + KEYS("3diw", X " ghi jkl"); + INTEGRITY(false); + + data.setText("abc " X " def"); + KEYS("diw", "abc" X "def"); + INTEGRITY(false); + KEYS("diw", ""); + + data.setText("abc " N " def"); + KEYS("3diw", X "def"); + + data.setText("abc " N " def" N " ghi"); + KEYS("4diw", " " X "ghi"); + data.setText("ab" X "c " N " def" N " ghi"); + KEYS("4diw", " " X "ghi"); + data.setText("a b" X "c " N " def" N " ghi"); + KEYS("4diw", "a" X " " N " ghi"); + + data.setText("abc def" N "ghi"); + KEYS("2diw", X "def" N "ghi"); + data.setText("abc def" N "ghi"); + KEYS("3diw", X "" N "ghi"); + + data.setText("x" N X "" N "" N " "); + KEYS("diw", "x" N X "" N "" N " "); + data.setText("x" N X "" N "" N " "); + KEYS("2diw", "x" N " " X " "); + data.setText("x" N X "" N "" N "" N "" N " "); + KEYS("3diw", "x" N " " X " "); + data.setText("x" N X "" N "" N "" N "" N "" N " "); + KEYS("3diw", "x" N X "" N " "); + data.setText("x" N X "" N "" N "" N "" N "" N "" N " "); + KEYS("4diw", "x" N X "" N " "); + + // delete single-character-word + data.setText("a " X "b c"); + KEYS("diw", "a " X " c"); +} + +void FakeVimPlugin::test_vim_delete_a_word() +{ + TestData data; + setup(&data); + + data.setText("abc def ghi"); + KEYS("wlldaw", "abc " X "ghi"); + + data.setText("abc def ghi jkl"); + KEYS("wll2daw", "abc " X "jkl"); + + data.setText("abc" X " def ghi"); + KEYS("daw", "abc" X " ghi"); + INTEGRITY(false); + KEYS("daw", "ab" X "c"); + INTEGRITY(false); + KEYS("daw", ""); + + data.setText(X " ghi jkl"); + KEYS("daw", X " jkl"); + KEYS("ldaw", X " "); + + data.setText("abc def ghi jkl"); + KEYS("3daw", X "jkl"); + INTEGRITY(false); + + // remove trailing spaces + data.setText("abc " N " def" N " ghi" N "jkl"); + KEYS("3daw", X "jkl"); + + data.setText("abc " N " def" N " ghi" N "jkl"); + KEYS("3daw", X "jkl"); + + data.setText("abc def" N "ghi"); + KEYS("2daw", X "" N "ghi"); + + data.setText("x" N X "" N "" N " "); + KEYS("daw", "x" N " " X " "); + data.setText("x" N X "" N "" N "" N "" N " "); + KEYS("2daw", "x" N " " X " "); + data.setText("x" N X "" N "" N "" N "" N "" N " "); + KEYS("2daw", "x" N X "" N " "); + data.setText("x" N X "" N "" N "" N "" N "" N "" N " "); + KEYS("3daw", "x" N " " X " "); + + // delete single-character-word + data.setText("a," X "b,c"); + KEYS("daw", "a," X ",c"); +} + +void FakeVimPlugin::test_vim_change_a_word() +{ + TestData data; + setup(&data); + + data.setText("abc " X "def ghi"); + KEYS("caw#", "abc #" X "ghi"); + INTEGRITY(false); + data.setText("abc d" X "ef ghi"); + KEYS("caw#", "abc #" X "ghi"); + data.setText("abc de" X "f ghi"); + KEYS("caw#", "abc #" X "ghi"); + + data.setText("abc de" X "f ghi jkl"); + KEYS("2caw#", "abc #" X "jkl"); + INTEGRITY(false); + + data.setText("abc" X " def ghi jkl"); + KEYS("2caw#", "abc#" X " jkl"); + + data.setText("abc " X " def ghi jkl"); + KEYS("2caw#", "abc#" X " jkl"); + + data.setText(" abc " N " def" N " ghi" N " jkl"); + KEYS("3caw#", "#" X N " jkl"); + + // change single-character-word + data.setText("a " X "b c"); + KEYS("ciwX<esc>", "a " X "X c"); + KEYS("cawZ<esc>", "a " X "Zc"); +} + +void FakeVimPlugin::test_vim_change_replace() +{ + TestData data; + setup(&data); + + // preserve lines in replace mode + data.setText("abc" N "def"); + KEYS("llvjhrX", "ab" X "X" N "XXf"); + + // change empty line + data.setText("a" N X "" N " b"); + KEYS("ccABC", "a" N "ABC" X N " b"); + INTEGRITY(false); + + // change on empty line + data.setText("a" N X "" N " b"); + KEYS("c$ABC<esc>", "a" N "AB" X "C" N " b"); + INTEGRITY(false); + KEYS("u", "a" N X "" N " b"); + KEYS("rA", "a" N X "" N " b"); + + // change in empty document + data.setText(""); + KEYS("ccABC", "ABC" X); + KEYS("u", ""); + KEYS("SABC", "ABC" X); + KEYS("u", ""); + KEYS("sABC", "ABC" X); + KEYS("u", ""); + KEYS("rA", "" X); + + // indentation with change + data.doCommand("set expandtab"); + data.doCommand("set shiftwidth=2"); + data.setText("int main()" N + "{" N + " " X " return 0;" N + "}" N + ""); + + KEYS("cc" "int i = 0;", + "int main()" N + "{" N + " int i = 0;" X N + "}" N + ""); + INTEGRITY(false); + + KEYS("uS" "int i = 0;" N "int j = 1;", + "int main()" N + "{" N + " int i = 0;" N + " int j = 1;" X N + "}" N + ""); + + // change to start of line + data.setText(" abc" N " de" X "f" N " ghi"); + KEYS("c0123<ESC>", " abc" N "12" X "3f" N " ghi"); + INTEGRITY(false); + data.setText(" abc" N " de" X "f" N " ghi"); + KEYS("c^123<ESC>", " abc" N " 12" X "3f" N " ghi"); + INTEGRITY(false); + + // change to mark + data.setText("abc " X "def ghi"); + KEYS("ma" "3l" "c`a123<ESC>", "abc 12" X "3 ghi"); + KEYS("u" "gg" "c`a123<ESC>", "12" X "3def ghi"); + + // change lines + data.setText(" abc" N " de" X "f" N " ghi" N " jkl"); + KEYS("cj123<ESC>", " abc" N " 12" X "3" N " jkl"); + INTEGRITY(false); + data.setText(" abc" N " def" N " gh" X "i" N " jkl"); + KEYS("ck123<ESC>", " abc" N " 12" X "3" N " jkl"); + INTEGRITY(false); +} + +void FakeVimPlugin::test_vim_block_selection() +{ + TestData data; + setup(&data); + + data.setText("int main(int /* (unused) */, char *argv[]);"); + KEYS("f(", "int main" X "(int /* (unused) */, char *argv[]);"); + KEYS("da(", "int main" X ";"); + INTEGRITY(false); + + data.setText("int main(int /* (unused) */, char *argv[]);"); + KEYS("f(", "int main" X "(int /* (unused) */, char *argv[]);"); + KEYS("di(", "int main(" X ");"); + INTEGRITY(false); + + data.setText("int main(int /* (unused) */, char *argv[]);"); + KEYS("2f)", "int main(int /* (unused) */, char *argv[]" X ");"); + KEYS("da(", "int main" X ";"); + + data.setText("int main(int /* (unused) */, char *argv[]);"); + KEYS("2f)", "int main(int /* (unused) */, char *argv[]" X ");"); + KEYS("di(", "int main(" X ");"); + + data.setText("{ { { } } }"); + KEYS("2f{l", "{ { {" X " } } }"); + KEYS("da{", "{ { " X " } }"); + KEYS("da{", "{ " X " }"); + INTEGRITY(false); + + data.setText("{ { { } } }"); + KEYS("2f{l", "{ { {" X " } } }"); + KEYS("2da{", "{ " X " }"); + INTEGRITY(false); + + data.setText("{" N " { " N " } " N "}"); + KEYS("di{", "{" N "}"); + + data.setText("(" X "())"); + KEYS("di(", "((" X "))"); + data.setText("\"\""); + KEYS("di\"", "\"" X "\""); + + // visual selection + data.setText("(abc()" X "(def))"); + KEYS("vi(d", "(abc()(" X "))"); + KEYS("u", "(abc()(" X "def))"); + KEYS("<c-r>", "(abc()(" X "))"); + KEYS("va(d", "(abc()" X ")"); + KEYS("u", "(abc()" X "())"); + KEYS("<c-r>", "(abc()" X ")"); + + // repeat change inner + data.setText("(abc)" N "def" N "(ghi)"); + KEYS("ci(xyz<esc>", "(xy" X "z)" N "def" N "(ghi)"); + KEYS("j.", "(xyz)" N "de" X "f" N "(ghi)"); + KEYS("j.", "(xyz)" N "def" N "(xy" X "z)"); +} + +void FakeVimPlugin::test_vim_repeat() +{ + TestData data; + setup(&data); + + // delete line + data.setText("abc" N "def" N "ghi"); + KEYS("dd", X "def" N "ghi"); + KEYS(".", X "ghi"); + INTEGRITY(false); + + // delete to next word + data.setText("abc def ghi jkl"); + KEYS("dw", X "def ghi jkl"); + KEYS("w.", "def " X "jkl"); + KEYS("gg.", X "jkl"); + + // change in word + data.setText("WORD text"); + KEYS("ciwWORD<esc>", "WOR" X "D text"); + KEYS("w.", "WORD WOR" X "D"); + + /* QTCREATORBUG-7248 */ + data.setText("test tex" X "t"); + KEYS("vbcWORD<esc>", "test " "WOR" X "D"); + KEYS("bb.", "WOR" X "D WORD"); + + // delete selected range + data.setText("abc def ghi jkl"); + KEYS("viwd", X " def ghi jkl"); + KEYS(".", X "f ghi jkl"); + KEYS(".", X "hi jkl"); + + // delete two lines + data.setText("abc" N "def" N "ghi" N "jkl" N "mno"); + KEYS("Vjx", X "ghi" N "jkl" N "mno"); + KEYS(".", X "mno"); + + // delete three lines + data.setText("abc" N "def" N "ghi" N "jkl" N "mno" N "pqr" N "stu"); + KEYS("d2j", X "jkl" N "mno" N "pqr" N "stu"); + KEYS(".", X "stu"); + + // replace block selection + data.setText("abcd" N "d" X "efg" N "ghij" N "jklm"); + KEYS("<c-v>jlrX", "abcd" N "d" X "XXg" N "gXXj" N "jklm"); + KEYS("gg.", "XXcd" N "XXXg" N "gXXj" N "jklm"); +} + +void FakeVimPlugin::test_vim_search() +{ + TestData data; + setup(&data); + + data.setText("abc" N "def" N "ghi"); + KEYS("/ghi<CR>", "abc" N "def" N X "ghi"); + KEYS("gg/\\w\\{3}<CR>", "abc" N X "def" N "ghi"); + KEYS("n", "abc" N "def" N X "ghi"); + KEYS("N", "abc" N X "def" N "ghi"); + KEYS("N", X "abc" N "def" N "ghi"); + + // return to search-start position on escape or not found + KEYS("/def<ESC>", X "abc" N "def" N "ghi"); + KEYS("/x", X "abc" N "def" N "ghi"); + KEYS("/x<CR>", X "abc" N "def" N "ghi"); + KEYS("/x<ESC>", X "abc" N "def" N "ghi"); + KEYS("/ghX", X "abc" N "def" N "ghi"); + + KEYS("?def<ESC>", X "abc" N "def" N "ghi"); + KEYS("?x", X "abc" N "def" N "ghi"); + KEYS("?x<CR>", X "abc" N "def" N "ghi"); + KEYS("?x<ESC>", X "abc" N "def" N "ghi"); + + // search [count] times + data.setText("abc" N "def" N "ghi"); + KEYS("/\\w\\{3}<CR>", "abc" N X "def" N "ghi"); + KEYS("2n", X "abc" N "def" N "ghi"); + KEYS("2N", "abc" N X "def" N "ghi"); + KEYS("2/\\w\\{3}<CR>", X "abc" N "def" N "ghi"); + + // set wrapscan (search wraps at end of file) + data.doCommand("set ws"); + data.setText("abc" N "def" N "abc" N "ghi abc jkl"); + KEYS("*", "abc" N "def" N X "abc" N "ghi abc jkl"); + KEYS("*", "abc" N "def" N "abc" N "ghi " X "abc jkl"); + KEYS("2*", "abc" N "def" N X "abc" N "ghi abc jkl"); + KEYS("#", X "abc" N "def" N "abc" N "ghi abc jkl"); + KEYS("#", "abc" N "def" N "abc" N "ghi " X "abc jkl"); + KEYS("#", "abc" N "def" N X "abc" N "ghi abc jkl"); + KEYS("2#", "abc" N "def" N "abc" N "ghi " X "abc jkl"); + + data.doCommand("set nows"); + data.setText("abc" N "def" N "abc" N "ghi abc jkl"); + KEYS("*", "abc" N "def" N X "abc" N "ghi abc jkl"); + KEYS("*", "abc" N "def" N "abc" N "ghi " X "abc jkl"); + KEYS("*", "abc" N "def" N "abc" N "ghi " X "abc jkl"); + KEYS("#", "abc" N "def" N X "abc" N "ghi abc jkl"); + KEYS("#", X "abc" N "def" N "abc" N "ghi abc jkl"); + KEYS("#", X "abc" N "def" N "abc" N "ghi abc jkl"); + + data.setText("abc" N "def" N "ab" X "c" N "ghi abc jkl"); + KEYS("#", X "abc" N "def" N "abc" N "ghi abc jkl"); + + // search with g* and g# + data.doCommand("set nows"); + data.setText("bc" N "abc" N "abcd" N "bc" N "b"); + KEYS("g*", "bc" N "a" X "bc" N "abcd" N "bc" N "b"); + KEYS("n", "bc" N "abc" N "a" X "bcd" N "bc" N "b"); + KEYS("n", "bc" N "abc" N "abcd" N X "bc" N "b"); + KEYS("n", "bc" N "abc" N "abcd" N X "bc" N "b"); + KEYS("g#", "bc" N "abc" N "a" X "bcd" N "bc" N "b"); + KEYS("n", "bc" N "a" X "bc" N "abcd" N "bc" N "b"); + KEYS("N", "bc" N "abc" N "a" X "bcd" N "bc" N "b"); + KEYS("3n", "bc" N "abc" N "a" X "bcd" N "bc" N "b"); + KEYS("2n", X "bc" N "abc" N "abcd" N "bc" N "b"); + + /* QTCREATORBUG-7251 */ + data.setText("abc abc abc abc"); + KEYS("$?abc<CR>", "abc abc abc " X "abc"); + KEYS("2?abc<CR>", "abc " X "abc abc abc"); + KEYS("n", X "abc abc abc abc"); + KEYS("N", "abc " X "abc abc abc"); + + // search is greedy + data.doCommand("set ws"); + data.setText("abc" N "def" N "abc" N "ghi abc jkl"); + KEYS("/[a-z]*<CR>", "abc" N X "def" N "abc" N "ghi abc jkl"); + KEYS("2n", "abc" N "def" N "abc" N X "ghi abc jkl"); + KEYS("3n", "abc" N "def" N "abc" N "ghi abc" X " jkl"); + KEYS("3N", "abc" N "def" N "abc" N X "ghi abc jkl"); + KEYS("2N", "abc" N X "def" N "abc" N "ghi abc jkl"); + + data.setText("a.b.c" N "" N "d.e.f"); + KEYS("/[a-z]*<CR>", "a" X ".b.c" N "" N "d.e.f"); + KEYS("n", "a." X "b.c" N "" N "d.e.f"); + KEYS("2n", "a.b." X "c" N "" N "d.e.f"); + KEYS("n", "a.b.c" N X "" N "d.e.f"); + KEYS("n", "a.b.c" N "" N X "d.e.f"); + KEYS("2N", "a.b." X "c" N "" N "d.e.f"); + KEYS("2n", "a.b.c" N "" N X "d.e.f"); + + // find same stuff forward and backward, + // i.e. '<ab>c' forward but not 'a<bc>' backward + data.setText("abc" N "def" N "ghi"); + KEYS("/\\w\\{2}<CR>", "abc" N X "def" N "ghi"); + KEYS("n", "abc" N "def" N X "ghi"); + KEYS("N", "abc" N X "def" N "ghi"); + KEYS("N", X "abc" N "def" N "ghi"); + KEYS("2n2N", X "abc" N "def" N "ghi"); +} + +void FakeVimPlugin::test_vim_indent() +{ + TestData data; + setup(&data); + + data.doCommand("set expandtab"); + data.doCommand("set shiftwidth=4"); + + data.setText( + "abc" N + "def" N + "ghi" N + "jkl" N + "mno"); + KEYS("j3>>", + "abc" N + " " X "def" N + " ghi" N + " jkl" N + "mno"); + KEYS("j2>>", + "abc" N + " def" N + " " X "ghi" N + " jkl" N + "mno"); + + KEYS("2<<", + "abc" N + " def" N + " " X "ghi" N + " jkl" N + "mno"); + INTEGRITY(false); + KEYS("k3<<", + "abc" N + X "def" N + "ghi" N + "jkl" N + "mno"); + + data.setText( + "abc" N + "def" N + "ghi" N + "jkl" N + "mno"); + KEYS("jj>j", + "abc" N + "def" N + " " X "ghi" N + " jkl" N + "mno"); + + data.setText("abc"); + KEYS(">>", " " X "abc"); + INTEGRITY(false); + + data.setText("abc"); + data.doCommand("set shiftwidth=2"); + KEYS(">>", " " X "abc"); + + data.setText("abc"); + data.doCommand("set noexpandtab"); + data.doCommand("set tabstop=2"); + data.doCommand("set shiftwidth=7"); + // shiftwidth = TABS * tabstop + SPACES + // 7 = 3 * 2 + 1 + KEYS(">>", "\t\t\t abc"); + + data.doCommand("set tabstop=3"); + data.doCommand("set shiftwidth=7"); + data.setText("abc"); + KEYS(">>", "\t\t abc"); + INTEGRITY(false); +} + +void FakeVimPlugin::test_vim_marks() +{ + TestData data; + setup(&data); + + data.setText(" abc" N " def" N " ghi"); + data.doKeys("ma"); + data.doKeys("ma"); + data.doKeys("jmb"); + data.doKeys("j^mc"); + KEYS("'a", " " X "abc" N " " "def" N " " "ghi"); + KEYS("`a", X " " "abc" N " " "def" N " " "ghi"); + KEYS("`b", " " "abc" N X " " "def" N " " "ghi"); + KEYS("'b", " " "abc" N " " X "def" N " " "ghi"); + KEYS("`c", " " "abc" N " " "def" N " " X "ghi"); + KEYS("'c", " " "abc" N " " "def" N " " X "ghi"); + + KEYS("`b", " " "abc" N X " " "def" N " " "ghi"); + KEYS("'c", " " "abc" N " " "def" N " " X "ghi"); + + KEYS("`'", " " "abc" N X " " "def" N " " "ghi"); + KEYS("`a", X " " "abc" N " " "def" N " " "ghi"); + KEYS("''", " " "abc" N " " X "def" N " " "ghi"); + KEYS("`'", X " " "abc" N " " "def" N " " "ghi"); + KEYS("`'", " " "abc" N " " X "def" N " " "ghi"); +} + +void FakeVimPlugin::test_vim_jumps() +{ + TestData data; + setup(&data); + + // last position + data.setText(" abc" N " def" N " ghi"); + KEYS("G", " abc" N " def" N " " X "ghi"); + KEYS("`'", X " abc" N " def" N " ghi"); + KEYS("`'", " abc" N " def" N " " X "ghi"); + KEYS("''", " " X "abc" N " def" N " ghi"); + KEYS("<C-O>", " abc" N " def" N " " X "ghi"); + KEYS("<C-I>", " " X "abc" N " def" N " ghi"); + + KEYS("lgUlhj", " aBc" N " " X "def" N " ghi"); + KEYS("`.", " a" X "Bc" N " def" N " ghi"); + KEYS("`'", " aBc" N " " X "def" N " ghi"); + KEYS("'.", " " X "aBc" N " def" N " ghi"); + KEYS("G", " aBc" N " def" N " " X "ghi"); + KEYS("u", " a" X "bc" N " def" N " ghi"); + KEYS("`'", " abc" N " def" N " " X "ghi"); + KEYS("<c-r>", " a" X "Bc" N " def" N " ghi"); + KEYS("jd$", " aBc" N " " X "d" N " ghi"); + KEYS("''", " aBc" N " d" N " " X "ghi"); + KEYS("`'", " aBc" N " " X "d" N " ghi"); + KEYS("u", " aBc" N " d" X "ef" N " ghi"); + KEYS("''", " aBc" N " " X "def" N " ghi"); + KEYS("`'", " aBc" N " d" X "ef" N " ghi"); +} + +void FakeVimPlugin::test_vim_copy_paste() +{ + TestData data; + setup(&data); + + data.setText("123" N "456"); + KEYS("llyy2P", X "123" N "123" N "123" N "456"); + + data.setText("123" N "456"); + KEYS("yyp", "123" N X "123" N "456"); + KEYS("2p", "123" N "123" N X "123" N "123" N "456"); + INTEGRITY(false); + + data.setText("123 456"); + KEYS("yw2P", "123 123" X " 123 456"); + KEYS("2p", "123 123 123 123" X " 123 456"); + + data.setText("123" N "456"); + KEYS("2yyp", "123" N X "123" N "456" N "456"); + + data.setText("123" N "456"); + KEYS("2yyP", X "123" N "456" N "123" N "456"); + + data.setText("123" N "456" N "789"); + KEYS("ddp", "456" N X "123" N "789"); + + // block-select middle column, copy and paste twice + data.setText("123" N "456"); + KEYS("l<C-v>j\"xy2\"xp", "12" X "223" N "45556"); + + data.setText("123" N "456" N "789"); + KEYS("wyiw" "wviwp", "123" N "456" N "45" X "6"); + + // QTCREATORBUG-8148 + data.setText("abc"); + KEYS("yyp", "abc" N X "abc"); + KEYS("4p", "abc" N "abc" N X "abc" N "abc" N "abc" N "abc"); +} + +void FakeVimPlugin::test_vim_undo_redo() +{ + TestData data; + setup(&data); + + data.setText("abc def" N "xyz" N "123"); + KEYS("ddu", X "abc def" N "xyz" N "123"); + COMMAND("redo", X "xyz" N "123"); + COMMAND("undo", X "abc def" N "xyz" N "123"); + COMMAND("redo", X "xyz" N "123"); + KEYS("dd", X "123"); + KEYS("3x", X ""); + KEYS("uuu", X "abc def" N "xyz" N "123"); + KEYS("<C-r>", X "xyz" N "123"); + KEYS("2<C-r>", X ""); + KEYS("3u", X "abc def" N "xyz" N "123"); + + KEYS("wved", "abc" X " " N "xyz" N "123"); + KEYS("2w", "abc " N "xyz" N X "123"); + KEYS("u", "abc " X "def" N "xyz" N "123"); + KEYS("<C-r>", "abc" X " " N "xyz" N "123"); + KEYS("10ugg", X "abc def" N "xyz" N "123"); + + KEYS("A xxx<ESC>", "abc def xx" X "x" N "xyz" N "123"); + KEYS("A yyy<ESC>", "abc def xxx yy" X "y" N "xyz" N "123"); + KEYS("u", "abc def xx" X "x" N "xyz" N "123"); + KEYS("u", "abc de" X "f" N "xyz" N "123"); + KEYS("<C-r>", "abc def" X " xxx" N "xyz" N "123"); + KEYS("<C-r>", "abc def xxx" X " yyy" N "xyz" N "123"); + + KEYS("izzz<ESC>", "abc def xxxzz" X "z yyy" N "xyz" N "123"); + KEYS("<C-r>", "abc def xxxzz" X "z yyy" N "xyz" N "123"); + KEYS("u", "abc def xxx" X " yyy" N "xyz" N "123"); + + data.setText("abc" N X "def"); + KEYS("oxyz<ESC>", "abc" N "def" N "xy" X "z"); + KEYS("u", "abc" N X "def"); + + // undo paste lines + data.setText("abc" N); + KEYS("yy2p", "abc" N X "abc" N "abc" N); + KEYS("yy3p", "abc" N "abc" N X "abc" N "abc" N "abc" N "abc" N); + KEYS("u", "abc" N X "abc" N "abc" N); + KEYS("u", X "abc" N); + KEYS("<C-r>", X "abc" N "abc" N "abc" N); + KEYS("<C-r>", "abc" N X "abc" N "abc" N "abc" N "abc" N "abc" N); + KEYS("u", "abc" N X "abc" N "abc" N); + KEYS("u", X "abc" N); + + // undo paste block + data.setText("abc" N "def" N "ghi"); + KEYS("<C-v>jyp", "a" X "abc" N "ddef" N "ghi"); + KEYS("2p", "aa" X "aabc" N "ddddef" N "ghi"); + KEYS("3p", "aaa" X "aaaabc" N "dddddddef" N "ghi"); + KEYS("u", "aa" X "aabc" N "ddddef" N "ghi"); + KEYS("u", "a" X "abc" N "ddef" N "ghi"); + + // undo indent + data.doCommand("set expandtab"); + data.doCommand("set shiftwidth=4"); + data.setText("abc" N "def"); + KEYS(">>", " " X "abc" N "def"); + KEYS(">>", " " X "abc" N "def"); + KEYS("<<", " " X "abc" N "def"); + KEYS("<<", X "abc" N "def"); + KEYS("u", " " X "abc" N "def"); + KEYS("u", " " X "abc" N "def"); + KEYS("u", " " X "abc" N "def"); + KEYS("u", X "abc" N "def"); + KEYS("<C-r>", X " abc" N "def"); + KEYS("<C-r>", " " X " abc" N "def"); + KEYS("<C-r>", " ab" X "c" N "def"); + KEYS("<C-r>", "ab" X "c" N "def"); + KEYS("<C-r>", "ab" X "c" N "def"); + + data.setText("abc" N "def"); + KEYS("2>>", " " X "abc" N " def"); + KEYS("u", X "abc" N "def"); + KEYS("<c-r>", X " abc" N " def"); + KEYS("u", X "abc" N "def"); + KEYS(">j", " " X "abc" N " def"); + KEYS("u", X "abc" N "def"); + KEYS("<c-r>", X " abc" N " def"); + + // undo replace line + data.setText("abc" N " def" N "ghi"); + KEYS("jlllSxyz<ESC>", "abc" N "xyz" N "ghi"); + KEYS("u", "abc" N " " X "def" N "ghi"); +} + +void FakeVimPlugin::test_vim_letter_case() +{ + TestData data; + setup(&data); + + // upper- and lower-case + data.setText("abc DEF"); + KEYS("lv3l~", "a" X "BC dEF"); + KEYS("v4lU", "a" X "BC DEF"); + KEYS("v4$u", "a" X "bc def"); + KEYS("v4$gU", "a" X "BC DEF"); + KEYS("gu$", "a" X "bc def"); + KEYS("lg~~", X "ABC DEF"); + KEYS(".", X "abc def"); + KEYS("gUiw", X "ABC def"); + + data.setText(" ab" X "c" N "def"); + KEYS("2gUU", " " X "ABC" N "DEF"); + KEYS("u", " " X "abc" N "def"); + KEYS("<c-r>", " " X "ABC" N "DEF"); +} + +void FakeVimPlugin::test_vim_code_autoindent() +{ + TestData data; + setup(&data); + + data.doCommand("set expandtab"); + data.doCommand("set shiftwidth=3"); + + data.setText("int main()" N + X "{" N + "}" N + ""); + KEYS("o" "return 0;", + "int main()" N + "{" N + " return 0;" X N + "}" N + ""); + INTEGRITY(false); + KEYS("O" "int i = 0;", + "int main()" N + "{" N + " int i = 0;" X N + " return 0;" N + "}" N + ""); + INTEGRITY(false); + KEYS("ddO" "int i = 0;" N "int j = 0;", + "int main()" N + "{" N + " int i = 0;" N + " int j = 0;" X N + " return 0;" N + "}" N + ""); + KEYS("^i" "int x = 1;" N, + "int main()" N + "{" N + " int i = 0;" N + " int x = 1;" N + " " X "int j = 0;" N + " return 0;" N + "}" N + ""); + KEYS("c2k" "if (true) {" N ";" N "}", + "int main()" N + "{" N + " if (true) {" N + " ;" N + " }" X N + " return 0;" N + "}" N + ""); + KEYS("jci{" "return 1;", + "int main()" N + "{" N + " return 1;" X N + "}" N + ""); + KEYS("di{", + "int main()" N + "{" N + X "}" N + ""); + INTEGRITY(false); + + // autoindent + data.doCommand("set nosmartindent"); + data.setText("abc" N "def"); + KEYS("3o 123<esc>", "abc" N " 123" N " 123" N " 12" X "3" N "def"); + INTEGRITY(false); + + data.setText("abc" N "def"); + KEYS("3O 123<esc>", " 123" N " 123" N " 12" X "3" N "abc" N "def"); + INTEGRITY(false); + data.doCommand("set smartindent"); +} + +void FakeVimPlugin::test_vim_code_folding() +{ + TestData data; + setup(&data); + + data.setText("int main()" N "{" N " return 0;" N "}" N ""); + + // fold/unfold function block + data.doKeys("zc"); + QCOMPARE(data.lines(), 2); + data.doKeys("zo"); + QCOMPARE(data.lines(), 5); + data.doKeys("za"); + QCOMPARE(data.lines(), 2); + + // delete whole block + KEYS("dd", ""); + + // undo/redo + KEYS("u", "int main()" N "{" N " return 0;" N "}" N ""); + KEYS("<c-r>", ""); + + // change block + KEYS("uggzo", X "int main()" N "{" N " return 0;" N "}" N ""); + KEYS("ccvoid f()<esc>", "void f(" X ")" N "{" N " return 0;" N "}" N ""); + KEYS("uzc.", "void f(" X ")" N ""); + + // open/close folds recursively + data.setText("int main()" N + "{" N + " if (true) {" N + " return 0;" N + " } else {" N + " // comment" N + " " X "return 2" N + " }" N + "}" N + ""); + int lines = data.lines(); + // close else block + data.doKeys("zc"); + QCOMPARE(data.lines(), lines - 3); + // close function block + data.doKeys("zc"); + QCOMPARE(data.lines(), lines - 8); + // jumping to a line opens all its parent folds + data.doKeys("6gg"); + QCOMPARE(data.lines(), lines); + + // close recursively + data.doKeys("zC"); + QCOMPARE(data.lines(), lines - 8); + data.doKeys("za"); + QCOMPARE(data.lines(), lines - 3); + data.doKeys("6gg"); + QCOMPARE(data.lines(), lines); + data.doKeys("zA"); + QCOMPARE(data.lines(), lines - 8); + data.doKeys("za"); + QCOMPARE(data.lines(), lines - 3); + + // close all folds + data.doKeys("zM"); + QCOMPARE(data.lines(), lines - 8); + data.doKeys("zo"); + QCOMPARE(data.lines(), lines - 4); + data.doKeys("zM"); + QCOMPARE(data.lines(), lines - 8); + + // open all folds + data.doKeys("zR"); + QCOMPARE(data.lines(), lines); + + // delete folded lined if deleting to the end of the first folding line + data.doKeys("zMgg"); + QCOMPARE(data.lines(), lines - 8); + KEYS("wwd$", "int main" N ""); + + // undo + KEYS("u", "int main" X "()" N + "{" N + " if (true) {" N + " return 0;" N + " } else {" N + " // comment" N + " return 2" N + " }" N + "}" N + ""); + + NOT_IMPLEMENTED + // Opening folds recursively isn't supported (previous position in fold isn't restored). +} + +void FakeVimPlugin::test_vim_substitute() +{ + TestData data; + setup(&data); + + data.setText("abcabc"); + COMMAND("s/abc/123/", X "123abc"); + COMMAND("u", X "abcabc"); + COMMAND("s/abc/123/g", X "123123"); + COMMAND("u", X "abcabc"); + + data.setText("abc" N "def"); + COMMAND("%s/^/ -- /", " -- abc" N " " X "-- def"); + COMMAND("u", X "abc" N "def"); + + data.setText(" abc" N " def"); + COMMAND("%s/$/./", " abc." N " " X "def."); + + data.setText("abc" N "def"); + COMMAND("%s/.*/(&)", "(abc)" N X "(def)"); + COMMAND("u", X "abc" N "def"); + COMMAND("%s/.*/X/g", "X" N X "X"); + + data.setText("abc" N "" N "def"); + COMMAND("%s/^\\|$/--", "--abc" N "--" N X "--def"); + COMMAND("u", X "abc" N "" N "def"); + COMMAND("%s/^\\|$/--/g", "--abc--" N "--" N X "--def--"); + + // captures + data.setText("abc def ghi"); + COMMAND("s/\\w\\+/'&'/g", X "'abc' 'def' 'ghi'"); + COMMAND("u", X "abc def ghi"); + COMMAND("s/\\w\\+/'\\&'/g", X "'&' '&' '&'"); + COMMAND("u", X "abc def ghi"); + COMMAND("s/\\(\\w\\{3}\\)/(\\1)/g", X "(abc) (def) (ghi)"); + COMMAND("u", X "abc def ghi"); + COMMAND("s/\\(\\w\\{3}\\) \\(\\w\\{3\\}\\)/\\2 \\1 \\\\1/g", X "def abc \\1 ghi"); + + // case-insensitive + data.setText("abc ABC abc"); + COMMAND("s/ABC/123/gi", X "123 123 123"); + + // replace on a line + data.setText("abc" N "def" N "ghi"); + COMMAND("2s/^/ + /", "abc" N " " X "+ def" N "ghi"); + COMMAND("1s/^/ * /", " " X "* abc" N " + def" N "ghi"); + COMMAND("$s/^/ - /", " * abc" N " + def" N " " X "- ghi"); + + // replace on lines + data.setText("abc" N "def" N "ghi"); + COMMAND("2,$s/^/ + /", "abc" N " + def" N " " X "+ ghi"); + COMMAND("1,2s/^/ * /", " * abc" N " " X "* + def" N " + ghi"); + COMMAND("3,3s/^/ - /", " * abc" N " * + def" N " " X "- + ghi"); + COMMAND("%s/\\( \\S \\)*//g", "abc" N "def" N X "ghi"); + + // last substitution + data.setText("abc" N "def" N "ghi"); + COMMAND("%s/DEF/+&/i", "abc" N X "+def" N "ghi"); + COMMAND("&&", "abc" N X "++def" N "ghi"); + COMMAND("&", "abc" N X "++def" N "ghi"); + COMMAND("&&", "abc" N X "++def" N "ghi"); + COMMAND("&i", "abc" N X "+++def" N "ghi"); + COMMAND("s", "abc" N X "+++def" N "ghi"); + COMMAND("&&i", "abc" N X "++++def" N "ghi"); + + // search for last substitute pattern + data.setText("abc" N "def" N "ghi"); + COMMAND("%s/def/def", "abc" N X "def" N "ghi"); + KEYS("gg", X "abc" N "def" N "ghi"); + COMMAND("\\&", "abc" N X "def" N "ghi"); + + // substitute last selection + data.setText("abc" N "def" N "ghi" N "jkl"); + KEYS("jVj:s/^/*<CR>", "abc" N "*def" N X "*ghi" N "jkl"); + COMMAND("'<,'>s/^/*", "abc" N "**def" N X "**ghi" N "jkl"); + KEYS("ugv:s/^/+<CR>", "abc" N "+*def" N X "+*ghi" N "jkl"); +} + +void FakeVimPlugin::test_vim_ex_yank() +{ + TestData data; + setup(&data); + + data.setText("abc" N "def"); + COMMAND("y x", X "abc" N "def"); + KEYS("\"xp", "abc" N X "abc" N "def"); + COMMAND("u", X "abc" N "def"); + COMMAND("redo", X "abc" N "abc" N "def"); + + KEYS("uw", "abc" N X "def"); + COMMAND("1y y", "abc" N X "def"); + KEYS("\"yP", "abc" N X "abc" N "def"); + COMMAND("u", "abc" N X "def"); + + COMMAND("-1,$y x", "abc" N X "def"); + KEYS("\"xP", "abc" N X "abc" N "def" N "def"); + COMMAND("u", "abc" N X "def"); + + COMMAND("$-1y", "abc" N X "def"); + KEYS("P", "abc" N X "abc" N "def"); + COMMAND("u", "abc" N X "def"); +} + +void FakeVimPlugin::test_vim_ex_delete() +{ + TestData data; + setup(&data); + + data.setText("abc" N X "def" N "ghi" N "jkl"); + COMMAND("d", "abc" N X "ghi" N "jkl"); + COMMAND("1,2d", X "jkl"); + COMMAND("u", X "abc" N "ghi" N "jkl"); + COMMAND("u", "abc" N X "def" N "ghi" N "jkl"); + KEYS("p", "abc" N "def" N X "abc" N "ghi" N "ghi" N "jkl"); + COMMAND("set ws|" "/abc/,/ghi/d|" "set nows", X "ghi" N "jkl"); + COMMAND("u", X "abc" N "def" N "abc" N "ghi" N "ghi" N "jkl"); + COMMAND("2,/abc/d3", "abc" N "def" N X "jkl"); + COMMAND("u", "abc" N "def" N X "abc" N "ghi" N "ghi" N "jkl"); + COMMAND("5,.+1d", "abc" N "def" N "abc" N X "jkl"); +} + +void FakeVimPlugin::test_vim_ex_change() +{ + TestData data; + setup(&data); + + data.setText("abc" N X "def" N "ghi" N "jkl"); + KEYS(":c<CR>xxx<ESC>0", "abc" N X "xxx" N "ghi" N "jkl"); + KEYS(":-1,+1c<CR>XXX<ESC>0", X "XXX" N "jkl"); +} + +void FakeVimPlugin::test_vim_ex_shift() +{ + TestData data; + setup(&data); + + data.doCommand("set expandtab"); + data.doCommand("set shiftwidth=2"); + + data.setText("abc" N X "def" N "ghi" N "jkl"); + COMMAND(">", "abc" N " " X "def" N "ghi" N "jkl"); + COMMAND(">>", "abc" N " " X "def" N "ghi" N "jkl"); + COMMAND("<", "abc" N " " X "def" N "ghi" N "jkl"); + COMMAND("<<", "abc" N X "def" N "ghi" N "jkl"); +} + +void FakeVimPlugin::test_vim_ex_move() +{ + TestData data; + setup(&data); + + data.setText("abc" N "def" N "ghi" N "jkl"); + COMMAND("m +1", "def" N X "abc" N "ghi" N "jkl"); + COMMAND("u", X "abc" N "def" N "ghi" N "jkl"); + COMMAND("redo", X "def" N "abc" N "ghi" N "jkl"); + COMMAND("m -2", X "def" N "abc" N "ghi" N "jkl"); + COMMAND("2m0", X "abc" N "def" N "ghi" N "jkl"); + + COMMAND("m $-2", "def" N X "abc" N "ghi" N "jkl"); + KEYS("`'", X "def" N "abc" N "ghi" N "jkl"); + KEYS("Vj:m+2<cr>", "ghi" N "def" N X "abc" N "jkl"); + KEYS("u", X "def" N "abc" N "ghi" N "jkl"); + + // move visual selection with indentation + data.doCommand("set expandtab"); + data.doCommand("set shiftwidth=2"); + data.doCommand("vnoremap <C-S-J> :m'>+<CR>gv="); + data.doCommand("vnoremap <C-S-K> :m-2<CR>gv="); + data.setText( + "int x;" N + "int y;" N + "int main() {" N + " if (true) {" N + " }" N + "}" N + ""); + KEYS("Vj<C-S-J>", + "int main() {" N + " int x;" N + " int y;" N + " if (true) {" N + " }" N + "}" N + ""); + KEYS("gv<C-S-J>", + "int main() {" N + " if (true) {" N + " int x;" N + " int y;" N + " }" N + "}" N + ""); + KEYS("gv<C-S-K>", + "int main() {" N + " int x;" N + " int y;" N + " if (true) {" N + " }" N + "}" N + ""); + data.doCommand("vunmap <C-S-K>"); + data.doCommand("vunmap <C-S-J>"); +} + +void FakeVimPlugin::test_vim_ex_join() +{ + TestData data; + setup(&data); + + data.setText(" abc" N X " def" N " ghi" N " jkl"); + COMMAND("j", " abc" N " " X "def ghi" N " jkl"); + COMMAND("u", " abc" N X " def" N " ghi" N " jkl"); + COMMAND("1j3", " " X "abc def ghi" N " jkl"); + COMMAND("u", X " abc" N " def" N " ghi" N " jkl"); +} + +void FakeVimPlugin::test_advanced_commands() +{ + TestData data; + setup(&data); + + // subcommands + data.setText("abc" N " xxx" N " xxx" N "def"); + COMMAND("%s/xxx/ZZZ/g|%s/ZZZ/OOO/g", "abc" N " OOO" N " " X "OOO" N "def"); + + // undo/redo all subcommands + COMMAND(":undo", "abc" N X " xxx" N " xxx" N "def"); + COMMAND(":redo", "abc" N X " OOO" N " OOO" N "def"); + + // redundant characters + COMMAND(" ::: %s/\\S\\S\\S/ZZZ/g |" + " :: : : %s/ZZZ/XXX/g ", "XXX" N " XXX" N " XXX" N X "XXX"); + + // bar character in regular expression is not command separator + data.setText("abc"); + COMMAND("%s/a\\|b\\||/X/g|%s/[^X]/Y/g", "XXY"); +} + +void FakeVimPlugin::test_map() +{ + TestData data; + setup(&data); + + data.setText("abc def"); + data.doCommand("map C i<space>x<space><esc>"); + data.doCommand("map c iXXX"); + data.doCommand("imap c YYY<space>"); + KEYS("C", " x" X " abc def"); + data.doCommand("map C <nop>"); + KEYS("C", " x" X " abc def"); + data.doCommand("map C i<bs><esc><right>"); + KEYS("C", " " X " abc def"); + KEYS("ccc<esc>", " XXXYYY YYY" X " abc def"); + // unmap + KEYS(":unmap c<cr>ccc<esc>", "YYY" X " "); + KEYS(":iunmap c<cr>ccc<esc>", X "c"); + data.doCommand("unmap C"); + + data.setText("abc def"); + data.doCommand("imap x (((<space><right><right>)))<esc>"); + KEYS("x", X "bc def"); + KEYS("ix", "((( bc))" X ") def"); + data.doCommand("iunmap x"); + + data.setText("abc def"); + data.doCommand("map <c-right> 3l"); + KEYS("<C-Right>", "abc" X " def"); + KEYS("<C-Right>", "abc de" X "f"); + + // map vs. noremap + data.setText("abc def"); + data.doCommand("map x 3l"); + data.doCommand("map X x"); + KEYS("X", "abc" X " def"); + data.doCommand("noremap X x"); + KEYS("X", "abc" X "def"); + data.doCommand("unmap X"); + data.doCommand("unmap x"); + + // limit number of recursions in mappings + data.doCommand("map X Y"); + data.doCommand("map Y Z"); + data.doCommand("map Z X"); + KEYS("X", "abc" X "def"); + data.doCommand("map Z i<space><esc>"); + KEYS("X", "abc" X " def"); + data.doCommand("unmap X"); + data.doCommand("unmap Y"); + data.doCommand("unmap Z"); + + // imcomplete mapping + data.setText("abc"); + data.doCommand("map Xa ia<esc>"); + data.doCommand("map Xb ib<esc>"); + data.doCommand("map X ic<esc>"); + KEYS("Xa", X "aabc"); + KEYS("Xb", X "baabc"); + KEYS("Xic<esc>", X "ccbaabc"); + + // unmap + data.doCommand("unmap Xa"); + KEYS("Xa<esc>", X "cccbaabc"); + data.doCommand("unmap Xb"); + KEYS("Xb", X "ccccbaabc"); + data.doCommand("unmap X"); + KEYS("Xb", X "ccccbaabc"); + KEYS("X<esc>", X "ccccbaabc"); + + // recursive mapping + data.setText("abc"); + data.doCommand("map X Y"); + data.doCommand("map XXX i1<esc>"); + data.doCommand("map Y i2<esc>"); + data.doCommand("map YZ i3<esc>"); + data.doCommand("map _ i <esc>"); + KEYS("_XXX_", X " 1 abc"); + KEYS("XX_0", X " 22 1 abc"); + KEYS("XXXXZ_0", X " 31 22 1 abc"); + KEYS("XXXXX_0", X " 221 31 22 1 abc"); + KEYS("XXZ", X "32 221 31 22 1 abc"); + data.doCommand("unmap X"); + data.doCommand("unmap XXX"); + data.doCommand("unmap Y"); + data.doCommand("unmap YZ"); + data.doCommand("unmap _"); + + // shift modifier + data.setText("abc"); + data.doCommand("map x i1<esc>"); + data.doCommand("map X i2<esc>"); + KEYS("x", X "1abc"); + KEYS("X", X "21abc"); + data.doCommand("map <S-X> i3<esc>"); + KEYS("X", X "321abc"); + data.doCommand("map X i4<esc>"); + KEYS("X", X "4321abc"); + KEYS("x", X "14321abc"); + data.doCommand("unmap x"); + data.doCommand("unmap X"); + + // undo/redo mapped input + data.setText("abc def ghi"); + data.doCommand("map X dwea xyz<esc>3l"); + KEYS("X", "def xyz g" X "hi"); + KEYS("u", X "abc def ghi"); + KEYS("<C-r>", X "def xyz ghi"); + data.doCommand("unmap X"); + + data.setText("abc" N " def" N " ghi"); + data.doCommand("map X jdd"); + KEYS("X", "abc" N " " X "ghi"); + KEYS("u", "abc" N X " def" N " ghi"); + KEYS("<c-r>", "abc" N X " ghi"); + data.doCommand("unmap X"); + + data.setText("abc" N "def" N "ghi"); + data.doCommand("map X jAxxx<cr>yyy<esc>"); + KEYS("X", "abc" N "defxxx" N "yy" X "y" N "ghi"); + KEYS("u", "abc" N "de" X "f" N "ghi"); + KEYS("<c-r>", "abc" N "def" X "xxx" N "yyy" N "ghi"); + data.doCommand("unmap X"); + + /* QTCREATORBUG-7913 */ + data.setText(""); + data.doCommand("noremap l k|noremap k j|noremap j h"); + KEYS("ikkk<esc>", "kk" X "k"); + KEYS("rj", "kk" X "j"); + data.doCommand("unmap l|unmap k|unmap j"); + + // bad mapping + data.setText(X "abc" N "def"); + data.doCommand("map X Zxx"); + KEYS("X", X "abc" N "def"); + // cancelled mapping + data.doCommand("map X fxxx"); + KEYS("X", X "abc" N "def"); + data.doCommand("map X ciXxx"); + KEYS("X", X "abc" N "def"); + data.doCommand("map Y Xxx"); + KEYS("Y", X "abc" N "def"); + data.doCommand("unmap X|unmap Y"); + + // <C-o> + data.setText("abc def"); + data.doCommand("imap X <c-o>:%s/def/xxx/<cr>"); + KEYS("iX", "abc xxx"); +} + +void FakeVimPlugin::test_vim_command_cc() +{ + TestData data; + setup(&data); + + data.setText( "|123" N "456" N "789" N "abc"); + KEYS("cc456<ESC>", "45|6" N "456" N "789" N "abc"); + KEYS("ccabc<Esc>", "ab|c" N "456" N "789" N "abc"); + KEYS(".", "ab|c" N "456" N "789" N "abc"); + KEYS("j", "abc" N "45|6" N "789" N "abc"); + KEYS(".", "abc" N "ab|c" N "789" N "abc"); + KEYS("kkk", "ab|c" N "abc" N "789" N "abc"); + KEYS("3ccxyz<Esc>", "xy|z" N "abc"); +} + +void FakeVimPlugin::test_vim_command_cw() +{ + TestData data; + setup(&data); + data.setText(X "123 456"); + KEYS("cwx<Esc>", X "x 456"); +} + +void FakeVimPlugin::test_vim_command_cj() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j$", cursor(1, -1)); + KEYS("cj<Esc>", l[0]+"\n|" + "\n" + lmid(3)); + KEYS("P", lmid(0,1)+"\n" + "|"+lmid(1,2)+"\n" + "\n" + lmid(3)); + KEYS("u", l[0]+"\n|" + "\n" + lmid(3)); + + data.setText(testLines); + KEYS("j$", cursor(1, -1)); + KEYS("cjabc<Esc>", l[0]+"\nab|c\n" + lmid(3)); + KEYS("u", cursor(2, 0)); + KEYS("gg", cursor(0, 0)); + KEYS(".", "ab|c\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_ck() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j$", cursor(1, -1)); + KEYS("ck<Esc>", "|\n" + lmid(2)); + KEYS("P", "|" + lmid(0,2)+"\n" + "\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_c_dollar() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j", cursor(1, 0)); + KEYS("$", cursor(1, -1)); + KEYS("c$<Esc>", l[0]+"\n" + l[1].left(l[1].length()-2)+"|"+l[1][l[1].length()-2]+"\n" + lmid(2)); + KEYS("c$<Esc>", l[0]+"\n" + l[1].left(l[1].length()-3)+"|"+l[1][l[1].length()-3]+"\n" + lmid(2)); + KEYS("0c$abc<Esc>", l[0]+"\n" + "ab|c\n" + lmid(2)); + KEYS("0c$abc<Esc>", l[0]+"\n" + "ab|c\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_C() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j", cursor(1, 0)); + KEYS("Cabc<Esc>", l[0] + "\nab|c\n" + lmid(2)); + KEYS("Cabc<Esc>", l[0] + "\nabab|c\n" + lmid(2)); + KEYS("$Cabc<Esc>", l[0] + "\nababab|c\n" + lmid(2)); + KEYS("0C<Esc>", l[0] + "\n|\n" + lmid(2)); + KEYS("0Cabc<Esc>", l[0] + "\nab|c\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_dw() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("dw", "|#include <QtCore>\n" + lmid(2)); + KEYS("dw", "|include <QtCore>\n" + lmid(2)); + KEYS("dw", "|<QtCore>\n" + lmid(2)); + KEYS("dw", "|QtCore>\n" + lmid(2)); + KEYS("dw", "|>\n" + lmid(2)); + KEYS("dw", "|\n" + lmid(2)); // Real vim has this intermediate step, too + KEYS("dw", "|#include <QtGui>\n" + lmid(3)); + KEYS("dw", "|include <QtGui>\n" + lmid(3)); + KEYS("dw", "|<QtGui>\n" + lmid(3)); + KEYS("dw", "|QtGui>\n" + lmid(3)); + KEYS("dw", "|>\n" + lmid(3)); +} + +void FakeVimPlugin::test_vim_command_dd() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j", cursor(1, 0)); + KEYS("dd", l[0] + "\n|" + lmid(2)); + KEYS(".", l[0] + "\n|" + lmid(3)); + KEYS("3dd", l[0] + "\n |QApplication app(argc, argv);\n" + lmid(7)); + KEYS("4l", l[0] + "\n QApp|lication app(argc, argv);\n" + lmid(7)); + KEYS("dd", l[0] + "\n|" + lmid(7)); + KEYS(".", l[0] + "\n |return app.exec();\n" + lmid(9)); + KEYS("dd", l[0] + "\n|" + lmid(9)); +} + +void FakeVimPlugin::test_vim_command_dd_2() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j", cursor(1, 0)); + KEYS("dd", l[0] + "\n|" + lmid(2)); + KEYS("p", l[0] + "\n" + l[2] + "\n|" + l[1] + "\n" + lmid(3)); + KEYS("u", l[0] + "\n|" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_d_dollar() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j$", cursor(1, -1)); + KEYS("$d$", l[0]+"\n" + l[1].left(l[1].length()-2)+"|"+l[1][l[1].length()-2]+"\n" + lmid(2)); + KEYS("0d$", l[0] + "\n"+"|\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_dj() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j$", cursor(1, -1)); + KEYS("dj", l[0]+"\n|" + lmid(3)); + KEYS("P", lmid(0,1)+"\n" + "|"+lmid(1)); + KEYS("0", lmid(0,1)+"\n" + "|"+lmid(1)); + KEYS("dj", l[0]+"\n|" + lmid(3)); + KEYS("P", lmid(0,1)+"\n" + "|"+lmid(1)); + KEYS("05l", l[0]+"\n" + l[1].left(5) + "|" + l[1].mid(5)+"\n" + lmid(2)); + KEYS("dj", l[0]+"\n|" + lmid(3)); + KEYS("P", lmid(0,1)+"\n" + "|"+lmid(1)); + KEYS("dj", l[0]+"\n|" + lmid(3)); + KEYS("p", lmid(0,1)+"\n" + lmid(3,1)+"\n" + "|"+lmid(1,2)+"\n" + lmid(4)); +} + +void FakeVimPlugin::test_vim_command_dk() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j$", cursor(1, -1)); + KEYS("dk", "|" + lmid(2)); + KEYS("P", "|" + lmid(0)); + KEYS("j0", l[0]+ "\n|" + lmid(1)); + KEYS("dk", "|" + lmid(2)); + KEYS("P", "|" + lmid(0)); + KEYS("j05l", l[0]+"\n" + l[1].left(5) + "|" + l[1].mid(5)+"\n" + lmid(2)); + KEYS("dk", "|" + lmid(2)); + KEYS("P", "|" + lmid(0)); + KEYS("j05l", l[0]+"\n" + l[1].left(5) + "|" + l[1].mid(5)+"\n" + lmid(2)); + KEYS("dk", "|" + lmid(2)); + KEYS("p", lmid(2,1)+"\n" + "|" + lmid(0,2)+"\n" + lmid(3)); +} + +void FakeVimPlugin::test_vim_command_dgg() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("G", lmid(0, l.size()-2)+"\n" "|"+lmid(l.size()-2)); + KEYS("dgg", "|"); + KEYS("u", "|" + lmid(0)); +} + +void FakeVimPlugin::test_vim_command_dG() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("dG", "|"); + KEYS("u", "|" + lmid(0)); + KEYS("j", cursor(1, 0)); + KEYS("dG", lmid(0,1)+"\n" + "|"); + KEYS("u", l[0]+"\n" + "|" + lmid(1)); + KEYS("G", lmid(0, l.size()-2)+"\n" + "|"+lmid(l.size()-2)); + + NOT_IMPLEMENTED + // include movement to first column, as otherwise the result depends on the 'startofline' setting + KEYS("dG0", lmid(0, l.size()-2)+"\n" + "|"+lmid(l.size()-2,1)); + KEYS("dG0", lmid(0, l.size()-3)+"\n" + "|"+lmid(l.size()-3,1)); +} + +void FakeVimPlugin::test_vim_command_D() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j", cursor(1, 0)); + KEYS("$D", l[0]+"\n" + l[1].left(l[1].length()-2)+"|"+l[1][l[1].length()-2]+"\n" + lmid(2)); + KEYS("0D", l[0] + "\n|\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_dollar() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j$", cursor(1, -1)); + KEYS("j$", cursor(2, -1)); + KEYS("2j", cursor(4, -1)); +} + +void FakeVimPlugin::test_vim_command_down() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j", l[0]+ "\n|" + lmid(1)); + KEYS("3j", lmid(0,4)+"\n" + "|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("4j", lmid(0,8)+"\n" + "| return app.exec();\n" + lmid(9)); +} + +void FakeVimPlugin::test_vim_command_dfx_down() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j4l", l[0] + "\n#inc|lude <QtCore>\n" + lmid(2)); + + //NOT_IMPLEMENTED + KEYS("df ", l[0] + "\n#inc|<QtCore>\n" + lmid(2)); + KEYS("j", l[0] + "\n#inc<QtCore>\n#inc|lude <QtGui>\n" + lmid(3)); + KEYS(".", l[0] + "\n#inc<QtCore>\n#inc|<QtGui>\n" + lmid(3)); + KEYS("u", l[0] + "\n#inc<QtCore>\n#inc|lude <QtGui>\n" + lmid(3)); + KEYS("u", l[0] + "\n#inc|lude <QtCore>\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_Cxx_down_dot() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j4l", l[0] + "\n#inc|lude <QtCore>\n" + lmid(2)); + KEYS("Cxx<Esc>", l[0] + "\n#incx|x\n" + lmid(2)); + KEYS("j", l[0] + "\n#incxx\n#incl|ude <QtGui>\n" + lmid(3)); + KEYS(".", l[0] + "\n#incxx\n#inclx|x\n" + lmid(3)); +} + +void FakeVimPlugin::test_vim_command_e() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("e", lmid(0,1)+"\n" + "|#include <QtCore>\n" + lmid(2)); + KEYS("e", lmid(0,1)+"\n" + "#includ|e <QtCore>\n" + lmid(2)); + KEYS("e", lmid(0,1)+"\n" + "#include |<QtCore>\n" + lmid(2)); + KEYS("3e", lmid(0,2)+"\n" + "|#include <QtGui>\n" + lmid(3)); + KEYS("e", lmid(0,2)+"\n" + "#includ|e <QtGui>\n" + lmid(3)); + KEYS("e", lmid(0,2)+"\n" + "#include |<QtGui>\n" + lmid(3)); + KEYS("e", lmid(0,2)+"\n" + "#include <QtGu|i>\n" + lmid(3)); + KEYS("4e", lmid(0,4)+"\n" + "int main|(int argc, char *argv[])\n" + lmid(5)); + KEYS("e", lmid(0,4)+"\n" + "int main(in|t argc, char *argv[])\n" + lmid(5)); + KEYS("e", lmid(0,4)+"\n" + "int main(int arg|c, char *argv[])\n" + lmid(5)); + KEYS("e", lmid(0,4)+"\n" + "int main(int argc|, char *argv[])\n" + lmid(5)); + KEYS("e", lmid(0,4)+"\n" + "int main(int argc, cha|r *argv[])\n" + lmid(5)); + KEYS("e", lmid(0,4)+"\n" + "int main(int argc, char |*argv[])\n" + lmid(5)); + KEYS("e", lmid(0,4)+"\n" + "int main(int argc, char *arg|v[])\n" + lmid(5)); + KEYS("e", lmid(0,4)+"\n" + "int main(int argc, char *argv[]|)\n" + lmid(5)); + KEYS("e", lmid(0,5)+"\n" + "|{\n" + lmid(6)); + KEYS("10k","|\n" + lmid(1)); // home. +} + +void FakeVimPlugin::test_vim_command_i() +{ + TestData data; + setup(&data); + + data.setText(testLines); + + // empty insertion at start of document + KEYS("i<Esc>", "|" + testLines); + KEYS("u", "|" + testLines); + + // small insertion at start of document + KEYS("ix<Esc>", "|x" + testLines); + KEYS("u", "|" + testLines); + COMMAND("redo", "|x" + testLines); + KEYS("u", "|" + testLines); + + // small insertion at start of document + KEYS("ixxx<Esc>", "xx|x" + testLines); + KEYS("u", "|" + testLines); + + // combine insertions + KEYS("i1<Esc>", "|1" + testLines); + KEYS("i2<Esc>", "|21" + testLines); + KEYS("i3<Esc>", "|321" + testLines); + KEYS("u", "|21" + testLines); + KEYS("u", "|1" + testLines); + KEYS("u", "|" + testLines); + KEYS("ia<Esc>", "|a" + testLines); + KEYS("ibx<Esc>", "b|xa" + testLines); + KEYS("icyy<Esc>", "bcy|yxa" + testLines); + KEYS("u", "b|xa" + testLines); + KEYS("u", "|a" + testLines); + COMMAND("redo", "|bxa" + testLines); + KEYS("u", "|a" + testLines); +} + +void FakeVimPlugin::test_vim_command_left() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("4j", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("h", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("$", lmid(0, 4) + "\nint main(int argc, char *argv[]|)\n" + lmid(5)); + KEYS("h", lmid(0, 4) + "\nint main(int argc, char *argv[|])\n" + lmid(5)); + KEYS("3h", lmid(0, 4) + "\nint main(int argc, char *ar|gv[])\n" + lmid(5)); + KEYS("50h", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); +} + +void FakeVimPlugin::test_vim_command_r() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("4j", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("$", lmid(0, 4) + "\nint main(int argc, char *argv[]|)\n" + lmid(5)); + KEYS("rx", lmid(0, 4) + "\nint main(int argc, char *argv[]|x\n" + lmid(5)); + KEYS("2h", lmid(0, 4) + "\nint main(int argc, char *argv|[]x\n" + lmid(5)); + KEYS("4ra", lmid(0, 4) + "\nint main(int argc, char *argv|[]x\n" + lmid(5)); + KEYS("3rb", lmid(0, 4) + "\nint main(int argc, char *argvbb|b\n" + lmid(5)); + KEYS("2rc", lmid(0, 4) + "\nint main(int argc, char *argvbb|b\n" + lmid(5)); + KEYS("h2rc",lmid(0, 4) + "\nint main(int argc, char *argvbc|c\n" + lmid(5)); +} + +void FakeVimPlugin::test_vim_command_right() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("4j", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("l", lmid(0, 4) + "\ni|nt main(int argc, char *argv[])\n" + lmid(5)); + KEYS("3l", lmid(0, 4) + "\nint |main(int argc, char *argv[])\n" + lmid(5)); + KEYS("50l", lmid(0, 4) + "\nint main(int argc, char *argv[]|)\n" + lmid(5)); +} + +void FakeVimPlugin::test_vim_command_up() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("9j", lmid(0, 9) + "\n|}\n"); + KEYS("k", lmid(0, 8) + "\n| return app.exec();\n" + lmid(9)); + KEYS("4k", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("3k", lmid(0, 1) + "\n|#include <QtCore>\n" + lmid(2)); + KEYS("k", cursor(0, 0)); + KEYS("2k", cursor(0, 0)); +} + +void FakeVimPlugin::test_vim_command_w() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("w", lmid(0,1)+"\n" + "|#include <QtCore>\n" + lmid(2)); + KEYS("w", lmid(0,1)+"\n" + "#|include <QtCore>\n" + lmid(2)); + KEYS("w", lmid(0,1)+"\n" + "#include |<QtCore>\n" + lmid(2)); + KEYS("3w", lmid(0,2)+"\n" + "|#include <QtGui>\n" + lmid(3)); + KEYS("w", lmid(0,2)+"\n" + "#|include <QtGui>\n" + lmid(3)); + KEYS("w", lmid(0,2)+"\n" + "#include |<QtGui>\n" + lmid(3)); + KEYS("w", lmid(0,2)+"\n" + "#include <|QtGui>\n" + lmid(3)); + KEYS("4w", lmid(0,4)+"\n" + "int |main(int argc, char *argv[])\n" + lmid(5)); + KEYS("w", lmid(0,4)+"\n" + "int main|(int argc, char *argv[])\n" + lmid(5)); + KEYS("w", lmid(0,4)+"\n" + "int main(|int argc, char *argv[])\n" + lmid(5)); + KEYS("w", lmid(0,4)+"\n" + "int main(int |argc, char *argv[])\n" + lmid(5)); + KEYS("w", lmid(0,4)+"\n" + "int main(int argc|, char *argv[])\n" + lmid(5)); + KEYS("w", lmid(0,4)+"\n" + "int main(int argc, |char *argv[])\n" + lmid(5)); + KEYS("w", lmid(0,4)+"\n" + "int main(int argc, char |*argv[])\n" + lmid(5)); + KEYS("w", lmid(0,4)+"\n" + "int main(int argc, char *|argv[])\n" + lmid(5)); + KEYS("w", lmid(0,4)+"\n" + "int main(int argc, char *argv|[])\n" + lmid(5)); + KEYS("w", lmid(0,5)+"\n" + "|{\n" + lmid(6)); +} + +void FakeVimPlugin::test_vim_command_yyp() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("4j", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("yyp", lmid(0, 4) + "\n" + lmid(4, 1) + "\n|" + lmid(4)); +} + +void FakeVimPlugin::test_vim_command_y_dollar() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j", l[0]+"\n|" + lmid(1)); + KEYS("$y$p", l[0]+"\n"+ l[1]+"|>\n" + lmid(2)); + KEYS("$y$p", l[0]+"\n"+ l[1]+">|>\n" + lmid(2)); + KEYS("$y$P", l[0]+"\n"+ l[1]+">|>>\n" + lmid(2)); + KEYS("$y$P", l[0]+"\n"+ l[1]+">>|>>\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_Yp() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("4j", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("Yp", lmid(0, 4) + "\n" + lmid(4, 1) + "\n|" + lmid(4)); +} + +void FakeVimPlugin::test_vim_command_ma_yank() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("4j", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("ygg", "|" + lmid(0)); + KEYS("4j", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("p", lmid(0,5) + "\n|" + lmid(0,4) +"\n" + lmid(4)); + + data.setText(testLines); + + KEYS("gg", "|" + lmid(0)); + KEYS("ma", "|" + lmid(0)); + KEYS("4j", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); + KEYS("mb", lmid(0,4) + "\n|" + lmid(4)); + KEYS("\"ay'a", "|" + lmid(0)); + KEYS("'b", lmid(0,4) + "\n|" + lmid(4)); + KEYS("\"ap", lmid(0,5) + "\n|" + lmid(0,4) +"\n" + lmid(4)); +} + +void FakeVimPlugin::test_vim_command_Gyyp() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("G", lmid(0, l.size()-2) + "\n|" + lmid(l.size()-2)); + KEYS("yyp", lmid(0) + "|" + lmid(9, 1)+"\n"); +} + +void FakeVimPlugin::test_i_cw_i() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j", l[0] + "\n|" + lmid(1)); + KEYS("ixx<Esc>", l[0] + "\nx|x" + lmid(1)); + KEYS("cwyy<Esc>", l[0] + "\nxy|y" + lmid(1)); + KEYS("iaa<Esc>", l[0] + "\nxya|ay" + lmid(1)); +} + +void FakeVimPlugin::test_vim_command_J() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("4j4l", lmid(0, 4) + "\nint |main(int argc, char *argv[])\n" + lmid(5)); + + KEYS("J", lmid(0, 5) + "| " + lmid(5)); + KEYS("u", lmid(0, 4) + "\nint |main(int argc, char *argv[])\n" + lmid(5)); + COMMAND("redo", lmid(0, 5) + "| " + lmid(5)); + + KEYS("3J", lmid(0, 5) + " " + lmid(5, 1) + " " + lmid(6, 1).mid(4) + "| " + lmid(7)); + KEYS("uu", lmid(0, 4) + "\nint |main(int argc, char *argv[])\n" + lmid(5)); + COMMAND("redo", lmid(0, 5) + "| " + lmid(5)); +} + +void FakeVimPlugin::test_vim_command_put_at_eol() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("j$", cursor(1, -1)); + KEYS("y$", cursor(1, -1)); + KEYS("p", lmid(0,2)+"|>\n" + lmid(2)); + KEYS("p", lmid(0,2)+">|>\n" + lmid(2)); + KEYS("$", lmid(0,2)+">|>\n" + lmid(2)); + KEYS("P", lmid(0,2)+">|>>\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_command_oO() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("gg", "|" + lmid(0)); + KEYS("Ol1<Esc>", "l|1\n" + lmid(0)); + KEYS("gg", "|l1\n" + lmid(0)); + KEYS("ol2<Esc>", "l1\n" "l|2\n" + lmid(0)); + KEYS("G", "l1\n" "l2\n" + lmid(0,l.size()-2)+"\n" + "|"+lmid(l.size()-2)); + KEYS("G$", "l1\n" "l2\n" + lmid(0,l.size()-2)+"\n" + "|"+lmid(l.size()-2)); + KEYS("ol-1<Esc>", "l1\n" "l2\n" + lmid(0) + "l-|1\n"); + KEYS("G", "l1\n" "l2\n" + lmid(0) + "|l-1\n"); + KEYS("Ol-2<Esc>", "l1\n" "l2\n" + lmid(0) + "l-|2\n" + "l-1\n"); +} + +void FakeVimPlugin::test_vim_command_x() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("x", "|" + lmid(0)); + KEYS("j$", cursor(1, -1)); + KEYS("x", lmid(0,1)+"\n" + l[1].left(l[1].length()-2)+"|"+l[1].mid(l[1].length()-2,1)+"\n" + lmid(2)); +} + +void FakeVimPlugin::test_vim_visual_d() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("vd", "|" + lmid(0)); + KEYS("vx", "|" + lmid(0)); + KEYS("vjd", "|" + lmid(1).mid(1)); + KEYS("u", "|" + lmid(0)); + KEYS("j", lmid(0, 1)+"\n" + "|" + lmid(1)); + KEYS("vd", lmid(0, 1)+"\n" + "|" + lmid(1).mid(1)); + KEYS("u", lmid(0, 1)+"\n" + "|" + lmid(1)); + KEYS("vx", lmid(0, 1)+"\n" + "|" + lmid(1).mid(1)); + KEYS("u", lmid(0, 1)+"\n" + "|" + lmid(1)); + KEYS("vhx", lmid(0, 1)+"\n" + "|" + lmid(1).mid(1)); + KEYS("u", lmid(0, 1)+"\n" + "|" + lmid(1)); + KEYS("vlx", lmid(0, 1)+"\n" + "|" + lmid(1).mid(2)); + KEYS("P", lmid(0, 1)+"\n" + lmid(1).left(1)+"|"+lmid(1).mid(1)); + KEYS("vhd", lmid(0, 1)+"\n" + "|" + lmid(1).mid(2)); + KEYS("u", lmid(0, 1)+"\n" + "|" + lmid(1)); + + KEYS("v$d", lmid(0, 1)+"\n" + "|" + lmid(2)); + NOT_IMPLEMENTED + KEYS("v$od", lmid(0, 1)+"\n" + "|" + lmid(3)); + KEYS("$v$x", lmid(0, 1)+"\n" + lmid(3,1) + "|" + lmid(4)); + KEYS("0v$d", lmid(0, 1)+"\n" + "|" + lmid(5)); + KEYS("$v0d", lmid(0, 1)+"\n" + "|\n" + lmid(6)); + KEYS("v$o0k$d", lmid(0, 1)+"\n" + "|" + lmid(6).mid(1)); +} + +void FakeVimPlugin::test_vim_Visual_d() +{ + TestData data; + setup(&data); + + data.setText(testLines); + KEYS("Vd", "|" + lmid(1)); + KEYS("V2kd", "|" + lmid(2)); + KEYS("u", "|" + lmid(1)); + KEYS("u", "|" + lmid(0)); + KEYS("j", lmid(0,1)+"\n" + "|" + lmid(1)); + KEYS("V$d", lmid(0,1)+"\n" + "|" + lmid(2)); + KEYS("$V$$d", lmid(0,1)+"\n" + "|" + lmid(3)); + KEYS("Vkx", "|" + lmid(4)); + KEYS("P", "|" + lmid(0,1)+"\n" + lmid(3)); +} diff --git a/src/plugins/fakevim/fakevimactions.cpp b/src/plugins/fakevim/fakevimactions.cpp index 88096894b5..f0025f4b4e 100644 --- a/src/plugins/fakevim/fakevimactions.cpp +++ b/src/plugins/fakevim/fakevimactions.cpp @@ -218,6 +218,13 @@ FakeVimSettings *theFakeVimSettings() instance->insertItem(ConfigSmartCase, item, _("smartcase"), _("scs")); item = new SavedAction(instance); + item->setDefaultValue(true); + item->setValue(true); + item->setSettingsKey(group, _("WrapScan")); item->setCheckable(true); + item->setCheckable(true); + instance->insertItem(ConfigWrapScan, item, _("wrapscan"), _("ws")); + + item = new SavedAction(instance); item->setDefaultValue(_("indent,eol,start")); item->setSettingsKey(group, _("Backspace")); instance->insertItem(ConfigBackspace, item, _("backspace"), _("bs")); @@ -249,6 +256,13 @@ FakeVimSettings *theFakeVimSettings() item->setCheckable(true); instance->insertItem(ConfigClipboard, item, _("clipboard"), _("cb")); + item = new SavedAction(instance); + item->setDefaultValue(true); + item->setValue(true); + item->setSettingsKey(group, _("ShowCmd")); item->setCheckable(true); + item->setCheckable(true); + instance->insertItem(ConfigShowCmd, item, _("showcmd"), _("sc")); + return instance; } diff --git a/src/plugins/fakevim/fakevimactions.h b/src/plugins/fakevim/fakevimactions.h index ae0bc65df9..f50ff4b8f1 100644 --- a/src/plugins/fakevim/fakevimactions.h +++ b/src/plugins/fakevim/fakevimactions.h @@ -52,9 +52,11 @@ enum FakeVimSettingsCode ConfigExpandTab, ConfigAutoIndent, ConfigSmartIndent, + ConfigIncSearch, ConfigUseCoreSearch, ConfigSmartCase, + ConfigWrapScan, // indent allow backspacing over autoindent // eol allow backspacing over line breaks (join lines) @@ -68,7 +70,8 @@ enum FakeVimSettingsCode // other actions ConfigShowMarks, ConfigPassControlKey, - ConfigClipboard + ConfigClipboard, + ConfigShowCmd }; class FakeVimSettings : public QObject diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 197466a80f..0da53b67af 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -59,6 +59,7 @@ #include "fakevimhandler.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDebug> @@ -98,7 +99,7 @@ //#define DEBUG_UNDO 1 #if DEBUG_UNDO -# define UNDO_DEBUG(s) qDebug() << << document()->availableUndoSteps() << s +# define UNDO_DEBUG(s) qDebug() << << revision() << s #else # define UNDO_DEBUG(s) #endif @@ -125,20 +126,13 @@ namespace Internal { #define EndOfDocument QTextCursor::End #define StartOfDocument QTextCursor::Start +#define ParagraphSeparator QChar::ParagraphSeparator + #define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s) -enum { -#ifdef Q_OS_MAC - RealControlModifier = Qt::MetaModifier -#else - RealControlModifier = Qt::ControlModifier -#endif -}; -// Enforce use of RealControlModifier by breaking the compilation. -#define MetaModifier // Use RealControlModifier instead -#define ControlModifier // Use RealControlModifier instead +#define MetaModifier // Use HostOsInfo::controlModifier() instead +#define ControlModifier // Use HostOsInfo::controlModifier() instead -const int ParagraphSeparator = 0x00002029; typedef QLatin1String _; /* Clipboard MIME types used by Vim. */ @@ -171,7 +165,9 @@ enum SubMode RegisterSubMode, // Used for " ShiftLeftSubMode, // Used for < ShiftRightSubMode, // Used for > - TransformSubMode, // Used for ~/gu/gU + InvertCaseSubMode, // Used for g~ + DownCaseSubMode, // Used for gu + UpCaseSubMode, // Used for gU WindowSubMode, // Used for Ctrl-w YankSubMode, // Used for y ZSubMode, // Used for z @@ -191,9 +187,6 @@ enum SubSubMode MarkSubSubMode, // Used for m. BackTickSubSubMode, // Used for `. TickSubSubMode, // Used for '. - InvertCaseSubSubMode, // Used for ~. - DownCaseSubSubMode, // Used for gu. - UpCaseSubSubMode, // Used for gU. TextObjectSubSubMode, // Used for thing like iw, aW, as etc. SearchSubSubMode }; @@ -239,9 +232,62 @@ enum EventResult { EventHandled, EventUnhandled, + EventCancelled, // Event is handled but a sub mode was cancelled. EventPassedToCore }; +struct CursorPosition +{ + CursorPosition() : line(-1), column(-1) {} + CursorPosition(int block, int column) : line(block), column(column) {} + explicit CursorPosition(const QTextCursor &tc) + : line(tc.block().blockNumber()), column(tc.positionInBlock()) {} + CursorPosition(const QTextDocument *document, int position) + { + QTextBlock block = document->findBlock(position); + line = block.blockNumber(); + column = position - block.position(); + } + bool isValid() const { return line >= 0 && column >= 0; } + bool operator==(const CursorPosition &other) const + { return line == other.line && column == other.column; } + bool operator!=(const CursorPosition &other) const { return !operator==(other); } + + int line; // Line in document (from 0, folded lines included). + int column; // Position on line. +}; + +struct Mark +{ + Mark(const CursorPosition &pos = CursorPosition(), const QString &fileName = QString()) + : position(pos), fileName(fileName) {} + + bool isValid() const { return position.isValid(); } + + bool isLocal(const QString &localFileName) const + { + return fileName.isEmpty() || fileName == localFileName; + } + + CursorPosition position; + QString fileName; +}; +typedef QHash<QChar, Mark> Marks; +typedef QHashIterator<QChar, Mark> MarksIterator; + +struct State +{ + State() : revision(-1), position(), marks(), lastVisualMode(NoVisualMode) {} + State(int revision, const CursorPosition &position, const Marks &marks, + VisualMode lastVisualMode) : revision(revision), position(position), marks(marks), + lastVisualMode(lastVisualMode) {} + + int revision; + CursorPosition position; + Marks marks; + VisualMode lastVisualMode; +}; + struct Column { Column(int p, int l) : physical(p), logical(l) {} @@ -254,15 +300,6 @@ QDebug operator<<(QDebug ts, const Column &col) return ts << "(p: " << col.physical << ", l: " << col.logical << ")"; } -struct CursorPosition -{ - // for jump history - CursorPosition() : position(-1), scrollLine(-1) {} - CursorPosition(int pos, int line) : position(pos), scrollLine(line) {} - int position; // Position in document - int scrollLine; // First visible line -}; - struct Register { Register() : rangemode(RangeCharMode) {} @@ -282,21 +319,26 @@ struct SearchData SearchData() { forward = true; - mustMove = true; highlightMatches = true; - highlightCursor = true; } QString needle; bool forward; - bool mustMove; bool highlightMatches; - bool highlightCursor; }; +// If string begins with given prefix remove it with trailing spaces and return true. +static bool eatString(const QString &prefix, QString *str) +{ + if (!str->startsWith(prefix)) + return false; + *str = str->mid(prefix.size()).trimmed(); + return true; +} + static QRegExp vimPatternToQtPattern(QString needle, bool smartcase) { - /* Trasformations (Vim regexp -> QRegExp): + /* Transformations (Vim regexp -> QRegExp): * \a -> [A-Za-z] * \A -> [^A-Za-z] * \h -> [A-Za-z_] @@ -331,6 +373,8 @@ static QRegExp vimPatternToQtPattern(QString needle, bool smartcase) bool escape = false; bool brace = false; + bool embraced = false; + bool range = false; bool curly = false; foreach (const QChar &c, needle) { if (brace) { @@ -338,11 +382,35 @@ static QRegExp vimPatternToQtPattern(QString needle, bool smartcase) if (c == ']') { pattern.append(_("\\[\\]")); continue; - } else { - pattern.append('['); } + pattern.append('['); + escape = true; + embraced = true; } - if (QString("(){}+|?").indexOf(c) != -1) { + if (embraced) { + if (range) { + QChar c2 = pattern[pattern.size() - 2]; + pattern.remove(pattern.size() - 2, 2); + pattern.append(c2.toUpper() + '-' + c.toUpper()); + pattern.append(c2.toLower() + '-' + c.toLower()); + range = false; + } else if (escape) { + escape = false; + pattern.append(c); + } else if (c == '\\') { + escape = true; + } else if (c == ']') { + pattern.append(']'); + embraced = false; + } else if (c == '-') { + range = ignorecase && pattern[pattern.size() - 1].isLetter(); + pattern.append('-'); + } else if (c.isLetter() && ignorecase) { + pattern.append(c.toLower()).append(c.toUpper()); + } else { + pattern.append(c); + } + } else if (QString("(){}+|?").indexOf(c) != -1) { if (c == '{') { curly = escape; } else if (c == '}' && curly) { @@ -410,6 +478,146 @@ static QRegExp vimPatternToQtPattern(QString needle, bool smartcase) return QRegExp(pattern); } +static bool afterEndOfLine(const QTextDocument *doc, int position) +{ + return doc->characterAt(position) == ParagraphSeparator + && doc->findBlock(position).length() > 1; +} + +static void searchForward(QTextCursor *tc, QRegExp &needleExp, int *repeat) +{ + const QTextDocument *doc = tc->document(); + const int startPos = tc->position(); + + // Search from beginning of line so that matched text is the same. + tc->movePosition(StartOfLine); + + // forward to current position + *tc = doc->find(needleExp, *tc); + while (!tc->isNull() && tc->anchor() < startPos) { + if (!tc->hasSelection()) + tc->movePosition(Right); + if (tc->atBlockEnd()) + tc->movePosition(Right); + *tc = doc->find(needleExp, *tc); + } + + if (tc->isNull()) + return; + + --*repeat; + + while (*repeat > 0) { + if (!tc->hasSelection()) + tc->movePosition(Right); + if (tc->atBlockEnd()) + tc->movePosition(Right); + *tc = doc->find(needleExp, *tc); + if (tc->isNull()) + return; + --*repeat; + } + + if (!tc->isNull() && afterEndOfLine(doc, tc->anchor())) + tc->movePosition(Left); +} + +static void searchBackward(QTextCursor *tc, QRegExp &needleExp, int *repeat) +{ + // Search from beginning of line so that matched text is the same. + QTextBlock block = tc->block(); + QString line = block.text(); + + int i = line.indexOf(needleExp, 0); + while (i != -1 && i < tc->positionInBlock()) { + --*repeat; + i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); + if (i == line.size()) + i = -1; + } + + if (i == tc->positionInBlock()) + --*repeat; + + while (*repeat > 0) { + block = block.previous(); + if (!block.isValid()) + break; + line = block.text(); + i = line.indexOf(needleExp, 0); + while (i != -1) { + --*repeat; + i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); + if (i == line.size()) + i = -1; + } + } + + if (!block.isValid()) { + *tc = QTextCursor(); + return; + } + + i = line.indexOf(needleExp, 0); + while (*repeat < 0) { + i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); + ++*repeat; + } + tc->setPosition(block.position() + i); +} + +static bool substituteText(QString *text, QRegExp &pattern, const QString &replacement, + bool global) +{ + bool substituted = false; + int pos = 0; + while (true) { + pos = pattern.indexIn(*text, pos, QRegExp::CaretAtZero); + if (pos == -1) + break; + substituted = true; + QString matched = text->mid(pos, pattern.cap(0).size()); + QString repl; + bool escape = false; + // insert captured texts + for (int i = 0; i < replacement.size(); ++i) { + const QChar &c = replacement[i]; + if (escape) { + escape = false; + if (c.isDigit()) { + if (c.digitValue() <= pattern.captureCount()) + repl += pattern.cap(c.digitValue()); + } else { + repl += c; + } + } else { + if (c == '\\') + escape = true; + else if (c == '&') + repl += pattern.cap(0); + else + repl += c; + } + } + text->replace(pos, matched.size(), repl); + pos += qMax(1, repl.size()); + + if (pos >= text->size() || !global) + break; + } + + return substituted; +} + +static int findUnescaped(QChar c, const QString &line, int from) +{ + for (int i = from; i < line.size(); ++i) { + if (line.at(i) == c && (i == 0 || line.at(i - 1) != '\\')) + return i; + } + return -1; +} + static void setClipboardData(const QString &content, RangeMode mode, QClipboard::Mode clipboardMode) { @@ -433,6 +641,94 @@ static void setClipboardData(const QString &content, RangeMode mode, clipboard->setMimeData(data, clipboardMode); } +static const QMap<QString, int> &vimKeyNames() +{ + static QMap<QString, int> k; + if (!k.isEmpty()) + return k; + + // FIXME: Should be value of mapleader. + k.insert("LEADER", Key_Backslash); + + k.insert("SPACE", Key_Space); + k.insert("TAB", Key_Tab); + k.insert("NL", Key_Return); + k.insert("NEWLINE", Key_Return); + k.insert("LINEFEED", Key_Return); + k.insert("LF", Key_Return); + k.insert("CR", Key_Return); + k.insert("RETURN", Key_Return); + k.insert("ENTER", Key_Return); + k.insert("BS", Key_Backspace); + k.insert("BACKSPACE", Key_Backspace); + k.insert("ESC", Key_Escape); + k.insert("BAR", Key_Bar); + k.insert("BSLASH", Key_Backslash); + k.insert("DEL", Key_Delete); + k.insert("DELETE", Key_Delete); + k.insert("KDEL", Key_Delete); + k.insert("UP", Key_Up); + k.insert("DOWN", Key_Down); + k.insert("LEFT", Key_Left); + k.insert("RIGHT", Key_Right); + + k.insert("F1", Key_F1); + k.insert("F2", Key_F2); + k.insert("F3", Key_F3); + k.insert("F4", Key_F4); + k.insert("F5", Key_F5); + k.insert("F6", Key_F6); + k.insert("F7", Key_F7); + k.insert("F8", Key_F8); + k.insert("F9", Key_F9); + k.insert("F10", Key_F10); + + k.insert("F11", Key_F11); + k.insert("F12", Key_F12); + k.insert("F13", Key_F13); + k.insert("F14", Key_F14); + k.insert("F15", Key_F15); + k.insert("F16", Key_F16); + k.insert("F17", Key_F17); + k.insert("F18", Key_F18); + k.insert("F19", Key_F19); + k.insert("F20", Key_F20); + + k.insert("F21", Key_F21); + k.insert("F22", Key_F22); + k.insert("F23", Key_F23); + k.insert("F24", Key_F24); + k.insert("F25", Key_F25); + k.insert("F26", Key_F26); + k.insert("F27", Key_F27); + k.insert("F28", Key_F28); + k.insert("F29", Key_F29); + k.insert("F30", Key_F30); + + k.insert("F31", Key_F31); + k.insert("F32", Key_F32); + k.insert("F33", Key_F33); + k.insert("F34", Key_F34); + k.insert("F35", Key_F35); + + k.insert("INSERT", Key_Insert); + k.insert("INS", Key_Insert); + k.insert("KINSERT", Key_Insert); + k.insert("HOME", Key_Home); + k.insert("END", Key_End); + k.insert("PAGEUP", Key_PageUp); + k.insert("PAGEDOWN", Key_PageDown); + + k.insert("KPLUS", Key_Plus); + k.insert("KMINUS", Key_Minus); + k.insert("KDIVIDE", Key_Slash); + k.insert("KMULTIPLY", Key_Asterisk); + k.insert("KENTER", Key_Enter); + k.insert("KPOINT", Key_Period); + + return k; +} + Range::Range() : beginPos(-1), endPos(-1), rangemode(RangeCharMode) @@ -463,17 +759,6 @@ bool ExCommand::matches(const QString &min, const QString &full) const return cmd.startsWith(min) && full.startsWith(cmd); } -void ExCommand::setContentsFromLine(const QString &line) -{ - cmd = line.section(' ', 0, 0); - args = line.mid(cmd.size() + 1).trimmed(); - while (cmd.startsWith(QLatin1Char(':'))) - cmd.remove(0, 1); - hasBang = cmd.endsWith('!'); - if (hasBang) - cmd.chop(1); -} - QDebug operator<<(QDebug ts, const ExCommand &cmd) { return ts << cmd.cmd << ' ' << cmd.args << ' ' << cmd.range; @@ -528,9 +813,15 @@ public: : m_key(0), m_xkey(0), m_modifiers(0) {} explicit Input(QChar x) - : m_key(x.unicode()), m_xkey(x.unicode()), m_modifiers(0), m_text(x) {} + : m_key(x.unicode()), m_xkey(x.unicode()), m_modifiers(0), m_text(x) + { + if (x.isUpper()) + m_modifiers = Qt::ShiftModifier; + else if (x.isLower()) + m_key = x.toUpper().unicode(); + } - Input(int k, int m, const QString &t) + Input(int k, int m, const QString &t = QString()) : m_key(k), m_modifiers(cleanModifier(m)), m_text(t) { // On Mac, QKeyEvent::text() returns non-empty strings for @@ -539,10 +830,22 @@ public: // FIXME: Check the real conditions. if (m_text.size() == 1 && m_text.at(0).unicode() < ' ') m_text.clear(); + + // Set text only if input is ascii key without control modifier. + if (m_text.isEmpty() && k <= 0x7f && (m & (HostOsInfo::controlModifier())) == 0) { + QChar c = QChar::fromAscii(k); + m_text = QString((m & ShiftModifier) != 0 ? c.toUpper() : c.toLower()); + } + // m_xkey is only a cache. m_xkey = (m_text.size() == 1 ? m_text.at(0).unicode() : m_key); } + bool isValid() const + { + return m_key != 0 || !m_text.isNull(); + } + bool isDigit() const { return m_xkey >= '0' && m_xkey <= '9'; @@ -560,7 +863,7 @@ public: bool isReturn() const { - return m_key == Key_Return || m_key == Key_Enter; + return m_key == '\n' || m_key == Key_Return || m_key == Key_Enter; } bool isEscape() const @@ -571,12 +874,12 @@ public: bool is(int c) const { - return m_xkey == c && m_modifiers != RealControlModifier; + return m_xkey == c && m_modifiers != int(HostOsInfo::controlModifier()); } bool isControl(int c) const { - return m_modifiers == RealControlModifier + return m_modifiers == int(HostOsInfo::controlModifier()) && (m_xkey == c || m_xkey + 32 == c || m_xkey + 64 == c || m_xkey + 96 == c); } @@ -585,16 +888,20 @@ public: return m_modifiers == Qt::ShiftModifier && m_xkey == c; } - bool operator==(const Input &a) const + bool operator<(const Input &a) const { - return a.m_key == m_key && a.m_modifiers == m_modifiers - && m_text == a.m_text; + if (m_key != a.m_key) + return m_key < a.m_key; + // Text for some mapped key cannot be determined (e.g. <C-J>) so if text is not set for + // one of compared keys ignore it. + if (!m_text.isEmpty() && !a.m_text.isEmpty()) + return m_text < a.m_text; + return m_modifiers < a.m_modifiers; } - // Ignore e.g. ShiftModifier, which is not available in sourced data. - bool matchesForMap(const Input &a) const + bool operator==(const Input &a) const { - return (a.m_key == m_key || a.m_xkey == m_xkey) && m_text == a.m_text; + return !(*this < a || a < *this); } bool operator!=(const Input &a) const { return !operator==(a); } @@ -617,6 +924,17 @@ public: return m_key; } + QString toString() const + { + bool hasCtrl = m_modifiers & int(HostOsInfo::controlModifier()); + QString key = vimKeyNames().key(m_key); + if (key.isEmpty()) + key = QChar(m_xkey); + else + key = '<' + key + '>'; + return (hasCtrl ? QString("^") : QString()) + key; + } + QDebug dump(QDebug ts) const { return ts << m_key << '-' << m_modifiers << '-' @@ -629,87 +947,194 @@ private: QString m_text; }; +// mapping to <Nop> (do nothing) +static const Input Nop(-1, -1, QString()); + QDebug operator<<(QDebug ts, const Input &input) { return input.dump(ts); } class Inputs : public QVector<Input> { public: - Inputs() {} - explicit Inputs(const QString &str) { parseFrom(str); } + Inputs() : m_noremap(true), m_silent(false) {} + + explicit Inputs(const QString &str, bool noremap = true, bool silent = false) + : m_noremap(noremap), m_silent(silent) + { + parseFrom(str); + } + + bool noremap() const { return m_noremap; } + + bool silent() const { return m_silent; } + +private: void parseFrom(const QString &str); + + bool m_noremap; + bool m_silent; }; -static bool iss(char a, char b) +static Input parseVimKeyName(const QString &keyName) { - if (a >= 'a') - a -= 'a' - 'A'; - if (b >= 'a') - b -= 'a' - 'A'; - return a == b; + if (keyName.length() == 1) + return Input(keyName.at(0)); + + const QStringList keys = keyName.split('-'); + const int len = keys.length(); + + if (len == 1 && keys.at(0) == _("nop")) + return Nop; + + int mods = NoModifier; + for (int i = 0; i < len - 1; ++i) { + const QString &key = keys[i].toUpper(); + if (key == "S") + mods |= Qt::ShiftModifier; + else if (key == "C") + mods |= HostOsInfo::controlModifier(); + else + return Input(); + } + + if (!keys.isEmpty()) { + const QString key = keys.last(); + if (key.length() == 1) { + // simple character + QChar c = key.at(0).toUpper(); + return Input(c.unicode(), mods); + } + + // find key name + QMap<QString, int>::ConstIterator it = vimKeyNames().constFind(key.toUpper()); + if (it != vimKeyNames().end()) + return Input(*it, mods); + } + + return Input(); } void Inputs::parseFrom(const QString &str) { const int n = str.size(); for (int i = 0; i < n; ++i) { - uint c0 = str.at(i).unicode(), c1 = 0, c2 = 0, c3 = 0, c4 = 0; - if (i + 1 < n) - c1 = str.at(i + 1).unicode(); - if (i + 2 < n) - c2 = str.at(i + 2).unicode(); - if (i + 3 < n) - c3 = str.at(i + 3).unicode(); - if (i + 4 < n) - c4 = str.at(i + 4).unicode(); - if (c0 == '<') { - if (iss(c1, 'C') && c2 == '-' && c4 == '>') { - uint c = (c3 < 90 ? c3 : c3 - 32); - append(Input(c, RealControlModifier, QString(QChar(c - 64)))); - i += 4; - } else if (iss(c1, 'C') && iss(c2, 'R') && c3 == '>') { - append(Input(Key_Return, Qt::NoModifier, QString(QChar(13)))); - i += 3; - } else if (iss(c1, 'E') && iss(c2, 'S') && iss(c3, 'C') && c4 == '>') { - append(Input(Key_Escape, Qt::NoModifier, QString(QChar(27)))); - i += 4; + uint c = str.at(i).unicode(); + if (c == '<') { + int j = str.indexOf('>', i); + Input input; + if (j != -1) { + const QString key = str.mid(i+1, j - i - 1); + if (!key.contains('<')) + input = parseVimKeyName(key); + } + if (input.isValid()) { + append(input); + i = j; } else { - append(Input(QLatin1Char(c0))); + append(Input(QLatin1Char(c))); } } else { - append(Input(QLatin1Char(c0))); + append(Input(QLatin1Char(c))); } } } -// This wraps a string and a "cursor position". +class History +{ +public: + History() : m_items(QString()), m_index(0) {} + void append(const QString &item); + const QString &move(const QStringRef &prefix, int skip); + const QString ¤t() const { return m_items[m_index]; } + const QStringList &items() const { return m_items; } + void restart() { m_index = m_items.size() - 1; } + +private: + // Last item is always empty or current search prefix. + QStringList m_items; + int m_index; +}; + +void History::append(const QString &item) +{ + if (item.isEmpty()) + return; + m_items.pop_back(); + m_items.removeAll(item); + m_items << item << QString(); + restart(); +} + +const QString &History::move(const QStringRef &prefix, int skip) +{ + if (!current().startsWith(prefix)) + restart(); + + if (m_items.last() != prefix) + m_items[m_items.size() - 1] = prefix.toString(); + + int i = m_index + skip; + if (!prefix.isEmpty()) + for (; i >= 0 && i < m_items.size() && !m_items[i].startsWith(prefix); i += skip); + if (i >= 0 && i < m_items.size()) + m_index = i; + + return current(); +} + +// Command line buffer with prompt (i.e. :, / or ? characters), text contents and cursor position. class CommandBuffer { public: - CommandBuffer() : m_pos(0) {} + CommandBuffer() : m_pos(0), m_userPos(0), m_historyAutoSave(true) {} - void clear() { m_buffer.clear(); m_pos = 0; } + void setPrompt(const QChar &prompt) { m_prompt = prompt; } void setContents(const QString &s) { m_buffer = s; m_pos = s.size(); } - QString contents() const { return m_buffer; } + + void setContents(const QString &s, int pos) { m_buffer = s; m_pos = m_userPos = pos; } + + QStringRef userContents() const { return m_buffer.leftRef(m_userPos); } + const QChar &prompt() const { return m_prompt; } + const QString &contents() const { return m_buffer; } bool isEmpty() const { return m_buffer.isEmpty(); } int cursorPos() const { return m_pos; } - void insertChar(QChar c) { m_buffer.insert(m_pos++, c); } - void insertText(const QString &s) { m_buffer.insert(m_pos, s); m_pos += s.size(); } - void deleteChar() { if (m_pos) m_buffer.remove(--m_pos, 1); } + void insertChar(QChar c) { m_buffer.insert(m_pos++, c); m_userPos = m_pos; } + void insertText(const QString &s) + { + m_buffer.insert(m_pos, s); m_userPos = m_pos = m_pos + s.size(); + } + void deleteChar() { if (m_pos) m_buffer.remove(--m_pos, 1); m_userPos = m_pos; } + + void moveLeft() { if (m_pos) m_userPos = --m_pos; } + void moveRight() { if (m_pos < m_buffer.size()) m_userPos = ++m_pos; } + void moveStart() { m_userPos = m_pos = 0; } + void moveEnd() { m_userPos = m_pos = m_buffer.size(); } - void moveLeft() { if (m_pos) --m_pos; } - void moveRight() { if (m_pos < m_buffer.size()) ++m_pos; } - void moveStart() { m_pos = 0; } - void moveEnd() { m_pos = m_buffer.size(); } + void setHistoryAutoSave(bool autoSave) { m_historyAutoSave = autoSave; } + void historyDown() { setContents(m_history.move(userContents(), 1)); } + void historyUp() { setContents(m_history.move(userContents(), -1)); } + const QStringList &historyItems() const { return m_history.items(); } + void historyPush(const QString &item = QString()) + { + m_history.append(item.isNull() ? contents() : item); + } + + void clear() + { + if (m_historyAutoSave) + historyPush(); + m_buffer.clear(); + m_userPos = m_pos = 0; + } QString display() const { - QString msg; + QString msg(m_prompt); for (int i = 0; i != m_buffer.size(); ++i) { const QChar c = m_buffer.at(i); if (c.unicode() < 32) { msg += '^'; - msg += QChar(c.unicode() + 64); + msg += QLatin1Char(c.unicode() + 64); } else { msg += c; } @@ -730,6 +1155,8 @@ public: } else if (input.isKey(Key_Delete)) { if (m_pos < m_buffer.size()) m_buffer.remove(m_pos, 1); + else + deleteChar(); } else if (!input.text().isEmpty()) { insertText(input.text()); } else { @@ -740,100 +1167,155 @@ public: private: QString m_buffer; + QChar m_prompt; + History m_history; int m_pos; + int m_userPos; // last position of inserted text (for retrieving history items) + bool m_historyAutoSave; // store items to history on clear()? }; - -class History +// Mappings for a specific mode (trie structure) +class ModeMapping : public QMap<Input, ModeMapping> { public: - History() : m_index(0) {} - void append(const QString &item); - void down() { m_index = qMin(m_index + 1, m_items.size()); } - void up() { m_index = qMax(m_index - 1, 0); } - void restart() { m_index = m_items.size(); } - QString current() const { return m_items.value(m_index, QString()); } - QStringList items() const { return m_items; } - + const Inputs &value() const { return m_value; } + void setValue(const Inputs &value) { m_value = value; } private: - QStringList m_items; - int m_index; + Inputs m_value; }; -void History::append(const QString &item) -{ - if (item.isEmpty()) - return; - m_items.removeAll(item); - m_items.append(item); m_index = m_items.size() - 1; -} +// Mappings for all modes +typedef QHash<char, ModeMapping> Mappings; -// Mappings for a specific mode. -class ModeMapping : public QList<QPair<Inputs, Inputs> > +// Iterator for mappings +class MappingsIterator : public QVector<ModeMapping::Iterator> { public: - ModeMapping() { test(); } - - void test() + MappingsIterator(Mappings *mappings, char mode = -1, const Inputs &inputs = Inputs()) + : m_parent(mappings) { - //insert(Inputs() << Input('A') << Input('A'), - // Inputs() << Input('x') << Input('x')); + reset(mode); + walk(inputs); } - void insert(const Inputs &from, const Inputs &to) + // Reset iterator state. Keep previous mode if 0. + void reset(char mode = 0) { - for (int i = 0; i != size(); ++i) - if (at(i).first == from) { - (*this)[i].second = to; - return; - } - append(QPair<Inputs, Inputs>(from, to)); + clear(); + m_lastValid = -1; + m_invalidInputCount = 0; + if (mode != 0) { + m_mode = mode; + if (mode != -1) + m_modeMapping = m_parent->find(mode); + } } - void remove(const Inputs &from) - { - for (int i = 0; i != size(); ++i) - if (at(i).first == from) { - removeAt(i); - return; - } - } + bool isValid() const { return !empty(); } + + // Return true if mapping can be extended. + bool canExtend() const { return isValid() && !last()->empty(); } + + // Return true if this mapping can be used. + bool isComplete() const { return m_lastValid != -1; } + + // Return size of current map. + int mapLength() const { return m_lastValid + 1; } + + int invalidInputCount() const { return m_invalidInputCount; } - // Returns 'false' if more input is needed to decide whether a mapping - // needs to be applied. If a decision can be made, return 'true', - // and replace *input with the mapped data. - bool mappingDone(Inputs *inputs) const + bool walk(const Input &input) { - // FIXME: inefficient. - for (int i = 0; i != size(); ++i) { - const Inputs &haystack = at(i).first; - // A mapping - if (couldTriggerMap(haystack, *inputs)) { - if (haystack.size() != inputs->size()) - return false; // This can be extended. - // Actual mapping. - *inputs = at(i).second; - return true; - } + if (m_modeMapping == m_parent->end()) + return false; + + if (!input.isValid()) { + m_invalidInputCount += 1; + return true; + } + + ModeMapping::Iterator it; + if (isValid()) { + it = last()->find(input); + if (it == last()->end()) + return false; + } else { + it = m_modeMapping->find(input); + if (it == m_modeMapping->end()) + return false; } - // No extensible mapping found. Use inputs as-is. + + if (!it->value().isEmpty()) + m_lastValid = size(); + append(it); + return true; } -private: - static bool couldTriggerMap(const Inputs &haystack, const Inputs &needle) + bool walk(const Inputs &inputs) { - // Input is already too long. - if (needle.size() > haystack.size()) - return false; - for (int i = 0; i != needle.size(); ++i) { - if (!needle.at(i).matchesForMap(haystack.at(i))) + foreach (const Input &input, inputs) { + if (!walk(input)) return false; } return true; } + + // Return current mapped value. Iterator must be valid. + const Inputs &inputs() const + { + return at(m_lastValid)->value(); + } + + void remove() + { + if (isValid()) { + if (canExtend()) { + last()->setValue(Inputs()); + } else { + if (size() > 1) { + while (last()->empty()) { + at(size() - 2)->erase(last()); + pop_back(); + if (size() == 1 || !last()->value().isEmpty()) + break; + } + if (last()->empty() && last()->value().isEmpty()) + m_modeMapping->erase(last()); + } else if (last()->empty() && !last()->value().isEmpty()) { + m_modeMapping->erase(last()); + } + } + } + } + + void setInputs(const Inputs &key, const Inputs &inputs, bool unique = false) + { + ModeMapping *current = &(*m_parent)[m_mode]; + foreach (const Input &input, key) + current = &(*current)[input]; + if (!unique || current->value().isEmpty()) + current->setValue(inputs); + } + +private: + Mappings *m_parent; + Mappings::Iterator m_modeMapping; + int m_lastValid; + int m_invalidInputCount; + char m_mode; }; +// state of current mapping +struct MappingState { + MappingState() + : maxMapDepth(1000), noremap(false), silent(false) {} + MappingState(int depth, bool noremap, bool silent) + : maxMapDepth(depth), noremap(noremap), silent(silent) {} + int maxMapDepth; + bool noremap; + bool silent; +}; class FakeVimHandler::Private : public QObject { @@ -844,6 +1326,10 @@ public: EventResult handleEvent(QKeyEvent *ev); bool wantsOverride(QKeyEvent *ev); + bool parseExCommmand(QString *line, ExCommand *cmd); + bool parseLineRange(QString *line, ExCommand *cmd); + int parseLineAddress(QString *cmd); + void parseRangeCount(const QString &line, Range *range) const; void handleCommand(const QString &cmd); // Sets m_tc + handleExCommand void handleExCommand(const QString &cmd); @@ -855,26 +1341,49 @@ public: friend class FakeVimHandler; void init(); - EventResult handleKey(const Input &); - Q_SLOT EventResult handleKey2(); + void focus(); + + EventResult handleKey(const Input &input); + EventResult handleDefaultKey(const Input &input); + void handleMappedKeys(); + void unhandleMappedKeys(); EventResult handleInsertMode(const Input &); EventResult handleReplaceMode(const Input &); + EventResult handleCommandMode(const Input &); - EventResult handleCommandMode1(const Input &); - EventResult handleCommandMode2(const Input &); - EventResult handleRegisterMode(const Input &); + + // return true only if input in current mode and sub-mode was correctly handled + bool handleEscape(); + bool handleNoSubMode(const Input &); + bool handleChangeDeleteSubModes(const Input &); + bool handleReplaceSubMode(const Input &); + bool handleFilterSubMode(const Input &); + bool handleRegisterSubMode(const Input &); + bool handleShiftSubMode(const Input &); + bool handleChangeCaseSubMode(const Input &); + bool handleWindowSubMode(const Input &); + bool handleYankSubMode(const Input &); + bool handleZSubMode(const Input &); + bool handleCapitalZSubMode(const Input &); + bool handleOpenSquareSubMode(const Input &); + bool handleCloseSquareSubMode(const Input &); + + bool handleMovement(const Input &); + EventResult handleExMode(const Input &); - EventResult handleOpenSquareSubMode(const Input &); - EventResult handleCloseSquareSubMode(const Input &); EventResult handleSearchSubSubMode(const Input &); - EventResult handleCommandSubSubMode(const Input &); - void finishMovement(const QString &dotCommand = QString()); - void finishMovement(const QString &dotCommand, int count); + bool handleCommandSubSubMode(const Input &); + void fixSelection(); // Fix selection according to current range, move and command modes. + void finishMovement(const QString &dotCommandMovement = QString()); + void finishMovement(const QString &dotCommandMovement, int count); void resetCommandMode(); - void search(const SearchData &sd); + QTextCursor search(const SearchData &sd, int startPos, int count, bool showMessages); + void search(const SearchData &sd, bool showMessages = true); + void searchNext(bool forward = true); void searchBalanced(bool forward, QChar needle, QChar other); void highlightMatches(const QString &needle); void stopIncrementalFind(); + void updateFind(bool isComplete); int mvCount() const { return m_mvcount.isEmpty() ? 1 : m_mvcount.toInt(); } int opCount() const { return m_opcount.isEmpty() ? 1 : m_opcount.toInt(); } @@ -882,17 +1391,29 @@ public: QTextBlock block() const { return cursor().block(); } int leftDist() const { return position() - block().position(); } int rightDist() const { return block().length() - leftDist() - 1; } + bool atBlockStart() const { return cursor().atBlockStart(); } bool atBlockEnd() const { return cursor().atBlockEnd(); } bool atEndOfLine() const { return atBlockEnd() && block().length() > 1; } - - int lastPositionInDocument() const; // Returns last valid position in doc. - int firstPositionInLine(int line) const; // 1 based line, 0 based pos - int lastPositionInLine(int line) const; // 1 based line, 0 based pos + bool atDocumentEnd() const { return position() >= lastPositionInDocument(); } + bool atDocumentStart() const { return cursor().atStart(); } + + bool atEmptyLine(const QTextCursor &tc = QTextCursor()) const; + bool atBoundary(bool end, bool simple, bool onlyWords = false, + const QTextCursor &tc = QTextCursor()) const; + bool atWordBoundary(bool end, bool simple, const QTextCursor &tc = QTextCursor()) const; + bool atWordStart(bool simple, const QTextCursor &tc = QTextCursor()) const; + bool atWordEnd(bool simple, const QTextCursor &tc = QTextCursor()) const; + bool isFirstNonBlankOnLine(int pos); + + int lastPositionInDocument(bool ignoreMode = false) const; // Returns last valid position in doc. + int firstPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos + int lastPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos int lineForPosition(int pos) const; // 1 based line, 0 based pos QString lineContents(int line) const; // 1 based line void setLineContents(int line, const QString &contents); // 1 based line int blockBoundary(const QString &left, const QString &right, bool end, int count) const; // end or start position of current code block + int lineNumber(const QTextBlock &block) const; int linesOnScreen() const; int columnsOnScreen() const; @@ -901,6 +1422,7 @@ public: // The following use all zero-based counting. int cursorLineOnScreen() const; int cursorLine() const; + int cursorBlockNumber() const; // "." address int physicalCursorColumn() const; // as stored in the data int logicalCursorColumn() const; // as visible on screen int physicalToLogicalColumn(int physical, const QString &text) const; @@ -910,11 +1432,11 @@ public: void scrollToLine(int line); void scrollUp(int count); void scrollDown(int count) { scrollUp(-count); } + void alignViewportToCursor(Qt::AlignmentFlag align, int line = -1, + bool moveToNonBlank = false); - CursorPosition cursorPosition() const - { return CursorPosition(position(), firstVisibleLine()); } - void setCursorPosition(const CursorPosition &p) - { setPosition(p.position); scrollToLine(p.scrollLine); } + void setCursorPosition(const CursorPosition &p); + void setCursorPosition(QTextCursor *tc, const CursorPosition &p); // Helper functions for indenting/ bool isElectricCharacter(QChar c) const; @@ -924,15 +1446,25 @@ public: void shiftRegionRight(int repeat = 1); void moveToFirstNonBlankOnLine(); + void moveToFirstNonBlankOnLine(QTextCursor *tc); void moveToTargetColumn(); void setTargetColumn() { m_targetColumn = logicalCursorColumn(); m_visualTargetColumn = m_targetColumn; //qDebug() << "TARGET: " << m_targetColumn; } - void moveToNextWord(bool simple, bool deleteWord = false); void moveToMatchingParanthesis(); - void moveToWordBoundary(bool simple, bool forward, bool changeWord = false); + void moveToBoundary(bool simple, bool forward = true); + void moveToNextBoundary(bool end, int count, bool simple, bool forward); + void moveToNextBoundaryStart(int count, bool simple, bool forward = true); + void moveToNextBoundaryEnd(int count, bool simple, bool forward = true); + void moveToBoundaryStart(int count, bool simple, bool forward = true); + void moveToBoundaryEnd(int count, bool simple, bool forward = true); + void moveToNextWord(bool end, int count, bool simple, bool forward, bool emptyLines); + void moveToNextWordStart(int count, bool simple, bool forward = true, bool emptyLines = true); + void moveToNextWordEnd(int count, bool simple, bool forward = true, bool emptyLines = true); + void moveToWordStart(int count, bool simple, bool forward = true, bool emptyLines = true); + void moveToWordEnd(int count, bool simple, bool forward = true, bool emptyLines = true); // Convenience wrappers to reduce line noise. void moveToStartOfLine(); @@ -951,6 +1483,8 @@ public: QTextCursor tc = cursor(); tc.movePosition(Right, KeepAnchor, n); setCursor(tc); + if (atEndOfLine()) + emit q->fold(1, false); //dump("RIGHT 2"); } void moveLeft(int n = 1) { @@ -980,30 +1514,34 @@ public: tc.setPosition(position, KeepAnchor); setCursor(tc); } - QTextCursor cursor() const { return EDITOR(textCursor()); } - void setCursor(const QTextCursor &tc) { - // Workaround for crash when in edit block and adding text to last empty line. - if (m_editBlockLevel > 0) - cursor().endEditBlock(); - EDITOR(setTextCursor(tc)); + + // Workaround for occational crash when setting text cursor while in edit block. + QTextCursor m_cursor; + + QTextCursor cursor() const { if (m_editBlockLevel > 0) - cursor().joinPreviousEditBlock(); + return m_cursor; + return EDITOR(textCursor()); } - bool handleFfTt(QString key); + void setCursor(const QTextCursor &tc) { + m_cursor = tc; + if (m_editBlockLevel == 0) + EDITOR(setTextCursor(tc)); + } - // Helper function for handleExCommand returning 1 based line index. - int readLineCode(QString &cmd); + bool handleFfTt(QString key); void enterInsertMode(); void enterReplaceMode(); - void enterCommandMode(); - void enterExMode(); - void showRedMessage(const QString &msg); - void showBlackMessage(const QString &msg); + void enterCommandMode(Mode returnToMode = CommandMode); + void enterExMode(const QString &contents = QString()); + void showMessage(MessageLevel level, const QString &msg); + void clearMessage() { showMessage(MessageInfo, QString()); } void notImplementedYet(); void updateMiniBuffer(); void updateSelection(); + void updateHighlights(); void updateCursorShape(); QWidget *editor() const; QTextDocument *document() const { return EDITOR(document()); } @@ -1011,54 +1549,33 @@ public: { return document()->characterAt(position()); } int m_editBlockLevel; // current level of edit blocks - - void beginEditBlock() - { - UNDO_DEBUG("BEGIN EDIT BLOCK"); - ++m_editBlockLevel; - cursor().beginEditBlock(); - } - void endEditBlock() - { - UNDO_DEBUG("END EDIT BLOCK"); - QTC_ASSERT(m_editBlockLevel > 0, - qDebug() << "beginEditBlock() not called before endEditBlock()!"; return); - --m_editBlockLevel; - cursor().endEditBlock(); - } - void joinPreviousEditBlock() - { - UNDO_DEBUG("JOIN"); - ++m_editBlockLevel; - cursor().joinPreviousEditBlock(); - } - void breakEditBlock() { - QTextCursor tc = cursor(); - tc.clearSelection(); - tc.beginEditBlock(); - tc.insertText("x"); - tc.deletePreviousChar(); - tc.endEditBlock(); - setCursor(tc); - } + void joinPreviousEditBlock(); + void beginEditBlock(bool rememberPosition = true); + void beginLargeEditBlock() { beginEditBlock(false); } + void endEditBlock(); + void breakEditBlock() { m_breakEditBlock = true; } bool isVisualMode() const { return m_visualMode != NoVisualMode; } bool isNoVisualMode() const { return m_visualMode == NoVisualMode; } bool isVisualCharMode() const { return m_visualMode == VisualCharMode; } bool isVisualLineMode() const { return m_visualMode == VisualLineMode; } bool isVisualBlockMode() const { return m_visualMode == VisualBlockMode; } + char currentModeCode() const; void updateEditor(); + void selectTextObject(bool simple, bool inner); void selectWordTextObject(bool inner); void selectWORDTextObject(bool inner); void selectSentenceTextObject(bool inner); void selectParagraphTextObject(bool inner); - void selectBlockTextObject(bool inner, char left, char right); - void changeNumberTextObject(bool doIncrement); - void selectQuotedStringTextObject(bool inner, const QString "e); + void changeNumberTextObject(int count); + // return true only if cursor is in a block delimited with correct characters + bool selectBlockTextObject(bool inner, char left, char right); + bool selectQuotedStringTextObject(bool inner, const QString "e); Q_SLOT void importSelection(); void exportSelection(); + void ensureCursorVisible(); void insertInInsertMode(const QString &text); public: @@ -1091,17 +1608,14 @@ public: int m_gflag; // whether current command started with 'g' - QString m_commandPrefix; - CommandBuffer m_commandBuffer; QString m_currentFileName; - QString m_currentMessage; - bool m_lastSearchForward; - bool m_findPending; int m_findStartPosition; QString m_lastInsertion; QString m_lastDeletion; + bool m_breakEditBlock; + int anchor() const { return cursor().anchor(); } int position() const { return cursor().position(); } @@ -1137,22 +1651,28 @@ public: QString selectText(const Range &range) const; void setCurrentRange(const Range &range); Range currentRange() const { return Range(position(), anchor(), m_rangemode); } - Range rangeFromCurrentLine() const; void yankText(const Range &range, int toregister = '"'); void pasteText(bool afterCursor); + void joinLines(int count, bool preserveSpace = false); + // undo handling + int revision() const { return document()->availableUndoSteps(); } + void undoRedo(bool undo); void undo(); void redo(); - void setUndoPosition(); - QMap<int, int> m_undoCursorPosition; // revision -> position + void setUndoPosition(bool overwrite = true); + // revision -> state + QStack<State> m_undo; + QStack<State> m_redo; // extra data for '.' - void replay(const QString &text, int count); + void replay(const QString &text); void setDotCommand(const QString &cmd) { g.dotCommand = cmd; } void setDotCommand(const QString &cmd, int n) { g.dotCommand = cmd.arg(n); } + QString visualDotCommand() const; // extra data for ';' QString m_semicolonCount; @@ -1163,14 +1683,14 @@ public: void toggleVisualMode(VisualMode visualMode); void leaveVisualMode(); VisualMode m_visualMode; - VisualMode m_oldVisualMode; + VisualMode m_lastVisualMode; - // marks as lines - int mark(int code) const; - void setMark(int code, int position); - typedef QHash<int, QTextCursor> Marks; - typedef QHashIterator<int, QTextCursor> MarksIterator; - Marks m_marks; + // marks + Mark mark(QChar code) const; + void setMark(QChar code, CursorPosition position); + // jump to valid mark return true if mark is valid and local + bool jumpToMark(QChar mark, bool backTickMode); + Marks m_marks; // local marks // vi style configuration QVariant config(int code) const { return theFakeVimSetting(code)->value(); } @@ -1197,23 +1717,24 @@ public: void getRegisterType(int reg, bool *isClipboard, bool *isSelection) const; void recordJump(); - QVector<CursorPosition> m_jumpListUndo; - QVector<CursorPosition> m_jumpListRedo; - int m_lastChangePosition; + void jump(int distance); + QStack<CursorPosition> m_jumpListUndo; + QStack<CursorPosition> m_jumpListRedo; + CursorPosition m_lastChangePosition; - QList<QTextEdit::ExtraSelection> m_searchSelections; + QList<QTextEdit::ExtraSelection> m_extraSelections; QTextCursor m_searchCursor; + int m_searchStartPosition; + int m_searchFromScreenLine; QString m_oldNeedle; - QString m_lastSubstituteFlags; - QRegExp m_lastSubstitutePattern; - QString m_lastSubstituteReplacement; - QTextCursor m_lastSelectionCursor; - VisualMode m_lastSelectionMode; - bool handleExCommandHelper(const ExCommand &cmd); // Returns success. + bool handleExCommandHelper(ExCommand &cmd); // Returns success. bool handleExPluginCommand(const ExCommand &cmd); // Handled by plugin? bool handleExBangCommand(const ExCommand &cmd); - bool handleExDeleteCommand(const ExCommand &cmd); + bool handleExYankDeleteCommand(const ExCommand &cmd); + bool handleExChangeCommand(const ExCommand &cmd); + bool handleExMoveCommand(const ExCommand &cmd); + bool handleExJoinCommand(const ExCommand &cmd); bool handleExGotoCommand(const ExCommand &cmd); bool handleExHistoryCommand(const ExCommand &cmd); bool handleExRegisterCommand(const ExCommand &cmd); @@ -1221,7 +1742,7 @@ public: bool handleExNohlsearchCommand(const ExCommand &cmd); bool handleExNormalCommand(const ExCommand &cmd); bool handleExReadCommand(const ExCommand &cmd); - bool handleExRedoCommand(const ExCommand &cmd); + bool handleExUndoRedoCommand(const ExCommand &cmd); bool handleExSetCommand(const ExCommand &cmd); bool handleExShiftCommand(const ExCommand &cmd); bool handleExSourceCommand(const ExCommand &cmd); @@ -1236,31 +1757,57 @@ public: signed char m_charClass[256]; bool m_ctrlVActive; + void miniBufferTextEdited(const QString &text, int cursorPos); + static struct GlobalData { GlobalData() + : mappings(), currentMap(&mappings), inputTimer(-1), currentMessageLevel(MessageInfo), + lastSearchForward(false), findPending(false), returnToMode(CommandMode) { - inputTimer = -1; + // default mapping state - shouldn't be removed + mapStates << MappingState(); + commandBuffer.setPrompt(':'); } + // Repetition. + QString dotCommand; + + QHash<int, Register> registers; + + // All mappings. + Mappings mappings; + // Input. Inputs pendingInput; + MappingsIterator currentMap; int inputTimer; + QStack<MappingState> mapStates; - // Repetition. - QString dotCommand; + // Command line buffers. + CommandBuffer commandBuffer; + CommandBuffer searchBuffer; - // History for searches. - History searchHistory; + // Current mini buffer message. + QString currentMessage; + MessageLevel currentMessageLevel; + QString currentCommand; - // History for :ex commands. - History commandHistory; + // Search state. + QString lastSearch; + bool lastSearchForward; + bool findPending; - QHash<int, Register> registers; + // Last substitution command. + QString lastSubstituteFlags; + QString lastSubstitutePattern; + QString lastSubstituteReplacement; - // All mappings. - typedef QHash<char, ModeMapping> Mappings; - Mappings mappings; + // Global marks. + Marks marks; + + // Return to insert/replace mode after single command (<C-O>). + Mode returnToMode; } g; }; @@ -1283,16 +1830,16 @@ void FakeVimHandler::Private::init() m_subsubmode = NoSubSubMode; m_passing = false; m_firstKeyPending = false; - m_findPending = false; + g.findPending = false; m_findStartPosition = -1; m_fakeEnd = false; m_positionPastEnd = false; m_anchorPastEnd = false; - m_lastSearchForward = true; + g.lastSearchForward = true; m_register = '"'; m_gflag = false; m_visualMode = NoVisualMode; - m_oldVisualMode = NoVisualMode; + m_lastVisualMode = NoVisualMode; m_targetColumn = 0; m_visualTargetColumn = 0; m_movetype = MoveInclusive; @@ -1304,12 +1851,25 @@ void FakeVimHandler::Private::init() m_oldExternalAnchor = -1; m_oldExternalPosition = -1; m_oldPosition = -1; - m_lastChangePosition = -1; + m_breakEditBlock = false; + m_searchStartPosition = 0; + m_searchFromScreenLine = 0; m_editBlockLevel = 0; setupCharClass(); } +void FakeVimHandler::Private::focus() +{ + stopIncrementalFind(); + if (g.returnToMode != CommandMode && g.currentCommand.isEmpty() && m_mode != ExMode) { + // Return to insert mode. + resetCommandMode(); + updateMiniBuffer(); + updateCursorShape(); + } +} + bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev) { const int key = ev->key(); @@ -1323,14 +1883,14 @@ bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev) if (isNoVisualMode() && m_mode == CommandMode && m_submode == NoSubMode - && m_opcount.isEmpty() - && m_mvcount.isEmpty()) + && g.currentCommand.isEmpty() + && g.returnToMode == CommandMode) return false; return true; } // We are interested in overriding most Ctrl key combinations. - if (mods == RealControlModifier + if (mods == int(HostOsInfo::controlModifier()) && !config(ConfigPassControlKey).toBool() && ((key >= Key_A && key <= Key_Z && key != Key_K) || key == Key_BracketLeft || key == Key_BracketRight)) { @@ -1413,12 +1973,11 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev) QTextCursor tc = cursor(); tc.setVisualNavigation(true); - setCursor(tc); - if (m_firstKeyPending) { m_firstKeyPending = false; recordJump(); } + setCursor(tc); if (m_fakeEnd) moveRight(); @@ -1467,7 +2026,7 @@ void FakeVimHandler::Private::installEventFilter() void FakeVimHandler::Private::setupWidget() { - enterCommandMode(); + resetCommandMode(); if (m_textedit) { m_textedit->setLineWrapMode(QTextEdit::NoWrap); } else if (m_plaintextedit) { @@ -1485,9 +2044,11 @@ void FakeVimHandler::Private::setupWidget() void FakeVimHandler::Private::exportSelection() { int pos = position(); - int anc = anchor(); + int anc = isVisualMode() ? anchor() : position(); + m_oldInternalPosition = pos; m_oldInternalAnchor = anc; + if (isVisualMode()) { if (pos >= anc) setAnchorAndPosition(anc, pos + 1); @@ -1507,18 +2068,61 @@ void FakeVimHandler::Private::exportSelection() pos = firstPositionInLine(posLine); anc = lastPositionInLine(ancLine); } + // putting cursor on folded line will unfold the line, so move the cursor a bit + if (!document()->findBlock(pos).isVisible()) + ++pos; setAnchorAndPosition(anc, pos); } else if (m_visualMode == VisualCharMode) { /* Nothing */ } else { QTC_CHECK(false); } + + setMark('<', mark('<').position); + setMark('>', mark('>').position); } else { - setAnchorAndPosition(pos, pos); + if (m_subsubmode == SearchSubSubMode && !m_searchCursor.isNull()) + setCursor(m_searchCursor); + else + setAnchorAndPosition(pos, pos); } m_oldExternalPosition = position(); m_oldExternalAnchor = anchor(); - m_oldVisualMode = m_visualMode; +} + +void FakeVimHandler::Private::ensureCursorVisible() +{ + int pos = position(); + int anc = isVisualMode() ? anchor() : position(); + + // fix selection so it is outside folded block + int start = qMin(pos, anc); + int end = qMax(pos, anc) + 1; + QTextBlock block = document()->findBlock(start); + QTextBlock block2 = document()->findBlock(end); + if (!block.isVisible() || !block2.isVisible()) { + // FIXME: Moving cursor left/right or unfolding block immediately after block is folded + // should restore cursor position inside block. + // Changing cursor position after folding is not Vim behavior so at least record the jump. + if (block.isValid() && !block.isVisible()) + recordJump(); + + pos = start; + while (block.isValid() && !block.isVisible()) + block = block.previous(); + if (block.isValid()) + pos = block.position() + qMin(m_targetColumn, block.length() - 2); + + if (isVisualMode()) { + anc = end; + while (block2.isValid() && !block2.isVisible()) { + anc = block2.position() + block2.length() - 2; + block2 = block2.next(); + } + } + + setAnchorAndPosition(anc, pos); + } } void FakeVimHandler::Private::importSelection() @@ -1529,15 +2133,12 @@ void FakeVimHandler::Private::importSelection() if (position() == m_oldExternalPosition && anchor() == m_oldExternalAnchor) { // Undo drawing correction. - m_visualMode = m_oldVisualMode; setAnchorAndPosition(m_oldInternalAnchor, m_oldInternalPosition); - //setMark('<', m_oldInternalAnchor); - //setMark('>', m_oldInternalPosition); } else { // Import new selection. Qt::KeyboardModifiers mods = QApplication::keyboardModifiers(); if (cursor().hasSelection()) { - if (mods & RealControlModifier) + if (mods & HostOsInfo::controlModifier()) m_visualMode = VisualBlockMode; else if (mods & Qt::AltModifier) m_visualMode = VisualBlockMode; @@ -1545,12 +2146,10 @@ void FakeVimHandler::Private::importSelection() m_visualMode = VisualLineMode; else m_visualMode = VisualCharMode; + m_lastVisualMode = m_visualMode; } else { m_visualMode = NoVisualMode; } - //dump("IS @"); - //setMark('<', tc.anchor()); - //setMark('>', tc.position()); } } @@ -1563,7 +2162,7 @@ void FakeVimHandler::Private::updateEditor() void FakeVimHandler::Private::restoreWidget(int tabSize) { - //showBlackMessage(QString()); + //clearMessage(); //updateMiniBuffer(); //EDITOR(removeEventFilter(q)); //EDITOR(setReadOnly(m_wasReadOnly)); @@ -1576,72 +2175,159 @@ void FakeVimHandler::Private::restoreWidget(int tabSize) m_subsubmode = NoSubSubMode; updateCursorShape(); updateSelection(); + updateHighlights(); } EventResult FakeVimHandler::Private::handleKey(const Input &input) { KEY_DEBUG("HANDLE INPUT: " << input << " MODE: " << mode); - if (m_mode == ExMode) - return handleExMode(input); - if (m_subsubmode == SearchSubSubMode) - return handleSearchSubSubMode(input); - if (m_mode == InsertMode || m_mode == ReplaceMode || m_mode == CommandMode) { + + bool handleMapped = true; + bool hasInput = input.isValid(); + + if (hasInput) g.pendingInput.append(input); - const char code = m_mode == InsertMode ? 'i' : 'n'; - if (g.mappings.value(code).mappingDone(&g.pendingInput)) - return handleKey2(); - if (g.inputTimer != -1) - killTimer(g.inputTimer); - g.inputTimer = startTimer(1000); - return EventHandled; + + // Waiting on input to complete mapping? + if (g.inputTimer != -1) { + killTimer(g.inputTimer); + g.inputTimer = -1; + // If there is a new input add it to incomplete input or + // if the mapped input can be completed complete. + if (hasInput && g.currentMap.walk(input)) { + if (g.currentMap.canExtend()) { + g.currentCommand.append(input.toString()); + updateMiniBuffer(); + g.inputTimer = startTimer(1000); + return EventHandled; + } else { + hasInput = false; + handleMappedKeys(); + } + } else if (g.currentMap.isComplete()) { + handleMappedKeys(); + } else { + g.currentMap.reset(); + handleMapped = false; + } + g.currentCommand.clear(); + updateMiniBuffer(); } + + EventResult r = EventUnhandled; + while (!g.pendingInput.isEmpty()) { + const Input &in = g.pendingInput.front(); + + // invalid input is used to pop mapping state + if (!in.isValid()) { + unhandleMappedKeys(); + } else { + if (handleMapped && !g.mapStates.last().noremap && m_subsubmode != SearchSubSubMode) { + if (!g.currentMap.isValid()) { + g.currentMap.reset(currentModeCode()); + if (!g.currentMap.walk(g.pendingInput) && g.currentMap.isComplete()) { + handleMappedKeys(); + continue; + } + } + + // handle user mapping + if (g.currentMap.canExtend()) { + g.currentCommand.append(in.toString()); + updateMiniBuffer(); + // wait for user to press any key or trigger complete mapping after interval + g.inputTimer = startTimer(1000); + return EventHandled; + } else if (g.currentMap.isComplete()) { + handleMappedKeys(); + continue; + } + } + + r = handleDefaultKey(in); + if (r != EventHandled) { + // clear bad mapping + const int index = g.pendingInput.lastIndexOf(Input()); + if (index != -1) + g.pendingInput.remove(0, index - 1); + } + } + handleMapped = true; + g.pendingInput.pop_front(); + } + + return r; +} + +EventResult FakeVimHandler::Private::handleDefaultKey(const Input &input) +{ + if (input == Nop) + return EventHandled; + else if (m_subsubmode == SearchSubSubMode) + return handleSearchSubSubMode(input); + else if (m_mode == CommandMode) + return handleCommandMode(input); + else if (m_mode == InsertMode) + return handleInsertMode(input); + else if (m_mode == ReplaceMode) + return handleReplaceMode(input); + else if (m_mode == ExMode) + return handleExMode(input); return EventUnhandled; } -EventResult FakeVimHandler::Private::handleKey2() +void FakeVimHandler::Private::handleMappedKeys() { - Inputs pendingInput = g.pendingInput; - g.pendingInput.clear(); - if (m_mode == InsertMode) { - EventResult result = EventUnhandled; - foreach (const Input &in, pendingInput) { - EventResult r = handleInsertMode(in); - if (r == EventHandled) - result = EventHandled; - } - return result; - } - if (m_mode == ReplaceMode) { - EventResult result = EventUnhandled; - foreach (const Input &in, pendingInput) { - EventResult r = handleReplaceMode(in); - if (r == EventHandled) - result = EventHandled; - } - return result; - } - if (m_mode == CommandMode) { - EventResult result = EventUnhandled; - foreach (const Input &in, pendingInput) { - EventResult r = handleCommandMode(in); - if (r == EventHandled) - result = EventHandled; - } - return result; + int maxMapDepth = g.mapStates.last().maxMapDepth - 1; + + int invalidCount = g.currentMap.invalidInputCount(); + if (invalidCount > 0) { + g.mapStates.remove(g.mapStates.size() - invalidCount, invalidCount); + QTC_CHECK(!g.mapStates.empty()); + for (int i = 0; i < invalidCount; ++i) + endEditBlock(); } - return EventUnhandled; + + if (maxMapDepth <= 0) { + showMessage(MessageError, "recursive mapping"); + g.pendingInput.remove(0, g.currentMap.mapLength() + invalidCount); + } else { + const Inputs &inputs = g.currentMap.inputs(); + QVector<Input> rest = g.pendingInput.mid(g.currentMap.mapLength() + invalidCount); + g.pendingInput.clear(); + g.pendingInput << inputs << Input() << rest; + g.mapStates << MappingState(maxMapDepth, inputs.noremap(), inputs.silent()); + g.commandBuffer.setHistoryAutoSave(false); + beginLargeEditBlock(); + } + g.currentMap.reset(); +} + +void FakeVimHandler::Private::unhandleMappedKeys() +{ + if (g.mapStates.size() == 1) + return; + g.mapStates.pop_back(); + endEditBlock(); + if (g.mapStates.size() == 1) + g.commandBuffer.setHistoryAutoSave(true); + if (m_mode == ExMode || m_subsubmode == SearchSubSubMode) + updateMiniBuffer(); // update cursor position on command line } void FakeVimHandler::Private::timerEvent(QTimerEvent *ev) { - Q_UNUSED(ev); - handleKey2(); + if (ev->timerId() == g.inputTimer) { + if (g.currentMap.isComplete()) + handleMappedKeys(); + handleKey(Input()); + } } void FakeVimHandler::Private::stopIncrementalFind() { - if (m_findPending) { - m_findPending = false; + if (g.findPending) { + g.findPending = false; QTextCursor tc = cursor(); setAnchorAndPosition(m_findStartPosition, tc.selectionStart()); finishMovement(); @@ -1649,46 +2335,133 @@ void FakeVimHandler::Private::stopIncrementalFind() } } -void FakeVimHandler::Private::setUndoPosition() +void FakeVimHandler::Private::updateFind(bool isComplete) +{ + if (!isComplete && !hasConfig(ConfigIncSearch)) + return; + + g.currentMessage.clear(); + + const QString &needle = g.searchBuffer.contents(); + SearchData sd; + sd.needle = needle; + sd.forward = g.lastSearchForward; + sd.highlightMatches = isComplete; + if (isComplete) { + setPosition(m_searchStartPosition); + recordJump(); + } + search(sd, isComplete); +} + +bool FakeVimHandler::Private::atEmptyLine(const QTextCursor &tc) const { - int pos = qMin(position(), anchor()); - if (m_visualMode == VisualLineMode) - pos = firstPositionInLine(lineForPosition(pos)); - const int rev = document()->availableUndoSteps(); - m_undoCursorPosition[rev] = pos; + if (tc.isNull()) + return atEmptyLine(cursor()); + return tc.block().length() == 1; +} + +bool FakeVimHandler::Private::atBoundary(bool end, bool simple, bool onlyWords, + const QTextCursor &tc) const +{ + if (tc.isNull()) + return atBoundary(end, simple, onlyWords, cursor()); + if (atEmptyLine(tc)) + return true; + int pos = tc.position(); + QChar c1 = document()->characterAt(pos); + QChar c2 = document()->characterAt(pos + (end ? 1 : -1)); + int thisClass = charClass(c1, simple); + return (!onlyWords || thisClass != 0) + && (c2.isNull() || c2 == ParagraphSeparator || thisClass != charClass(c2, simple)); +} + +bool FakeVimHandler::Private::atWordBoundary(bool end, bool simple, const QTextCursor &tc) const +{ + return atBoundary(end, simple, true, tc); +} + +bool FakeVimHandler::Private::atWordStart(bool simple, const QTextCursor &tc) const +{ + return atWordBoundary(false, simple, tc); +} + +bool FakeVimHandler::Private::atWordEnd(bool simple, const QTextCursor &tc) const +{ + return atWordBoundary(true, simple, tc); +} + +bool FakeVimHandler::Private::isFirstNonBlankOnLine(int pos) +{ + for (int i = document()->findBlock(pos).position(); i < pos; ++i) { + if (!document()->characterAt(i).isSpace()) + return false; + } + return true; +} + +void FakeVimHandler::Private::setUndoPosition(bool overwrite) +{ + const int rev = revision(); + if (!overwrite && !m_undo.empty() && m_undo.top().revision >= rev) + return; + + int pos = position(); + if (m_mode != InsertMode && m_mode != ReplaceMode) { + if (isVisualMode() || m_submode == DeleteSubMode) { + pos = qMin(pos, anchor()); + if (isVisualLineMode()) + pos = firstPositionInLine(lineForPosition(pos)); + } else if (m_movetype == MoveLineWise && hasConfig(ConfigStartOfLine)) { + QTextCursor tc = cursor(); + if (m_submode == ShiftLeftSubMode || m_submode == ShiftRightSubMode + || m_submode == IndentSubMode) { + pos = qMin(pos, anchor()); + } + tc.setPosition(pos); + moveToFirstNonBlankOnLine(&tc); + pos = qMin(pos, tc.position()); + } + } + + m_redo.clear(); + while (!m_undo.empty() && m_undo.top().revision >= rev) + m_undo.pop(); + m_lastChangePosition = CursorPosition(document(), pos); + if (isVisualMode()) { + setMark('<', mark('<').position); + setMark('>', mark('>').position); + } + m_undo.push(State(rev, m_lastChangePosition, m_marks, m_lastVisualMode)); } void FakeVimHandler::Private::moveDown(int n) { -#if 0 - // does not work for "hidden" documents like in the autotests - tc.movePosition(Down, MoveAnchor, n); -#else - const int col = position() - block().position(); - const int lastLine = document()->lastBlock().blockNumber(); - const int targetLine = qMax(0, qMin(lastLine, block().blockNumber() + n)); - const QTextBlock &block = document()->findBlockByNumber(targetLine); - const int pos = block.position(); - setPosition(pos + qMax(0, qMin(block.length() - 2, col))); + QTextBlock block = cursor().block(); + const int col = position() - block.position(); + const int targetLine = qMax(0, lineNumber(block) + n); + + block = document()->findBlockByLineNumber(qMax(0, targetLine - 1)); + if (!block.isValid()) + block = document()->lastBlock(); + setPosition(block.position() + qMax(0, qMin(block.length() - 2, col))); moveToTargetColumn(); -#endif } void FakeVimHandler::Private::moveToEndOfLine() { -#if 0 - // does not work for "hidden" documents like in the autotests - tc.movePosition(EndOfLine, MoveAnchor); -#else - const int pos = block().position() + block().length() - 2; - setPosition(qMax(block().position(), pos)); -#endif + // Additionally select (in visual mode) or apply current command on hidden lines following + // the current line. + bool onlyVisibleLines = isVisualMode() || m_submode != NoSubMode; + const int id = onlyVisibleLines ? lineNumber(block()) : block().blockNumber() + 1; + setPosition(lastPositionInLine(id, onlyVisibleLines)); } void FakeVimHandler::Private::moveBehindEndOfLine() { + emit q->fold(1, false); int pos = qMin(block().position() + block().length() - 1, - lastPositionInDocument()); + lastPositionInDocument() + 1); setPosition(pos); } @@ -1702,63 +2475,105 @@ void FakeVimHandler::Private::moveToStartOfLine() #endif } -void FakeVimHandler::Private::finishMovement(const QString &dotCommand, int count) +void FakeVimHandler::Private::fixSelection() { - finishMovement(dotCommand.arg(count)); + if (m_rangemode == RangeBlockMode) + return; + + if (m_movetype == MoveExclusive) { + if (anchor() < position() && atBlockStart()) { + // Exlusive motion ending at the beginning of line + // becomes inclusive and end is moved to end of previous line. + m_movetype = MoveInclusive; + moveToStartOfLine(); + moveLeft(); + + // Exclusive motion ending at the beginning of line and + // starting at or before first non-blank on a line becomes linewise. + if (anchor() < block().position() && isFirstNonBlankOnLine(anchor())) { + m_movetype = MoveLineWise; + } + } + } + + if (m_movetype == MoveLineWise) + m_rangemode = (m_submode == ChangeSubMode) + ? RangeLineModeExclusive + : RangeLineMode; + + if (m_movetype == MoveInclusive) { + if (anchor() <= position()) { + if (!atBlockEnd()) + setPosition(position() + 1); // correction + + // Omit first character in selection if it's line break on non-empty line. + int start = anchor(); + int end = position(); + if (afterEndOfLine(document(), start) && start > 0) { + start = qMin(start + 1, end); + if (m_submode == DeleteSubMode && !atDocumentEnd()) + setAnchorAndPosition(start, end + 1); + else + setAnchorAndPosition(start, end); + } + + // If more than one line is selected and all are selected completely + // movement becomes linewise. + if (start < block().position() && isFirstNonBlankOnLine(start) && atBlockEnd()) { + if (m_submode != ChangeSubMode) { + moveRight(); + if (atEmptyLine()) + moveRight(); + } + m_movetype = MoveLineWise; + } + } else { + setAnchorAndPosition(anchor() + 1, position()); + } + } + + if (m_positionPastEnd) { + const int anc = anchor(); + moveBehindEndOfLine(); + moveRight(); + setAnchorAndPosition(anc, position()); + } + + if (m_anchorPastEnd) { + setAnchorAndPosition(anchor() + 1, position()); + } } -void FakeVimHandler::Private::finishMovement(const QString &dotCommand) +void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement, int count) +{ + finishMovement(dotCommandMovement.arg(count)); +} + +void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) { //dump("FINISH MOVEMENT"); if (m_submode == FilterSubMode) { int beginLine = lineForPosition(anchor()); int endLine = lineForPosition(position()); setPosition(qMin(anchor(), position())); - enterExMode(); - m_currentMessage.clear(); - m_commandBuffer.setContents(QString(".,+%1!").arg(qAbs(endLine - beginLine))); - //g.commandHistory.append(QString()); - updateMiniBuffer(); + enterExMode(QString(".,+%1!").arg(qAbs(endLine - beginLine))); return; } - //if (isVisualMode()) - // setMark('>', position()); - if (m_submode == ChangeSubMode || m_submode == DeleteSubMode || m_submode == YankSubMode - || m_submode == TransformSubMode) { - + || m_submode == InvertCaseSubMode + || m_submode == DownCaseSubMode + || m_submode == UpCaseSubMode) { if (m_submode != YankSubMode) beginEditBlock(); - if (m_movetype == MoveLineWise) - m_rangemode = (m_submode == ChangeSubMode) - ? RangeLineModeExclusive - : RangeLineMode; - - if (m_movetype == MoveInclusive) { - if (anchor() <= position()) { - if (!cursor().atBlockEnd()) - setPosition(position() + 1); // correction - } else { - setAnchorAndPosition(anchor() + 1, position()); - } - } - - if (m_positionPastEnd) { - const int anc = anchor(); - moveBehindEndOfLine(); - moveRight(); - setAnchorAndPosition(anc, position()); - } + fixSelection(); - if (m_anchorPastEnd) { - setAnchorAndPosition(anchor() + 1, position()); - } - - if (m_submode != TransformSubMode) { + if (m_submode != InvertCaseSubMode + && m_submode != DownCaseSubMode + && m_submode != UpCaseSubMode) { yankText(currentRange(), m_register); if (m_movetype == MoveLineWise) setRegister(m_register, registerContents(m_register), RangeLineMode); @@ -1767,86 +2582,76 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) m_positionPastEnd = m_anchorPastEnd = false; } + QString dotCommand; if (m_submode == ChangeSubMode) { - if (m_rangemode == RangeLineMode) - m_rangemode = RangeLineModeExclusive; + if (m_rangemode != RangeLineModeExclusive) + setUndoPosition(); removeText(currentRange()); - if (!dotCommand.isEmpty()) - setDotCommand(QLatin1Char('c') + dotCommand); + dotCommand = QString('c'); if (m_movetype == MoveLineWise) insertAutomaticIndentation(true); endEditBlock(); - enterInsertMode(); - m_submode = NoSubMode; + setTargetColumn(); + g.returnToMode = InsertMode; } else if (m_submode == DeleteSubMode) { + setUndoPosition(); removeText(currentRange()); - if (!dotCommand.isEmpty()) - setDotCommand(QLatin1Char('d') + dotCommand); + dotCommand = QString('d'); if (m_movetype == MoveLineWise) handleStartOfLine(); - m_submode = NoSubMode; if (atEndOfLine()) moveLeft(); else setTargetColumn(); endEditBlock(); } else if (m_submode == YankSubMode) { - m_submode = NoSubMode; - const int la = lineForPosition(anchor()); - const int lp = lineForPosition(position()); - if (m_register != '"') { - setPosition(mark(m_register)); - moveToStartOfLine(); - } else { - if (anchor() <= position()) - setPosition(anchor()); - } - if (la != lp) - showBlackMessage(QString("%1 lines yanked").arg(qAbs(la - lp) + 1)); - } else if (m_submode == TransformSubMode) { - if (m_subsubmode == InvertCaseSubSubMode) { + setPosition(qMin(position(), anchor())); + leaveVisualMode(); + if (anchor() <= position()) + setPosition(anchor()); + } else if (m_submode == InvertCaseSubMode + || m_submode == UpCaseSubMode + || m_submode == DownCaseSubMode) { + if (m_submode == InvertCaseSubMode) { invertCase(currentRange()); - if (!dotCommand.isEmpty()) - setDotCommand(QLatin1Char('~') + dotCommand); - } else if (m_subsubmode == UpCaseSubSubMode) { - upCase(currentRange()); - if (!dotCommand.isEmpty()) - setDotCommand("gU" + dotCommand); - } else if (m_subsubmode == DownCaseSubSubMode) { + dotCommand = QString("g~"); + } else if (m_submode == DownCaseSubMode) { downCase(currentRange()); - if (!dotCommand.isEmpty()) - setDotCommand("gu" + dotCommand); + dotCommand = QString("gu"); + } else if (m_submode == UpCaseSubMode) { + upCase(currentRange()); + dotCommand = QString("gU"); } - m_submode = NoSubMode; - m_subsubmode = NoSubSubMode; - setPosition(qMin(anchor(), position())); if (m_movetype == MoveLineWise) handleStartOfLine(); endEditBlock(); - } else if (m_submode == IndentSubMode) { - setUndoPosition(); + } else if (m_submode == IndentSubMode + || m_submode == ShiftRightSubMode + || m_submode == ShiftLeftSubMode) { recordJump(); - indentSelectedText(); - m_submode = NoSubMode; - } else if (m_submode == ShiftRightSubMode) { setUndoPosition(); - recordJump(); - shiftRegionRight(1); - m_submode = NoSubMode; - } else if (m_submode == ShiftLeftSubMode) { - setUndoPosition(); - recordJump(); - shiftRegionLeft(1); - m_submode = NoSubMode; + if (m_submode == IndentSubMode) { + indentSelectedText(); + dotCommand = QString('='); + } else if (m_submode == ShiftRightSubMode) { + shiftRegionRight(1); + dotCommand = QString('>'); + } else if (m_submode == ShiftLeftSubMode) { + shiftRegionLeft(1); + dotCommand = QString('<'); + } } + if (!dotCommand.isEmpty() && !dotCommandMovement.isEmpty()) + setDotCommand(dotCommand + dotCommandMovement); + resetCommandMode(); - updateSelection(); - updateMiniBuffer(); } void FakeVimHandler::Private::resetCommandMode() { + m_subsubmode = NoSubSubMode; + m_submode = NoSubMode; m_movetype = MoveInclusive; m_mvcount.clear(); m_opcount.clear(); @@ -1854,27 +2659,29 @@ void FakeVimHandler::Private::resetCommandMode() m_register = '"'; //m_tc.clearSelection(); m_rangemode = RangeCharMode; + if (isNoVisualMode()) + setAnchor(); + g.currentCommand.clear(); + if (g.returnToMode != CommandMode) { + if (g.returnToMode == InsertMode) + enterInsertMode(); + else + enterReplaceMode(); + moveToTargetColumn(); + } } void FakeVimHandler::Private::updateSelection() { - QList<QTextEdit::ExtraSelection> selections = m_searchSelections; - if (!m_searchCursor.isNull()) { - QTextEdit::ExtraSelection sel; - sel.cursor = m_searchCursor; - sel.format = m_searchCursor.blockCharFormat(); - sel.format.setForeground(Qt::white); - sel.format.setBackground(Qt::black); - selections.append(sel); - } + QList<QTextEdit::ExtraSelection> selections = m_extraSelections; if (hasConfig(ConfigShowMarks)) { for (MarksIterator it(m_marks); it.hasNext(); ) { it.next(); QTextEdit::ExtraSelection sel; - const int pos = it.value().position(); sel.cursor = cursor(); - sel.cursor.setPosition(pos, MoveAnchor); - sel.cursor.setPosition(pos + 1, KeepAnchor); + setCursorPosition(&sel.cursor, it.value().position); + sel.cursor.setPosition(sel.cursor.position(), MoveAnchor); + sel.cursor.movePosition(Right, KeepAnchor); sel.format = cursor().blockCharFormat(); sel.format.setForeground(Qt::blue); sel.format.setBackground(Qt::green); @@ -1885,6 +2692,12 @@ void FakeVimHandler::Private::updateSelection() emit q->selectionChanged(selections); } +void FakeVimHandler::Private::updateHighlights() +{ + if (!hasConfig(ConfigUseCoreSearch)) + emit q->highlightMatches(m_oldNeedle); +} + void FakeVimHandler::Private::updateMiniBuffer() { if (!m_textedit && !m_plaintextedit) @@ -1892,34 +2705,54 @@ void FakeVimHandler::Private::updateMiniBuffer() QString msg; int cursorPos = -1; + MessageLevel messageLevel = MessageMode; + + if (g.mapStates.last().silent && g.currentMessageLevel < MessageInfo) + g.currentMessage.clear(); + if (m_passing) { - msg = "-- PASSING -- "; - } else if (!m_currentMessage.isEmpty()) { - msg = m_currentMessage; + msg = "PASSING"; + } else if (m_subsubmode == SearchSubSubMode) { + msg = g.searchBuffer.display(); + if (g.mapStates.size() == 1) + cursorPos = g.searchBuffer.cursorPos() + 1; + } else if (m_mode == ExMode) { + msg = g.commandBuffer.display(); + if (g.mapStates.size() == 1) + cursorPos = g.commandBuffer.cursorPos() + 1; + } else if (!g.currentMessage.isEmpty()) { + msg = g.currentMessage; + g.currentMessage.clear(); + messageLevel = g.currentMessageLevel; + } else if (g.mapStates.size() > 1 && !g.mapStates.last().silent) { + // Do not reset previous message when after running a mapped command. + return; + } else if (m_mode == CommandMode && !g.currentCommand.isEmpty() && hasConfig(ConfigShowCmd)) { + msg = g.currentCommand; + messageLevel = MessageShowCmd; } else if (m_mode == CommandMode && isVisualMode()) { if (isVisualCharMode()) { - msg = "-- VISUAL --"; + msg = "VISUAL"; } else if (isVisualLineMode()) { - msg = "-- VISUAL LINE --"; + msg = "VISUAL LINE"; } else if (isVisualBlockMode()) { - msg = "-- VISUAL BLOCK --"; + msg = "VISUAL BLOCK"; } } else if (m_mode == InsertMode) { - msg = "-- INSERT --"; + msg = "INSERT"; } else if (m_mode == ReplaceMode) { - msg = "-- REPLACE --"; - } else if (!m_commandPrefix.isEmpty()) { - //QTC_ASSERT(m_mode == ExMode || m_subsubmode == SearchSubSubMode, - // qDebug() << "MODE: " << m_mode << m_subsubmode); - msg = m_commandPrefix + m_commandBuffer.display(); - if (m_mode != CommandMode) - cursorPos = m_commandPrefix.size() + m_commandBuffer.cursorPos(); + msg = "REPLACE"; } else { QTC_CHECK(m_mode == CommandMode && m_subsubmode != SearchSubSubMode); - msg = "-- COMMAND --"; + if (g.returnToMode == CommandMode) + msg = "COMMAND"; + else if (g.returnToMode == InsertMode) + msg = "(insert)"; + else + msg = "(replace)"; } - emit q->commandBufferChanged(msg, cursorPos); + emit q->commandBufferChanged(msg, cursorPos, messageLevel, q); int linesInDoc = linesInDocument(); int l = cursorLine(); @@ -1935,25 +2768,17 @@ void FakeVimHandler::Private::updateMiniBuffer() emit q->statusDataChanged(status); } -void FakeVimHandler::Private::showRedMessage(const QString &msg) +void FakeVimHandler::Private::showMessage(MessageLevel level, const QString &msg) { //qDebug() << "MSG: " << msg; - m_currentMessage = msg; - updateMiniBuffer(); -} - -void FakeVimHandler::Private::showBlackMessage(const QString &msg) -{ - //qDebug() << "MSG: " << msg; - m_commandBuffer.setContents(msg); - updateMiniBuffer(); + g.currentMessage = msg; + g.currentMessageLevel = level; } void FakeVimHandler::Private::notImplementedYet() { qDebug() << "Not implemented in FakeVim"; - showRedMessage(FakeVimHandler::tr("Not implemented in FakeVim")); - updateMiniBuffer(); + showMessage(MessageError, FakeVimHandler::tr("Not implemented in FakeVim")); } void FakeVimHandler::Private::passShortcuts(bool enable) @@ -1966,20 +2791,10 @@ void FakeVimHandler::Private::passShortcuts(bool enable) QCoreApplication::instance()->removeEventFilter(q); } -static bool subModeCanUseTextObjects(int submode) -{ - return submode == DeleteSubMode - || submode == YankSubMode - || submode == ChangeSubMode - || submode == IndentSubMode - || submode == ShiftLeftSubMode - || submode == ShiftRightSubMode; -} - -EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) +bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) { //const int key = input.key; - EventResult handled = EventHandled; + bool handled = true; if (m_subsubmode == FtSubSubMode) { m_semicolonType = m_subsubdata; m_semicolonKey = input.text(); @@ -1987,7 +2802,8 @@ EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) m_subsubmode = NoSubSubMode; if (!valid) { m_submode = NoSubMode; - finishMovement(); + resetCommandMode(); + handled = false; } else { finishMovement(QString("%1%2%3") .arg(count()) @@ -1995,6 +2811,7 @@ EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) .arg(m_semicolonKey)); } } else if (m_subsubmode == TextObjectSubSubMode) { + bool ok = true; if (input.is('w')) selectWordTextObject(m_subsubdata.is('i')); else if (input.is('W')) @@ -2004,245 +2821,96 @@ EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) else if (input.is('p')) selectParagraphTextObject(m_subsubdata.is('i')); else if (input.is('[') || input.is(']')) - selectBlockTextObject(m_subsubdata.is('i'), '[', ']'); + ok = selectBlockTextObject(m_subsubdata.is('i'), '[', ']'); else if (input.is('(') || input.is(')') || input.is('b')) - selectBlockTextObject(m_subsubdata.is('i'), '(', ')'); + ok = selectBlockTextObject(m_subsubdata.is('i'), '(', ')'); else if (input.is('<') || input.is('>')) - selectBlockTextObject(m_subsubdata.is('i'), '<', '>'); + ok = selectBlockTextObject(m_subsubdata.is('i'), '<', '>'); else if (input.is('{') || input.is('}') || input.is('B')) - selectBlockTextObject(m_subsubdata.is('i'), '{', '}'); + ok = selectBlockTextObject(m_subsubdata.is('i'), '{', '}'); else if (input.is('"') || input.is('\'') || input.is('`')) - selectQuotedStringTextObject(m_subsubdata.is('i'), input.asChar()); + ok = selectQuotedStringTextObject(m_subsubdata.is('i'), input.asChar()); + else + ok = false; m_subsubmode = NoSubSubMode; - finishMovement(QString("%1%2%3") - .arg(count()) - .arg(m_subsubdata.text()) - .arg(input.text())); + if (ok) { + finishMovement(QString("%1%2%3") + .arg(count()) + .arg(m_subsubdata.text()) + .arg(input.text())); + } else { + resetCommandMode(); + handled = false; + } } else if (m_subsubmode == MarkSubSubMode) { - setMark(input.asChar().unicode(), position()); + setMark(input.asChar(), CursorPosition(cursor())); m_subsubmode = NoSubSubMode; } else if (m_subsubmode == BackTickSubSubMode || m_subsubmode == TickSubSubMode) { - int m = mark(input.asChar().unicode()); - if (m != -1) { - setPosition(m); - if (m_subsubmode == TickSubSubMode) - moveToFirstNonBlankOnLine(); + if (jumpToMark(input.asChar(), m_subsubmode == BackTickSubSubMode)) { finishMovement(); } else { - showRedMessage(msgMarkNotSet(input.text())); + resetCommandMode(); + handled = false; } m_subsubmode = NoSubSubMode; } else { - handled = EventUnhandled; + handled = false; } return handled; } -EventResult FakeVimHandler::Private::handleOpenSquareSubMode(const Input &input) +bool FakeVimHandler::Private::handleOpenSquareSubMode(const Input &input) { - EventResult handled = EventHandled; + bool handled = true; m_submode = NoSubMode; if (input.is('{')) { searchBalanced(false, '{', '}'); } else if (input.is('(')) { searchBalanced(false, '(', ')'); } else { - handled = EventUnhandled; + handled = false; } return handled; } -EventResult FakeVimHandler::Private::handleCloseSquareSubMode(const Input &input) +bool FakeVimHandler::Private::handleCloseSquareSubMode(const Input &input) { - EventResult handled = EventHandled; + bool handled = true; m_submode = NoSubMode; if (input.is('}')) { searchBalanced(true, '}', '{'); } else if (input.is(')')) { searchBalanced(true, ')', '('); } else { - handled = EventUnhandled; + handled = false; } return handled; } -EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) +bool FakeVimHandler::Private::handleMovement(const Input &input) { - EventResult handled = EventHandled; + bool handled = true; + QString movement; + int count = this->count(); - if (input.isEscape()) { - if (isVisualMode()) { - leaveVisualMode(); - } else if (m_submode != NoSubMode) { - m_submode = NoSubMode; - m_subsubmode = NoSubSubMode; - finishMovement(); - } else { - resetCommandMode(); - updateSelection(); - updateMiniBuffer(); - } - } else if (m_subsubmode != NoSubSubMode) { - handleCommandSubSubMode(input); - } else if (m_submode == OpenSquareSubMode) { - handled = handleOpenSquareSubMode(input); - } else if (m_submode == CloseSquareSubMode) { - handled = handleCloseSquareSubMode(input); - } else if (m_submode == WindowSubMode) { - emit q->windowCommandRequested(input.key()); - m_submode = NoSubMode; - } else if (m_submode == RegisterSubMode) { - m_register = input.asChar().unicode(); - m_submode = NoSubMode; - m_rangemode = RangeLineMode; - } else if (m_submode == ReplaceSubMode) { - if (isVisualMode()) { - setUndoPosition(); - m_lastChangePosition = position(); - if (isVisualLineMode()) - m_rangemode = RangeLineMode; - else if (isVisualBlockMode()) - m_rangemode = RangeBlockMode; - else - m_rangemode = RangeCharMode; - leaveVisualMode(); - Range range = currentRange(); - Transformation tr = - &FakeVimHandler::Private::replaceByCharTransform; - transformText(range, tr, input.asChar()); - setPosition(range.beginPos); - } else if (count() <= rightDist()) { - setUndoPosition(); - m_lastChangePosition = position(); - setAnchor(); - moveRight(count()); - Range range = currentRange(); - if (input.isReturn()) { - beginEditBlock(); - replaceText(range, QString()); - insertText(QString("\n")); - endEditBlock(); - } else { - replaceText(range, QString(count(), input.asChar())); - moveLeft(); - } - setTargetColumn(); - setDotCommand("%1r" + input.text(), count()); - } - m_submode = NoSubMode; - finishMovement(); - } else if (m_submode == ChangeSubMode && input.is('c')) { // tested - setUndoPosition(); - m_lastChangePosition = position(); - moveToStartOfLine(); - setAnchor(); - moveDown(count() - 1); - moveToEndOfLine(); - m_movetype = MoveLineWise; - m_lastInsertion.clear(); - setDotCommand("%1cc", count()); - finishMovement(); - } else if (m_submode == DeleteSubMode && input.is('d')) { // tested - setUndoPosition(); - m_lastChangePosition = position(); - m_movetype = MoveLineWise; - int endPos = firstPositionInLine(lineForPosition(position()) + count() - 1); - Range range(position(), endPos, RangeLineMode); - yankText(range); - removeText(range); - setDotCommand("%1dd", count()); - m_submode = NoSubMode; - handleStartOfLine(); - setTargetColumn(); - finishMovement(); - } else if ((subModeCanUseTextObjects(m_submode) || isVisualMode()) - && (input.is('a') || input.is('i'))) { - m_subsubmode = TextObjectSubSubMode; - m_subsubdata = input; - } else if (m_submode == ShiftLeftSubMode && input.is('<')) { - m_lastChangePosition = position(); - setAnchor(); - moveDown(count() - 1); - m_movetype = MoveLineWise; - setDotCommand("%1<<", count()); - finishMovement(); - } else if (m_submode == ShiftRightSubMode && input.is('>')) { - m_lastChangePosition = position(); - setAnchor(); - moveDown(count() - 1); - m_movetype = MoveLineWise; - setDotCommand("%1>>", count()); - finishMovement(); - } else if (m_submode == IndentSubMode && input.is('=')) { - m_lastChangePosition = position(); - setAnchor(); - moveDown(count() - 1); - m_movetype = MoveLineWise; - setDotCommand("%1==", count()); - finishMovement(); - } else if (m_submode == ZSubMode) { - //qDebug() << "Z_MODE " << cursorLine() << linesOnScreen(); - if (input.isReturn() || input.is('t')) { - // Cursor line to top of window. - if (!m_mvcount.isEmpty()) - setPosition(firstPositionInLine(count())); - scrollUp(- cursorLineOnScreen()); - if (input.isReturn()) - moveToFirstNonBlankOnLine(); - finishMovement(); - } else if (input.is('.') || input.is('z')) { - // Cursor line to center of window. - if (!m_mvcount.isEmpty()) - setPosition(firstPositionInLine(count())); - scrollUp(linesOnScreen() / 2 - cursorLineOnScreen()); - if (input.is('.')) - moveToFirstNonBlankOnLine(); - finishMovement(); - } else if (input.is('-') || input.is('b')) { - // Cursor line to bottom of window. - if (!m_mvcount.isEmpty()) - setPosition(firstPositionInLine(count())); - scrollUp(linesOnScreen() - cursorLineOnScreen()); - if (input.is('-')) - moveToFirstNonBlankOnLine(); - finishMovement(); - } else { - qDebug() << "IGNORED Z_MODE " << input.key() << input.text(); - } - m_submode = NoSubMode; - } else if (m_submode == CapitalZSubMode) { - // Recognize ZZ and ZQ as aliases for ":x" and ":q!". - m_submode = NoSubMode; - if (input.is('Z')) - handleExCommand(QString(QLatin1Char('x'))); - else if (input.is('Q')) - handleExCommand("q!"); - } else if (input.isDigit()) { + if (input.isDigit()) { if (input.is('0') && m_mvcount.isEmpty()) { m_movetype = MoveExclusive; moveToStartOfLine(); setTargetColumn(); - finishMovement(QString(QLatin1Char('0'))); + count = 1; } else { m_mvcount.append(input.text()); + return true; } - } else { - handled = handleCommandMode1(input); - } - - return handled; -} - -EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) -{ - EventResult handled = EventHandled; - - if (input.is('^') || input.is('_')) { + } else if (input.is('a') || input.is('i')) { + m_subsubmode = TextObjectSubSubMode; + m_subsubdata = input; + } else if (input.is('^') || input.is('_')) { moveToFirstNonBlankOnLine(); setTargetColumn(); m_movetype = MoveExclusive; - finishMovement(input.text()); } else if (0 && input.is(',')) { // FIXME: fakevim uses ',' by itself, so it is incompatible m_subsubmode = FtSubSubMode; @@ -2250,112 +2918,77 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) //m_subsubdata = m_semicolonType ^ 32; handleFfTt(m_semicolonKey); m_subsubmode = NoSubSubMode; - finishMovement(); } else if (input.is(';')) { m_subsubmode = FtSubSubMode; m_subsubdata = m_semicolonType; handleFfTt(m_semicolonKey); m_subsubmode = NoSubSubMode; - finishMovement(); - } else if (input.is('&')) { - handleExCommand(m_gflag ? "%s//~/&" : "s"); - } else if (input.is(':')) { - enterExMode(); - g.commandHistory.restart(); - m_currentMessage.clear(); - m_commandBuffer.clear(); - if (isVisualMode()) - m_commandBuffer.setContents("'<,'>"); - updateMiniBuffer(); } else if (input.is('/') || input.is('?')) { - m_lastSearchForward = input.is('/'); - g.searchHistory.restart(); + g.lastSearchForward = input.is('/'); if (hasConfig(ConfigUseCoreSearch)) { // re-use the core dialog. - m_findPending = true; + g.findPending = true; m_findStartPosition = position(); m_movetype = MoveExclusive; setAnchor(); // clear selection: otherwise, search is restricted to selection - emit q->findRequested(!m_lastSearchForward); + emit q->findRequested(!g.lastSearchForward); } else { // FIXME: make core find dialog sufficiently flexible to // produce the "default vi" behaviour too. For now, roll our own. - m_currentMessage.clear(); + g.currentMessage.clear(); m_movetype = MoveExclusive; m_subsubmode = SearchSubSubMode; - m_commandPrefix = QLatin1Char(m_lastSearchForward ? '/' : '?'); - m_commandBuffer.clear(); - updateMiniBuffer(); + g.searchBuffer.setPrompt(g.lastSearchForward ? '/' : '?'); + m_searchStartPosition = position(); + m_searchFromScreenLine = firstVisibleLine(); + m_searchCursor = QTextCursor(); + g.searchBuffer.clear(); } } else if (input.is('`')) { m_subsubmode = BackTickSubSubMode; - if (m_submode != NoSubMode) - m_movetype = MoveLineWise; } else if (input.is('#') || input.is('*')) { // FIXME: That's not proper vim behaviour QString needle; QTextCursor tc = cursor(); tc.select(QTextCursor::WordUnderCursor); - needle = "\\<" + tc.selection().toPlainText() + "\\>"; + needle = QRegExp::escape(tc.selection().toPlainText()); + if (!m_gflag) + needle = "\\<" + needle + "\\>"; setAnchorAndPosition(tc.position(), tc.anchor()); - g.searchHistory.append(needle); - m_lastSearchForward = input.is('*'); - m_currentMessage.clear(); - m_commandPrefix = QLatin1Char(m_lastSearchForward ? '/' : '?'); - m_commandBuffer.setContents(needle); - SearchData sd; - sd.needle = needle; - sd.forward = m_lastSearchForward; - sd.highlightCursor = false; - sd.highlightMatches = true; - search(sd); - //m_searchCursor = QTextCursor(); - //updateSelection(); - //updateMiniBuffer(); + g.searchBuffer.historyPush(needle); + g.lastSearch = needle; + g.lastSearchForward = input.is('*'); + searchNext(); } else if (input.is('\'')) { m_subsubmode = TickSubSubMode; if (m_submode != NoSubMode) m_movetype = MoveLineWise; } else if (input.is('|')) { moveToStartOfLine(); - moveRight(qMin(count(), rightDist()) - 1); + moveRight(qMin(count, rightDist()) - 1); setTargetColumn(); - finishMovement(); - } else if (input.is('!') && isNoVisualMode()) { - m_submode = FilterSubMode; - } else if (input.is('!') && isVisualMode()) { - enterExMode(); - m_currentMessage.clear(); - m_commandBuffer.setContents("'<,'>!"); - //g.commandHistory.append(QString()); - updateMiniBuffer(); - } else if (input.is('"')) { - m_submode = RegisterSubMode; } else if (input.isReturn()) { moveToStartOfLine(); moveDown(); moveToFirstNonBlankOnLine(); m_movetype = MoveLineWise; - finishMovement("%1j", count()); } else if (input.is('-')) { moveToStartOfLine(); - moveUp(count()); + moveUp(count); moveToFirstNonBlankOnLine(); m_movetype = MoveLineWise; - finishMovement("%1-", count()); } else if (input.is('+')) { moveToStartOfLine(); - moveDown(count()); + moveDown(count); moveToFirstNonBlankOnLine(); m_movetype = MoveLineWise; - finishMovement("%1+", count()); } else if (input.isKey(Key_Home)) { moveToStartOfLine(); setTargetColumn(); - finishMovement(); + movement = "<HOME>"; } else if (input.is('$') || input.isKey(Key_End)) { - if (count() > 1) - moveDown(count() - 1); + if (count > 1) + moveDown(count - 1); moveToEndOfLine(); m_movetype = MoveInclusive; setTargetColumn(); @@ -2363,7 +2996,298 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) m_targetColumn = -1; if (isVisualMode()) m_visualTargetColumn = -1; - finishMovement("%1$", count()); + movement = "$"; + } else if (input.is('%')) { + recordJump(); + if (count == 1) { + moveToMatchingParanthesis(); + } else { + // set cursor position in percentage - formula taken from Vim help + setPosition(firstPositionInLine((count * linesInDocument() + 99) / 100)); + moveToTargetColumn(); + handleStartOfLine(); + } + } else if (input.is('b') || input.isShift(Key_Left)) { + m_movetype = MoveExclusive; + moveToNextWordStart(count, false, false); + setTargetColumn(); + movement = "b"; + } else if (input.is('B')) { + m_movetype = MoveExclusive; + moveToNextWordStart(count, true, false); + setTargetColumn(); + } else if (input.is('e') && m_gflag) { + m_movetype = MoveInclusive; + moveToNextWordEnd(count, false, false); + setTargetColumn(); + } else if (input.is('e') || input.isShift(Key_Right)) { + m_movetype = MoveInclusive; + moveToNextWordEnd(count, false, true, false); + setTargetColumn(); + movement = "e"; + } else if (input.is('E') && m_gflag) { + m_movetype = MoveInclusive; + moveToNextWordEnd(count, true, false); + setTargetColumn(); + } else if (input.is('E')) { + m_movetype = MoveInclusive; + moveToNextWordEnd(count, true, true, false); + setTargetColumn(); + } else if (input.isControl('e')) { + // FIXME: this should use the "scroll" option, and "count" + if (cursorLineOnScreen() == 0) + moveDown(1); + scrollDown(1); + movement = "<C-E>"; + } else if (input.is('f')) { + m_subsubmode = FtSubSubMode; + m_movetype = MoveInclusive; + m_subsubdata = input; + } else if (input.is('F')) { + m_subsubmode = FtSubSubMode; + m_movetype = MoveExclusive; + m_subsubdata = input; + } else if (!m_gflag && input.is('g')) { + m_gflag = true; + return true; + } else if (input.is('g') || input.is('G')) { + QString dotCommand = QString("%1G").arg(count); + recordJump(); + if (input.is('G') && m_mvcount.isEmpty()) + dotCommand = QString(QLatin1Char('G')); + int n = (input.is('g')) ? 1 : linesInDocument(); + n = m_mvcount.isEmpty() ? n : count; + if (m_submode == NoSubMode || m_submode == ZSubMode + || m_submode == CapitalZSubMode || m_submode == RegisterSubMode) { + setPosition(firstPositionInLine(n, false)); + handleStartOfLine(); + } else { + m_movetype = MoveLineWise; + m_rangemode = RangeLineMode; + setAnchor(); + setPosition(firstPositionInLine(n, false)); + } + setTargetColumn(); + } else if (input.is('h') || input.isKey(Key_Left) || input.isBackspace()) { + m_movetype = MoveExclusive; + int n = qMin(count, leftDist()); + if (m_fakeEnd && block().length() > 1) + ++n; + moveLeft(n); + setTargetColumn(); + movement = "h"; + } else if (input.is('H')) { + setCursor(EDITOR(cursorForPosition(QPoint(0, 0)))); + moveDown(qMax(count - 1, 0)); + handleStartOfLine(); + } else if (input.is('j') || input.isKey(Key_Down) + || input.isControl('j') || input.isControl('n')) { + m_movetype = MoveLineWise; + moveDown(count); + movement = "j"; + } else if (input.is('k') || input.isKey(Key_Up) || input.isControl('p')) { + m_movetype = MoveLineWise; + moveUp(count); + movement = "k"; + } else if (input.is('l') || input.isKey(Key_Right) || input.is(' ')) { + m_movetype = MoveExclusive; + bool pastEnd = count >= rightDist() - 1; + moveRight(qMax(0, qMin(count, rightDist() - (m_submode == NoSubMode)))); + setTargetColumn(); + if (pastEnd && isVisualMode()) + m_visualTargetColumn = -1; + } else if (input.is('L')) { + QTextCursor tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height())))); + setCursor(tc); + moveUp(qMax(count, 1)); + handleStartOfLine(); + } else if (m_gflag && input.is('m')) { + moveToStartOfLine(); + moveRight(qMin(columnsOnScreen() / 2, rightDist()) - 1); + setTargetColumn(); + } else if (input.is('M')) { + QTextCursor tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()) / 2))); + setCursor(tc); + handleStartOfLine(); + } else if (input.is('n') || input.is('N')) { + if (hasConfig(ConfigUseCoreSearch)) { + bool forward = (input.is('n')) ? g.lastSearchForward : !g.lastSearchForward; + int pos = position(); + emit q->findNextRequested(!forward); + if (forward && pos == cursor().selectionStart()) { + // if cursor is already positioned at the start of a find result, this is returned + emit q->findNextRequested(false); + } + setPosition(cursor().selectionStart()); + } else { + searchNext(input.is('n')); + } + } else if (input.is('t')) { + m_movetype = MoveInclusive; + m_subsubmode = FtSubSubMode; + m_subsubdata = input; + } else if (input.is('T')) { + m_movetype = MoveExclusive; + m_subsubmode = FtSubSubMode; + m_subsubdata = input; + } else if (input.is('w') || input.is('W')) { // tested + // Special case: "cw" and "cW" work the same as "ce" and "cE" if the + // cursor is on a non-blank - except if the cursor is on the last + // character of a word: only the current word will be changed + bool simple = input.is('W'); + if (m_submode == ChangeSubMode) { + moveToWordEnd(count, simple, true); + m_movetype = MoveInclusive; + } else { + moveToNextWordStart(count, simple, true); + m_movetype = MoveExclusive; + } + setTargetColumn(); + } else if (input.is('[')) { + m_submode = OpenSquareSubMode; + } else if (input.is(']')) { + m_submode = CloseSquareSubMode; + } else if (input.isKey(Key_PageDown) || input.isControl('f')) { + moveDown(count * (linesOnScreen() - 2) - cursorLineOnScreen()); + scrollToLine(cursorLine()); + handleStartOfLine(); + movement = "f"; + } else if (input.isKey(Key_PageUp) || input.isControl('b')) { + moveUp(count * (linesOnScreen() - 2) + cursorLineOnScreen()); + scrollToLine(cursorLine() + linesOnScreen() - 2); + handleStartOfLine(); + movement = "b"; + } else if (input.isKey(Key_BracketLeft) || input.isKey(Key_BracketRight)) { + + } else { + handled = false; + } + + if (handled && m_subsubmode == NoSubSubMode) { + if (m_submode == NoSubMode) { + resetCommandMode(); + } else { + // finish movement for sub modes + const QString dotMovement = + (count > 1 ? QString::number(count) : QString()) + + (m_gflag ? "g" : "")\ + + (movement.isNull() ? QString(input.asChar()) : movement); + finishMovement(dotMovement); + setTargetColumn(); + } + } + + return handled; +} + +EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) +{ + bool handled = false; + + bool clearGflag = m_gflag; + bool clearRegister = m_submode != RegisterSubMode; + bool clearCount = m_submode != RegisterSubMode && !input.isDigit(); + + // Process input for a sub-mode. + if (input.isEscape()) { + handled = handleEscape(); + } else if (m_subsubmode != NoSubSubMode) { + handled = handleCommandSubSubMode(input); + } else if (m_submode == NoSubMode) { + handled = handleNoSubMode(input); + } else if (m_submode == ChangeSubMode || m_submode == DeleteSubMode) { + handled = handleChangeDeleteSubModes(input); + } else if (m_submode == ReplaceSubMode) { + handled = handleReplaceSubMode(input); + } else if (m_submode == FilterSubMode) { + handled = handleFilterSubMode(input); + } else if (m_submode == RegisterSubMode) { + handled = handleRegisterSubMode(input); + } else if (m_submode == WindowSubMode) { + handled = handleWindowSubMode(input); + } else if (m_submode == YankSubMode) { + handled = handleYankSubMode(input); + } else if (m_submode == ZSubMode) { + handled = handleZSubMode(input); + } else if (m_submode == CapitalZSubMode) { + handled = handleCapitalZSubMode(input); + } else if (m_submode == OpenSquareSubMode) { + handled = handleOpenSquareSubMode(input); + } else if (m_submode == CloseSquareSubMode) { + handled = handleCloseSquareSubMode(input); + } else if (m_submode == ShiftLeftSubMode + || m_submode == ShiftRightSubMode + || m_submode == IndentSubMode) { + handled = handleShiftSubMode(input); + } else if (m_submode == InvertCaseSubMode + || m_submode == DownCaseSubMode + || m_submode == UpCaseSubMode) { + handled = handleChangeCaseSubMode(input); + } + + // Clear state and display incomplete command if necessary. + if (handled) { + bool noMode = + (m_mode == CommandMode && m_submode == NoSubMode && m_subsubmode == NoSubSubMode); + clearCount = clearCount && noMode && !m_gflag; + if (clearCount && clearRegister) { + resetCommandMode(); + } else { + // Use gflag only for next input. + if (clearGflag) + m_gflag = false; + // Clear [count] and [register] if its no longer needed. + if (clearCount) { + m_mvcount.clear(); + m_opcount.clear(); + } + // Show or clear current command on minibuffer (showcmd). + if (input.isEscape() || m_mode != CommandMode || clearCount) + g.currentCommand.clear(); + else + g.currentCommand.append(input.toString()); + } + } else { + resetCommandMode(); + //qDebug() << "IGNORED IN COMMAND MODE: " << key << text + // << " VISUAL: " << m_visualMode; + + // if a key which produces text was pressed, don't mark it as unhandled + // - otherwise the text would be inserted while being in command mode + if (input.text().isEmpty()) { + handled = EventUnhandled; + } + } + + updateMiniBuffer(); + + m_positionPastEnd = (m_visualTargetColumn == -1) && isVisualMode(); + + return handled ? EventHandled : EventCancelled; +} + +bool FakeVimHandler::Private::handleEscape() +{ + if (isVisualMode()) + leaveVisualMode(); + resetCommandMode(); + return true; +} + +bool FakeVimHandler::Private::handleNoSubMode(const Input &input) +{ + bool handled = true; + + if (input.is('&')) { + handleExCommand(m_gflag ? "%s//~/&" : "s"); + } else if (input.is(':')) { + enterExMode(); + } else if (input.is('!') && isNoVisualMode()) { + m_submode = FilterSubMode; + } else if (input.is('!') && isVisualMode()) { + enterExMode(QString("!")); + } else if (input.is('"')) { + m_submode = RegisterSubMode; } else if (input.is(',')) { passShortcuts(true); } else if (input.is('.')) { @@ -2371,74 +3295,61 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) // << input; QString savedCommand = g.dotCommand; g.dotCommand.clear(); - replay(savedCommand, count()); - enterCommandMode(); + replay(savedCommand); + resetCommandMode(); g.dotCommand = savedCommand; - } else if (input.is('<')) { - setUndoPosition(); + } else if (input.is('<') || input.is('>') || input.is('=')) { if (isNoVisualMode()) { - m_submode = ShiftLeftSubMode; - } else { - shiftRegionLeft(count()); - leaveVisualMode(); - } - } else if (input.is('>')) { - setUndoPosition(); - if (isNoVisualMode()) { - m_submode = ShiftRightSubMode; - } else { - shiftRegionRight(count()); - leaveVisualMode(); - } - } else if (input.is('=')) { - setUndoPosition(); - if (isNoVisualMode()) { - m_submode = IndentSubMode; + if (input.is('<')) + m_submode = ShiftLeftSubMode; + else if (input.is('>')) + m_submode = ShiftRightSubMode; + else + m_submode = IndentSubMode; + setAnchor(); } else { - indentSelectedText(); leaveVisualMode(); + const int lines = qAbs(lineForPosition(position()) - lineForPosition(anchor())) + 1; + const int repeat = count(); + if (input.is('<')) + shiftRegionLeft(repeat); + else if (input.is('>')) + shiftRegionRight(repeat); + else + indentSelectedText(); + const QString selectDotCommand = + (lines > 1) ? QString("V%1j").arg(lines - 1): QString(); + setDotCommand(selectDotCommand + QString("%1%2%2").arg(repeat).arg(input.raw())); } - } else if (input.is('%')) { - moveToMatchingParanthesis(); - finishMovement(); } else if ((!isVisualMode() && input.is('a')) || (isVisualMode() && input.is('A'))) { leaveVisualMode(); - setUndoPosition(); breakEditBlock(); enterInsertMode(); + setDotCommand("%1a", count()); m_lastInsertion.clear(); if (!atEndOfLine()) moveRight(); - updateMiniBuffer(); - } else if (input.is('A')) { setUndoPosition(); + } else if (input.is('A')) { breakEditBlock(); moveBehindEndOfLine(); + setUndoPosition(); setAnchor(); enterInsertMode(); - setDotCommand(QString(QLatin1Char('A'))); + setDotCommand("%1A", count()); m_lastInsertion.clear(); - updateMiniBuffer(); } else if (input.isControl('a')) { - changeNumberTextObject(true); - } else if (input.is('b') || input.isShift(Key_Left)) { - m_movetype = MoveExclusive; - moveToWordBoundary(false, false); - setTargetColumn(); - finishMovement(); - } else if (input.is('B')) { - m_movetype = MoveExclusive; - moveToWordBoundary(true, false); - setTargetColumn(); - finishMovement(); - } else if (input.is('c') && isNoVisualMode()) { - setUndoPosition(); - if (atEndOfLine()) - moveLeft(); + changeNumberTextObject(count()); + setDotCommand("%1<c-a>", count()); + } else if ((input.is('c') || input.is('d')) && isNoVisualMode()) { setAnchor(); - m_submode = ChangeSubMode; + m_opcount = m_mvcount; + m_mvcount.clear(); + m_movetype = MoveExclusive; + m_submode = input.is('c') ? ChangeSubMode : DeleteSubMode; } else if ((input.is('c') || input.is('C') || input.is('s') || input.is('R')) && (isVisualCharMode() || isVisualLineMode())) { + setDotCommand(visualDotCommand() + input.asChar()); if ((input.is('c')|| input.is('s')) && isVisualCharMode()) { leaveVisualMode(); m_rangemode = RangeCharMode; @@ -2458,23 +3369,13 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) finishMovement(); } else if (input.isControl('c')) { if (isNoVisualMode()) - showBlackMessage("Type Alt-v,Alt-v to quit FakeVim mode"); + showMessage(MessageInfo, "Type Alt-v,Alt-v to quit FakeVim mode"); else leaveVisualMode(); - } else if (input.is('d') && isNoVisualMode()) { - if (m_rangemode == RangeLineMode) { - int pos = position(); - moveToEndOfLine(); - setAnchor(); - setPosition(pos); - } else { - setAnchor(); - } - m_opcount = m_mvcount; - m_mvcount.clear(); - m_submode = DeleteSubMode; } else if ((input.is('d') || input.is('x') || input.isKey(Key_Delete)) && isVisualMode()) { + setUndoPosition(); + setDotCommand(visualDotCommand() + 'x'); if (isVisualCharMode()) { leaveVisualMode(); m_submode = DeleteSubMode; @@ -2493,17 +3394,18 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) setPosition(qMin(position(), anchor())); } } else if (input.is('D') && isNoVisualMode()) { + setUndoPosition(); if (atEndOfLine()) moveLeft(); m_submode = DeleteSubMode; - setAnchor(); - moveDown(qMax(count() - 1, 0)); m_movetype = MoveInclusive; - moveToEndOfLine(); + setAnchorAndPosition(position(), lastPositionInLine(cursorLine() + count())); setDotCommand(QString(QLatin1Char('D'))); finishMovement(); + setTargetColumn(); } else if ((input.is('D') || input.is('X')) && (isVisualCharMode() || isVisualLineMode())) { + setDotCommand(visualDotCommand() + 'X'); leaveVisualMode(); m_rangemode = RangeLineMode; m_submode = NoSubMode; @@ -2511,6 +3413,7 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) removeText(currentRange()); moveToFirstNonBlankOnLine(); } else if ((input.is('D') || input.is('X')) && isVisualBlockMode()) { + setDotCommand(visualDotCommand() + 'X'); leaveVisualMode(); m_rangemode = RangeBlockAndTailMode; yankText(currentRange(), m_register); @@ -2522,86 +3425,17 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) moveDown(linesOnScreen() / 2); handleStartOfLine(); scrollToLine(cursorLine() - sline); - finishMovement(); - } else if (input.is('e') || input.isShift(Key_Right)) { - m_movetype = MoveInclusive; - moveToWordBoundary(false, true); - setTargetColumn(); - finishMovement("%1e", count()); - } else if (input.is('E')) { - m_movetype = MoveInclusive; - moveToWordBoundary(true, true); - setTargetColumn(); - finishMovement("%1E", count()); - } else if (input.isControl('e')) { - // FIXME: this should use the "scroll" option, and "count" - if (cursorLineOnScreen() == 0) - moveDown(1); - scrollDown(1); - finishMovement(); - } else if (input.is('f')) { - m_subsubmode = FtSubSubMode; - m_movetype = MoveInclusive; - m_subsubdata = input; - } else if (input.is('F')) { - m_subsubmode = FtSubSubMode; - m_movetype = MoveExclusive; - m_subsubdata = input; - } else if (input.is('g') && !m_gflag) { + } else if (!m_gflag && input.is('g')) { m_gflag = true; - } else if (input.is('g') || input.is('G')) { - QString dotCommand = QString("%1G").arg(count()); - if (input.is('G') && m_mvcount.isEmpty()) - dotCommand = QString(QLatin1Char('G')); - if (input.is('g')) - m_gflag = false; - int n = (input.is('g')) ? 1 : linesInDocument(); - n = m_mvcount.isEmpty() ? n : count(); - if (m_submode == NoSubMode || m_submode == ZSubMode - || m_submode == CapitalZSubMode || m_submode == RegisterSubMode) { - setPosition(firstPositionInLine(n)); - handleStartOfLine(); - } else { - m_movetype = MoveLineWise; - m_rangemode = RangeLineMode; - setAnchor(); - setPosition(firstPositionInLine(n)); - } - finishMovement(dotCommand); - } else if (input.is('h') || input.isKey(Key_Left) || input.isBackspace()) { - m_movetype = MoveExclusive; - int n = qMin(count(), leftDist()); - if (m_fakeEnd && block().length() > 1) - ++n; - moveLeft(n); - setTargetColumn(); - finishMovement("%1h", count()); - } else if (input.is('H')) { - setCursor(EDITOR(cursorForPosition(QPoint(0, 0)))); - moveDown(qMax(count() - 1, 0)); - handleStartOfLine(); - finishMovement(); } else if (!isVisualMode() && (input.is('i') || input.isKey(Key_Insert))) { - setDotCommand(QString(QLatin1Char('i'))); // setDotCommand("%1i", count()); - setUndoPosition(); + setDotCommand("%1i", count()); breakEditBlock(); enterInsertMode(); - updateMiniBuffer(); if (atEndOfLine()) moveLeft(); - } else { - handled = handleCommandMode2(input); - } - return handled; -} - -EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) -{ - EventResult handled = EventHandled; - - if (input.is('I')) { + } else if (input.is('I')) { setUndoPosition(); - setDotCommand(QString(QLatin1Char('I'))); // setDotCommand("%1I", count()); + setDotCommand("%1I", count()); if (isVisualMode()) { int beginLine = lineForPosition(anchor()); int endLine = lineForPosition(position()); @@ -2612,97 +3446,25 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) moveToStartOfLine(); else moveToFirstNonBlankOnLine(); - m_gflag = false; //m_tc.clearSelection(); } breakEditBlock(); enterInsertMode(); } else if (input.isControl('i')) { - if (!m_jumpListRedo.isEmpty()) { - m_jumpListUndo.append(cursorPosition()); - setCursorPosition(m_jumpListRedo.last()); - m_jumpListRedo.pop_back(); - } - } else if (input.is('j') || input.isKey(Key_Down) - || input.isControl('j') || input.isControl('n')) { - m_movetype = MoveLineWise; - moveDown(count()); - finishMovement("%1j", count()); + jump(count()); } else if (input.is('J')) { - setDotCommand("%1J", count()); + moveBehindEndOfLine(); + const int pos = position(); beginEditBlock(); - if (m_submode == NoSubMode) { - for (int i = qMax(count(), 2) - 1; --i >= 0; ) { - moveBehindEndOfLine(); - setAnchor(); - moveRight(); - if (m_gflag) { - removeText(currentRange()); - } else { - while (characterAtCursor() == ' ' - || characterAtCursor() == '\t') - moveRight(); - removeText(currentRange()); - cursor().insertText(QString(QLatin1Char(' '))); - } - } - if (!m_gflag) - moveLeft(); - } + if (m_submode == NoSubMode) + joinLines(count(), m_gflag); endEditBlock(); - finishMovement(); - } else if (input.is('k') || input.isKey(Key_Up) || input.isControl('p')) { - m_movetype = MoveLineWise; - moveUp(count()); - finishMovement("%1k", count()); - } else if (input.is('l') || input.isKey(Key_Right) || input.is(' ')) { - m_movetype = MoveExclusive; - bool pastEnd = count() >= rightDist() - 1; - moveRight(qMax(0, qMin(count(), rightDist() - (m_submode == NoSubMode)))); - setTargetColumn(); - if (pastEnd && isVisualMode()) - m_visualTargetColumn = -1; - finishMovement("%1l", count()); - } else if (input.is('L')) { - QTextCursor tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height())))); - setCursor(tc); - moveUp(qMax(count(), 1)); - handleStartOfLine(); - finishMovement(); + setPosition(pos); + setDotCommand("%1J", count()); } else if (input.isControl('l')) { // screen redraw. should not be needed } else if (input.is('m')) { - if (m_gflag) { - moveToStartOfLine(); - moveRight(qMin(columnsOnScreen() / 2, rightDist()) - 1); - setTargetColumn(); - finishMovement(); - } else { - m_subsubmode = MarkSubSubMode; - } - } else if (input.is('M')) { - QTextCursor tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()) / 2))); - setCursor(tc); - handleStartOfLine(); - finishMovement(); - } else if (input.is('n') || input.is('N')) { - if (hasConfig(ConfigUseCoreSearch)) { - bool forward = (input.is('n')) ? m_lastSearchForward : !m_lastSearchForward; - int pos = position(); - emit q->findNextRequested(!forward); - if (forward && pos == cursor().selectionStart()) { - // if cursor is already positioned at the start of a find result, this is returned - emit q->findNextRequested(false); - } - setPosition(cursor().selectionStart()); - } else { - SearchData sd; - sd.needle = g.searchHistory.current(); - sd.forward = input.is('n') ? m_lastSearchForward : !m_lastSearchForward; - sd.highlightCursor = false; - sd.highlightMatches = true; - search(sd); - } + m_subsubmode = MarkSubSubMode; } else if (isVisualMode() && (input.is('o') || input.is('O'))) { int pos = position(); setAnchorAndPosition(pos, anchor()); @@ -2710,51 +3472,47 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) setTargetColumn(); if (m_positionPastEnd) m_visualTargetColumn = -1; - updateSelection(); - } else if (input.is('o')) { - setDotCommand("%1o", count()); - setUndoPosition(); - breakEditBlock(); - enterInsertMode(); - beginEditBlock(); - moveToFirstNonBlankOnLine(); - moveBehindEndOfLine(); - insertText(QString("\n")); - insertAutomaticIndentation(true); - endEditBlock(); - } else if (input.is('O')) { - setDotCommand("%1O", count()); + } else if (input.is('o') || input.is('O')) { + bool insertAfter = input.is('o'); + setDotCommand(insertAfter ? "%1o" : "%1O", count()); setUndoPosition(); - breakEditBlock(); enterInsertMode(); + // Insert new line so that command can be repeated [count] times inserting new line + // each time without unfolding any lines. + QTextBlock block = cursor().block(); + bool appendLine = false; + if (insertAfter) { + const int line = lineNumber(block); + appendLine = line >= document()->lineCount(); + setPosition(appendLine ? lastPositionInLine(line) : firstPositionInLine(line + 1)); + } else { + setPosition(block.position()); + } beginEditBlock(); - moveToFirstNonBlankOnLine(); - moveToStartOfLine(); insertText(QString("\n")); - moveUp(); - insertAutomaticIndentation(false); + m_lastInsertion += '\n'; + if (!appendLine) + moveUp(); + insertAutomaticIndentation(insertAfter); + setTargetColumn(); endEditBlock(); } else if (input.isControl('o')) { - if (!m_jumpListUndo.isEmpty()) { - m_jumpListRedo.append(cursorPosition()); - setCursorPosition(m_jumpListUndo.last()); - m_jumpListUndo.pop_back(); - } + jump(-count()); } else if (input.is('p') || input.is('P')) { pasteText(input.is('p')); setTargetColumn(); setDotCommand("%1p", count()); finishMovement(); } else if (input.is('r')) { - setUndoPosition(); m_submode = ReplaceSubMode; } else if (!isVisualMode() && input.is('R')) { setUndoPosition(); breakEditBlock(); enterReplaceMode(); - updateMiniBuffer(); } else if (input.isControl('r')) { - redo(); + int repeat = count(); + while (--repeat >= 0) + redo(); } else if (input.is('s') && isVisualBlockMode()) { setUndoPosition(); Range range(position(), anchor(), RangeBlockMode); @@ -2774,16 +3532,12 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) moveLeft(); setAnchor(); moveRight(qMin(count(), rightDist())); - yankText(currentRange(), m_register); - removeText(currentRange()); setDotCommand("%1s", count()); - m_opcount.clear(); - m_mvcount.clear(); - breakEditBlock(); - enterInsertMode(); + m_submode = ChangeSubMode; + finishMovement(); } else if (input.is('S')) { + m_movetype = MoveLineWise; setUndoPosition(); - beginEditBlock(); if (!isVisualMode()) { const int line = cursorLine() + 1; const int anc = firstPositionInLine(line); @@ -2791,41 +3545,32 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) setAnchorAndPosition(anc, pos); } setDotCommand("%1S", count()); - breakEditBlock(); - enterInsertMode(); m_submode = ChangeSubMode; - m_movetype = MoveLineWise; - endEditBlock(); finishMovement(); } else if (m_gflag && input.is('t')) { - m_gflag = false; handleExCommand("tabnext"); - } else if (input.is('t')) { - m_movetype = MoveInclusive; - m_subsubmode = FtSubSubMode; - m_subsubdata = input; } else if (m_gflag && input.is('T')) { - m_gflag = false; handleExCommand("tabprev"); - } else if (input.is('T')) { - m_movetype = MoveExclusive; - m_subsubmode = FtSubSubMode; - m_subsubdata = input; } else if (input.isControl('t')) { handleExCommand("pop"); - } else if (!m_gflag && input.is('u')) { - undo(); + } else if (!m_gflag && input.is('u') && !isVisualMode()) { + int repeat = count(); + while (--repeat >= 0) + undo(); } else if (input.isControl('u')) { int sline = cursorLineOnScreen(); // FIXME: this should use the "scroll" option, and "count" moveUp(linesOnScreen() / 2); handleStartOfLine(); scrollToLine(cursorLine() - sline); - finishMovement(); } else if (m_gflag && input.is('v')) { - if (m_lastSelectionCursor.hasSelection()) { - toggleVisualMode(m_lastSelectionMode); - setCursor(m_lastSelectionCursor); + if (m_lastVisualMode != NoVisualMode) { + CursorPosition from = mark('<').position; + CursorPosition to = mark('>').position; + toggleVisualMode(m_lastVisualMode); + setCursorPosition(from); + setAnchor(); + setCursorPosition(to); } } else if (input.is('v')) { toggleVisualMode(VisualCharMode); @@ -2833,29 +3578,6 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) toggleVisualMode(VisualLineMode); } else if (input.isControl('v')) { toggleVisualMode(VisualBlockMode); - } else if (input.is('w')) { // tested - // Special case: "cw" and "cW" work the same as "ce" and "cE" if the - // cursor is on a non-blank - except if the cursor is on the last - // character of a word: only the current word will be changed - if (m_submode == ChangeSubMode) { - moveToWordBoundary(false, true, true); - setTargetColumn(); - m_movetype = MoveInclusive; - } else { - moveToNextWord(false, m_submode == DeleteSubMode); - m_movetype = MoveExclusive; - } - finishMovement("%1w", count()); - } else if (input.is('W')) { - if (m_submode == ChangeSubMode) { - moveToWordBoundary(true, true, true); - setTargetColumn(); - m_movetype = MoveInclusive; - } else { - moveToNextWord(true, m_submode == DeleteSubMode); - m_movetype = MoveExclusive; - } - finishMovement("%1W", count()); } else if (input.isControl('w')) { m_submode = WindowSubMode; } else if (input.is('x') && isNoVisualMode()) { // = "dl" @@ -2866,7 +3588,8 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) setDotCommand("%1x", count()); finishMovement(); } else if (input.isControl('x')) { - changeNumberTextObject(false); + changeNumberTextObject(-count()); + setDotCommand("%1<c-x>", count()); } else if (input.is('X')) { if (leftDist() > 0) { setAnchor(); @@ -2874,140 +3597,312 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) yankText(currentRange(), m_register); removeText(currentRange()); } - finishMovement(); - } else if ((m_submode == YankSubMode && input.is('y')) - || (input.is('Y') && isNoVisualMode())) { - setAnchor(); - if (count() > 1) - moveDown(count()-1); - m_rangemode = RangeLineMode; - m_movetype = MoveLineWise; - m_submode = YankSubMode; - finishMovement(); + } else if (input.is('Y') && isNoVisualMode()) { + handleYankSubMode(Input('y')); } else if (input.isControl('y')) { // FIXME: this should use the "scroll" option, and "count" if (cursorLineOnScreen() == linesOnScreen() - 1) moveUp(1); scrollUp(1); - finishMovement(); } else if (input.is('y') && isNoVisualMode()) { setAnchor(); + m_movetype = MoveExclusive; m_submode = YankSubMode; } else if (input.is('y') && isVisualCharMode()) { - Range range(position(), anchor(), RangeCharMode); - range.endPos++; // MoveInclusive - yankText(range, m_register); - setPosition(qMin(position(), anchor())); - leaveVisualMode(); + m_rangemode = RangeCharMode; + m_movetype = MoveInclusive; + m_submode = YankSubMode; finishMovement(); } else if ((input.is('y') && isVisualLineMode()) || (input.is('Y') && isVisualLineMode()) || (input.is('Y') && isVisualCharMode())) { m_rangemode = RangeLineMode; - yankText(currentRange(), m_register); - setPosition(qMin(position(), anchor())); - moveToStartOfLine(); - leaveVisualMode(); + m_submode = YankSubMode; finishMovement(); } else if ((input.is('y') || input.is('Y')) && isVisualBlockMode()) { m_rangemode = RangeBlockMode; - yankText(currentRange(), m_register); - setPosition(qMin(position(), anchor())); - leaveVisualMode(); + m_movetype = MoveInclusive; + m_submode = YankSubMode; finishMovement(); } else if (input.is('z')) { m_submode = ZSubMode; } else if (input.is('Z')) { m_submode = CapitalZSubMode; - } else if (!m_gflag && input.is('~') && !isVisualMode()) { + } else if ((input.is('~') || input.is('u') || input.is('U'))) { m_movetype = MoveExclusive; - if (!atEndOfLine()) { - beginEditBlock(); + if (isVisualMode()) { + if (isVisualLineMode()) + m_rangemode = RangeLineMode; + else if (isVisualBlockMode()) + m_rangemode = RangeBlockMode; + leaveVisualMode(); + if (input.is('~')) + m_submode = InvertCaseSubMode; + else if (input.is('u')) + m_submode = DownCaseSubMode; + else if (input.is('U')) + m_submode = UpCaseSubMode; + finishMovement(); + } else if (m_gflag) { + setUndoPosition(); + if (atEndOfLine()) + moveLeft(); setAnchor(); - moveRight(qMin(count(), rightDist())); - if (input.is('~')) { - invertCase(currentRange()); - setDotCommand("%1~", count()); - } else if (input.is('u')) { - downCase(currentRange()); - setDotCommand("%1gu", count()); - } else if (input.is('U')) { - upCase(currentRange()); - setDotCommand("%1gU", count()); + if (input.is('~')) + m_submode = InvertCaseSubMode; + else if (input.is('u')) + m_submode = DownCaseSubMode; + else if (input.is('U')) + m_submode = UpCaseSubMode; + } else { + if (!atEndOfLine()) { + beginEditBlock(); + setAnchor(); + moveRight(qMin(count(), rightDist())); + if (input.is('~')) + invertCase(currentRange()); + else if (input.is('u')) + downCase(currentRange()); + else if (input.is('U')) + upCase(currentRange()); + setDotCommand(QString::fromLatin1("%1%2").arg(count()).arg(input.raw())); + endEditBlock(); } - endEditBlock(); } - finishMovement(); - } else if ((m_gflag && input.is('~') && !isVisualMode()) - || (m_gflag && input.is('u') && !isVisualMode()) - || (m_gflag && input.is('U') && !isVisualMode())) { - m_gflag = false; - m_movetype = MoveExclusive; + } else if (input.isKey(Key_Delete)) { + setAnchor(); + moveRight(qMin(1, rightDist())); + removeText(currentRange()); if (atEndOfLine()) moveLeft(); - setAnchor(); - m_submode = TransformSubMode; - if (input.is('~')) - m_subsubmode = InvertCaseSubSubMode; - if (input.is('u')) - m_subsubmode = DownCaseSubSubMode; - else if (input.is('U')) - m_subsubmode = UpCaseSubSubMode; - } else if ((input.is('~') && isVisualMode()) - || (m_gflag && input.is('u') && isVisualMode()) - || (m_gflag && input.is('U') && isVisualMode())) { - m_gflag = false; - m_movetype = MoveExclusive; + } else if (input.isControl(Key_BracketRight)) { + handleExCommand("tag"); + } else if (handleMovement(input)) { + // movement handled + } else { + handled = false; + } + + return handled; +} + +bool FakeVimHandler::Private::handleChangeDeleteSubModes(const Input &input) +{ + bool handled = false; + + if ((m_submode == ChangeSubMode && input.is('c')) + || (m_submode == DeleteSubMode && input.is('d'))) { + m_movetype = MoveLineWise; + setUndoPosition(); + const int line = cursorLine() + 1; + const int anc = firstPositionInLine(line); + const int pos = lastPositionInLine(line + count() - 1); + setAnchorAndPosition(anc, pos); + if (m_submode == ChangeSubMode) { + m_lastInsertion.clear(); + setDotCommand("%1cc", count()); + } else { + setDotCommand("%1dd", count()); + } + finishMovement(); + m_submode = NoSubMode; + handled = true; + } else { + handled = handleMovement(input); + } + + return handled; +} + +bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input) +{ + bool handled = true; + + setDotCommand(visualDotCommand() + 'r' + input.asChar()); + if (isVisualMode()) { + setUndoPosition(); if (isVisualLineMode()) m_rangemode = RangeLineMode; else if (isVisualBlockMode()) m_rangemode = RangeBlockMode; + else + m_rangemode = RangeCharMode; leaveVisualMode(); - m_submode = TransformSubMode; - if (input.is('~')) - m_subsubmode = InvertCaseSubSubMode; - else if (input.is('u')) - m_subsubmode = DownCaseSubSubMode; - else if (input.is('U')) - m_subsubmode = UpCaseSubSubMode; - finishMovement(); - } else if (input.is('[')) { - m_submode = OpenSquareSubMode; - } else if (input.is(']')) { - m_submode = CloseSquareSubMode; - } else if (input.isKey(Key_PageDown) || input.isControl('f')) { - moveDown(count() * (linesOnScreen() - 2) - cursorLineOnScreen()); - scrollToLine(cursorLine()); - handleStartOfLine(); - finishMovement(); - } else if (input.isKey(Key_PageUp) || input.isControl('b')) { - moveUp(count() * (linesOnScreen() - 2) + cursorLineOnScreen()); - scrollToLine(cursorLine() + linesOnScreen() - 2); - handleStartOfLine(); - finishMovement(); - } else if (input.isKey(Key_Delete)) { + Range range = currentRange(); + if (m_rangemode == RangeCharMode) + ++range.endPos; + Transformation tr = + &FakeVimHandler::Private::replaceByCharTransform; + transformText(range, tr, input.asChar()); + } else if (count() <= rightDist()) { + setUndoPosition(); setAnchor(); - moveRight(qMin(1, rightDist())); - removeText(currentRange()); - if (atEndOfLine()) - moveLeft(); - } else if (input.isKey(Key_BracketLeft) || input.isKey(Key_BracketRight)) { + moveRight(count()); + Range range = currentRange(); + if (input.isReturn()) { + beginEditBlock(); + replaceText(range, QString()); + insertText(QString("\n")); + endEditBlock(); + } else { + replaceText(range, QString(count(), input.asChar())); + moveRight(count() - 1); + } + setTargetColumn(); + setDotCommand("%1r" + input.text(), count()); + } else { + handled = false; + } + m_submode = NoSubMode; + finishMovement(); - } else if (input.isControl(Key_BracketRight)) { - handleExCommand("tag"); + return handled; +} + +bool FakeVimHandler::Private::handleFilterSubMode(const Input &input) +{ + return handleMovement(input); +} + +bool FakeVimHandler::Private::handleRegisterSubMode(const Input &input) +{ + bool handled = false; + + QChar reg = input.asChar(); + if (QString("*+.%#:-\"").contains(reg) || reg.isLetterOrNumber()) { + m_register = reg.unicode(); + m_rangemode = RangeLineMode; + handled = true; + } + m_submode = NoSubMode; + + return handled; +} + +bool FakeVimHandler::Private::handleShiftSubMode(const Input &input) +{ + bool handled = false; + if ((m_submode == ShiftLeftSubMode && input.is('<')) + || (m_submode == ShiftRightSubMode && input.is('>')) + || (m_submode == IndentSubMode && input.is('='))) { + m_movetype = MoveLineWise; + setUndoPosition(); + moveDown(count() - 1); + setDotCommand(QString("%2%1%1").arg(input.asChar()), count()); + finishMovement(); + handled = true; + m_submode = NoSubMode; } else { - //qDebug() << "IGNORED IN COMMAND MODE: " << key << text - // << " VISUAL: " << m_visualMode; + handled = handleMovement(input); + } + return handled; +} - // if a key which produces text was pressed, don't mark it as unhandled - // - otherwise the text would be inserted while being in command mode - if (input.text().isEmpty()) { - handled = EventUnhandled; +bool FakeVimHandler::Private::handleChangeCaseSubMode(const Input &input) +{ + bool handled = false; + if ((m_submode == InvertCaseSubMode && input.is('~')) + || (m_submode == DownCaseSubMode && input.is('u')) + || (m_submode == UpCaseSubMode && input.is('U'))) { + if (!isFirstNonBlankOnLine(position())) { + moveToStartOfLine(); + moveToFirstNonBlankOnLine(); } + setTargetColumn(); + setUndoPosition(); + setAnchor(); + setPosition(lastPositionInLine(cursorLine() + count()) + 1); + finishMovement(QString("%1%2").arg(count()).arg(input.raw())); + handled = true; + m_submode = NoSubMode; + } else { + handled = handleMovement(input); } + return handled; +} - m_positionPastEnd = (m_visualTargetColumn == -1) && isVisualMode(); +bool FakeVimHandler::Private::handleWindowSubMode(const Input &input) +{ + emit q->windowCommandRequested(input.key()); + m_submode = NoSubMode; + return EventHandled; +} + +bool FakeVimHandler::Private::handleYankSubMode(const Input &input) +{ + bool handled = false; + if (input.is('y')) { + m_movetype = MoveLineWise; + int endPos = firstPositionInLine(lineForPosition(position()) + count() - 1); + Range range(position(), endPos, RangeLineMode); + yankText(range); + m_submode = NoSubMode; + handled = true; + } else { + handled = handleMovement(input); + } + return handled; +} +bool FakeVimHandler::Private::handleZSubMode(const Input &input) +{ + bool handled = true; + bool foldMaybeClosed = false; + if (input.isReturn() || input.is('t') + || input.is('-') || input.is('b') + || input.is('.') || input.is('z')) { + // Cursor line to top/center/bottom of window. + Qt::AlignmentFlag align; + if (input.isReturn() || input.is('t')) + align = Qt::AlignTop; + else if (input.is('.') || input.is('z')) + align = Qt::AlignBottom; + else + align = Qt::AlignVCenter; + const bool moveToNonBlank = (input.is('.') || input.isReturn() || input.is('-')); + const int line = m_mvcount.isEmpty() ? -1 : firstPositionInLine(count()); + alignViewportToCursor(align, line, moveToNonBlank); + finishMovement(); + } else if (input.is('o') || input.is('c')) { + // Open/close current fold. + foldMaybeClosed = input.is('c'); + emit q->fold(count(), foldMaybeClosed); + finishMovement(); + } else if (input.is('O') || input.is('C')) { + // Recursively open/close current fold. + foldMaybeClosed = input.is('C'); + emit q->fold(-1, foldMaybeClosed); + finishMovement(); + } else if (input.is('a') || input.is('A')) { + // Toggle current fold. + foldMaybeClosed = true; + emit q->foldToggle(input.is('a') ? count() : -1); + finishMovement(); + } else if (input.is('R') || input.is('M')) { + // Open/close all folds in document. + foldMaybeClosed = input.is('M'); + emit q->foldAll(foldMaybeClosed); + finishMovement(); + } else { + handled = false; + } + if (foldMaybeClosed) + ensureCursorVisible(); + m_submode = NoSubMode; + return handled; +} + +bool FakeVimHandler::Private::handleCapitalZSubMode(const Input &input) +{ + // Recognize ZZ and ZQ as aliases for ":x" and ":q!". + bool handled = true; + if (input.is('Z')) + handleExCommand(QString(QLatin1Char('x'))); + else if (input.is('Q')) + handleExCommand("q!"); + else + handled = false; + m_submode = NoSubMode; return handled; } @@ -3016,9 +3911,7 @@ EventResult FakeVimHandler::Private::handleReplaceMode(const Input &input) if (input.isEscape()) { moveLeft(qMin(1, leftDist())); setTargetColumn(); - m_submode = NoSubMode; - m_mode = CommandMode; - finishMovement(); + enterCommandMode(); } else if (input.isKey(Key_Left)) { breakEditBlock(); moveLeft(1); @@ -3034,6 +3927,10 @@ EventResult FakeVimHandler::Private::handleReplaceMode(const Input &input) } else if (input.isKey(Key_Down)) { breakEditBlock(); moveDown(1); + } else if (input.isKey(Key_Insert)) { + m_mode = InsertMode; + } else if (input.isControl('o')) { + enterCommandMode(ReplaceMode); } else { joinPreviousEditBlock(); if (!atEndOfLine()) { @@ -3049,6 +3946,8 @@ EventResult FakeVimHandler::Private::handleReplaceMode(const Input &input) endEditBlock(); setTargetColumn(); } + updateMiniBuffer(); + return EventHandled; } @@ -3078,74 +3977,89 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input) } else { // Normal insertion. Start with '1', as one instance was // already physically inserted while typing. - QString data; - for (int i = 1; i < count(); ++i) - data += m_lastInsertion; - insertText(data); + const int repeat = count(); + if (repeat > 1) { + const QString text = m_lastInsertion; + for (int i = 1; i < repeat; ++i) { + m_lastInsertion.truncate(0); + foreach (const QChar &c, text) + handleInsertMode(Input(c)); + } + m_lastInsertion = text; + } moveLeft(qMin(1, leftDist())); setTargetColumn(); leaveVisualMode(); breakEditBlock(); } + // If command is 'o' or 'O' don't include the first line feed in dot command. + if (g.dotCommand.endsWith(QChar('o'), Qt::CaseInsensitive)) + m_lastInsertion.remove(0, 1); g.dotCommand += m_lastInsertion; g.dotCommand += QChar(27); enterCommandMode(); - m_submode = NoSubMode; m_ctrlVActive = false; m_opcount.clear(); m_mvcount.clear(); } else if (m_ctrlVActive) { insertInInsertMode(input.raw()); + } else if (input.isControl('o')) { + enterCommandMode(InsertMode); } else if (input.isControl('v')) { m_ctrlVActive = true; } else if (input.isControl('w')) { int endPos = position(); - moveToWordBoundary(false, false, false); + moveToNextWordStart(count(), false, false); setTargetColumn(); int beginPos = position(); Range range(beginPos, endPos, RangeCharMode); removeText(range); } else if (input.isKey(Key_Insert)) { - if (m_mode == ReplaceMode) - m_mode = InsertMode; - else - m_mode = ReplaceMode; + m_mode = ReplaceMode; } else if (input.isKey(Key_Left)) { moveLeft(count()); setTargetColumn(); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isControl(Key_Left)) { - moveToWordBoundary(false, false); + moveToNextWordStart(count(), false, false); setTargetColumn(); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isKey(Key_Down)) { //removeAutomaticIndentation(); m_submode = NoSubMode; moveDown(count()); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isKey(Key_Up)) { //removeAutomaticIndentation(); m_submode = NoSubMode; moveUp(count()); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isKey(Key_Right)) { moveRight(count()); setTargetColumn(); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isControl(Key_Right)) { - moveToWordBoundary(false, true); + moveToNextWordStart(count(), false, true); moveRight(); // we need one more move since we are in insert mode setTargetColumn(); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isKey(Key_Home)) { moveToStartOfLine(); setTargetColumn(); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isKey(Key_End)) { if (count() > 1) moveDown(count() - 1); moveBehindEndOfLine(); setTargetColumn(); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isReturn()) { joinPreviousEditBlock(); @@ -3189,10 +4103,12 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input) } else if (input.isKey(Key_PageDown) || input.isControl('f')) { removeAutomaticIndentation(); moveDown(count() * (linesOnScreen() - 2)); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isKey(Key_PageUp) || input.isControl('b')) { removeAutomaticIndentation(); moveUp(count() * (linesOnScreen() - 2)); + breakEditBlock(); m_lastInsertion.clear(); } else if (input.isKey(Key_Tab)) { m_justAutoIndented = 0; @@ -3227,8 +4143,8 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input) //} else if (key >= control('a') && key <= control('z')) { // // ignore these } else if (input.isControl('p') || input.isControl('n')) { - QTextCursor tc = EDITOR(textCursor()); - moveToWordBoundary(false, false); + QTextCursor tc = cursor(); + moveToNextWordStart(count(), false, false); QString str = selectText(Range(position(), tc.position())); setCursor(tc); emit q->simpleCompletionRequested(str, input.isControl('n')); @@ -3264,201 +4180,188 @@ void FakeVimHandler::Private::insertInInsertMode(const QString &text) EventResult FakeVimHandler::Private::handleExMode(const Input &input) { if (input.isEscape()) { - m_commandBuffer.clear(); - enterCommandMode(); - updateMiniBuffer(); + g.commandBuffer.clear(); + enterCommandMode(g.returnToMode); + resetCommandMode(); m_ctrlVActive = false; } else if (m_ctrlVActive) { - m_commandBuffer.insertChar(input.raw()); + g.commandBuffer.insertChar(input.raw()); m_ctrlVActive = false; } else if (input.isControl('v')) { m_ctrlVActive = true; + return EventHandled; } else if (input.isBackspace()) { - if (m_commandBuffer.isEmpty()) { - m_commandPrefix.clear(); - enterCommandMode(); + if (g.commandBuffer.isEmpty()) { + enterCommandMode(g.returnToMode); + resetCommandMode(); } else { - m_commandBuffer.deleteChar(); + g.commandBuffer.deleteChar(); } - updateMiniBuffer(); } else if (input.isKey(Key_Tab)) { - QStringList completions; - foreach (const QString &entry, g.commandHistory.items()) { - if (entry.startsWith(m_commandBuffer.contents())) - completions.append(entry); - } - qDebug() << completions; + // FIXME: Complete actual commands. + g.commandBuffer.historyUp(); } else if (input.isKey(Key_Left)) { - m_commandBuffer.moveLeft(); - updateMiniBuffer(); + g.commandBuffer.moveLeft(); } else if (input.isReturn()) { - if (!m_commandBuffer.isEmpty()) { - //g.commandHistory.takeLast(); - g.commandHistory.append(m_commandBuffer.contents()); - handleExCommand(m_commandBuffer.contents()); - if (m_textedit || m_plaintextedit) - leaveVisualMode(); - } - updateMiniBuffer(); + showMessage(MessageCommand, g.commandBuffer.display()); + handleExCommand(g.commandBuffer.contents()); + g.commandBuffer.clear(); + if (m_textedit || m_plaintextedit) + leaveVisualMode(); } else if (input.isKey(Key_Up) || input.isKey(Key_PageUp)) { - g.commandHistory.up(); - m_commandBuffer.setContents(g.commandHistory.current()); - updateMiniBuffer(); + g.commandBuffer.historyUp(); } else if (input.isKey(Key_Down) || input.isKey(Key_PageDown)) { - g.commandHistory.down(); - m_commandBuffer.setContents(g.commandHistory.current()); - updateMiniBuffer(); - } else if (m_commandBuffer.handleInput(input)) { - updateMiniBuffer(); - } else { + g.commandBuffer.historyDown(); + } else if (!g.commandBuffer.handleInput(input)) { qDebug() << "IGNORED IN EX-MODE: " << input.key() << input.text(); return EventUnhandled; } + updateMiniBuffer(); return EventHandled; } EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input) { + EventResult handled = EventHandled; + if (input.isEscape()) { - m_commandBuffer.clear(); - g.searchHistory.append(m_searchCursor.selectedText()); - m_searchCursor = QTextCursor(); - updateSelection(); - enterCommandMode(); - updateMiniBuffer(); + g.currentMessage.clear(); + g.searchBuffer.clear(); + setAnchorAndPosition(m_searchStartPosition, m_searchStartPosition); + scrollToLine(m_searchFromScreenLine); + enterCommandMode(g.returnToMode); + resetCommandMode(); } else if (input.isBackspace()) { - if (m_commandBuffer.isEmpty()) { - m_commandPrefix.clear(); - m_searchCursor = QTextCursor(); - enterCommandMode(); + if (g.searchBuffer.isEmpty()) { + resetCommandMode(); } else { - m_commandBuffer.deleteChar(); + g.searchBuffer.deleteChar(); } - updateMiniBuffer(); } else if (input.isKey(Key_Left)) { - m_commandBuffer.moveLeft(); - updateMiniBuffer(); + g.searchBuffer.moveLeft(); } else if (input.isKey(Key_Right)) { - m_commandBuffer.moveRight(); - updateMiniBuffer(); + g.searchBuffer.moveRight(); } else if (input.isReturn()) { - m_searchCursor = QTextCursor(); - QString needle = m_commandBuffer.contents(); - if (!needle.isEmpty()) { - g.searchHistory.append(needle); - if (!hasConfig(ConfigIncSearch)) { - SearchData sd; - sd.needle = needle; - sd.forward = m_lastSearchForward; - sd.highlightCursor = false; - sd.highlightMatches = true; - search(sd); - } - finishMovement(m_commandPrefix + needle + '\n'); + const QString &needle = g.searchBuffer.contents(); + if (!needle.isEmpty()) + g.lastSearch = needle; + else + g.searchBuffer.setContents(g.lastSearch); + if (!g.lastSearch.isEmpty()) { + updateFind(true); + finishMovement(g.searchBuffer.prompt() + g.lastSearch + '\n'); + } else { + finishMovement(); } - enterCommandMode(); - highlightMatches(needle); - updateMiniBuffer(); + if (g.currentMessage.isEmpty()) + showMessage(MessageCommand, g.searchBuffer.display()); + else + handled = EventCancelled; + enterCommandMode(g.returnToMode); + resetCommandMode(); + g.searchBuffer.clear(); } else if (input.isKey(Key_Up) || input.isKey(Key_PageUp)) { - // FIXME: This and the three cases below are wrong as vim - // takes only matching entries in the history into account. - g.searchHistory.up(); - showBlackMessage(g.searchHistory.current()); + g.searchBuffer.historyUp(); } else if (input.isKey(Key_Down) || input.isKey(Key_PageDown)) { - g.searchHistory.down(); - showBlackMessage(g.searchHistory.current()); + g.searchBuffer.historyDown(); } else if (input.isKey(Key_Tab)) { - m_commandBuffer.insertChar(QChar(9)); - updateMiniBuffer(); - } else if (m_commandBuffer.handleInput(input)) { - updateMiniBuffer(); + g.searchBuffer.insertChar(QChar(9)); + } else if (!g.searchBuffer.handleInput(input)) { + //qDebug() << "IGNORED IN SEARCH MODE: " << input.key() << input.text(); + return EventUnhandled; } - if (hasConfig(ConfigIncSearch) && !input.isReturn() && !input.isEscape()) { - SearchData sd; - sd.needle = m_commandBuffer.contents(); - sd.forward = m_lastSearchForward; - sd.mustMove = false; - sd.highlightCursor = true; - sd.highlightMatches = false; - search(sd); - } + updateMiniBuffer(); - //else { - // qDebug() << "IGNORED IN SEARCH MODE: " << input.key() << input.text(); - // return EventUnhandled; - //} - return EventHandled; + if (!input.isReturn() && !input.isEscape()) + updateFind(false); + + return handled; } -// This uses 1 based line counting. -int FakeVimHandler::Private::readLineCode(QString &cmd) +// This uses 0 based line counting (hidden lines included). +int FakeVimHandler::Private::parseLineAddress(QString *cmd) { //qDebug() << "CMD: " << cmd; - if (cmd.isEmpty()) + if (cmd->isEmpty()) return -1; - QChar c = cmd.at(0); - cmd = cmd.mid(1); - if (c == '.') { - if (cmd.isEmpty()) - return cursorLine() + 1; - QChar c1 = cmd.at(0); - if (c1 == '+' || c1 == '-') { - // Repeat for things like .+4 - cmd = cmd.mid(1); - return cursorLine() + readLineCode(cmd); - } - return cursorLine() + 1; - } - if (c == '$') - return linesInDocument(); - if (c == '\'' && !cmd.isEmpty()) { - if (cmd.isEmpty()) { - showRedMessage(msgMarkNotSet(QString())); + + int result = -1; + QChar c = cmd->at(0); + if (c == '.') { // current line + result = cursorBlockNumber(); + cmd->remove(0, 1); + } else if (c == '$') { // last line + result = document()->blockCount() - 1; + cmd->remove(0, 1); + } else if (c == '\'') { // mark + cmd->remove(0, 1); + if (cmd->isEmpty()) { + showMessage(MessageError, msgMarkNotSet(QString())); return -1; } - int m = mark(cmd.at(0).unicode()); - if (m == -1) { - showRedMessage(msgMarkNotSet(cmd.at(0))); - cmd = cmd.mid(1); + c = cmd->at(0); + Mark m = mark(c); + if (!m.isValid() || !m.isLocal(m_currentFileName)) { + showMessage(MessageError, msgMarkNotSet(c)); return -1; } - cmd = cmd.mid(1); - return lineForPosition(m); - } - if (c == '-') { - int n = readLineCode(cmd); - return cursorLine() + 1 - (n == -1 ? 1 : n); - } - if (c == '+') { - int n = readLineCode(cmd); - return cursorLine() + 1 + (n == -1 ? 1 : n); - } - if (c == '\'' && !cmd.isEmpty()) { - int pos = mark(cmd.at(0).unicode()); - if (pos == -1) { - showRedMessage(msgMarkNotSet(cmd.at(0))); - cmd = cmd.mid(1); - return -1; + cmd->remove(0, 1); + result = m.position.line; + } else if (c.isDigit()) { // line with given number + result = 0; + } else if (c == '-' || c == '+') { // add or subtract from current line number + result = cursorBlockNumber(); + } else if (c == '/' || c == '?' + || (c == '\\' && cmd->size() > 1 && QString("/?&").contains(cmd->at(1)))) { + // search for expression + SearchData sd; + if (c == '/' || c == '?') { + const int end = findUnescaped(c, *cmd, 1); + if (end == -1) + return -1; + sd.needle = cmd->mid(1, end - 1); + cmd->remove(0, end + 1); + } else { + c = cmd->at(1); + cmd->remove(0, 2); + sd.needle = (c == '&') ? g.lastSubstitutePattern : g.lastSearch; } - cmd = cmd.mid(1); - return lineForPosition(pos); - } - if (c.isDigit()) { - int n = c.unicode() - '0'; - while (!cmd.isEmpty()) { - c = cmd.at(0); - if (!c.isDigit()) - break; - cmd = cmd.mid(1); - n = n * 10 + (c.unicode() - '0'); + sd.forward = (c != '?'); + const QTextBlock b = block(); + const int pos = b.position() + (sd.forward ? b.length() - 1 : 0); + QTextCursor tc = search(sd, pos, 1, true); + g.lastSearch = sd.needle; + if (tc.isNull()) + return -1; + result = tc.block().blockNumber(); + } else { + return cursorBlockNumber(); + } + + // basic arithmetic ("-3+5" or "++" means "+2" etc.) + int n = 0; + bool add = true; + int i = 0; + for (; i < cmd->size(); ++i) { + c = cmd->at(i); + if (c == '-' || c == '+') { + if (n != 0) + result = result + (add ? n - 1 : -(n - 1)); + add = c == '+'; + result = result + (add ? 1 : -1); + n = 0; + } else if (c.isDigit()) { + n = n * 10 + c.digitValue(); + } else if (!c.isSpace()) { + break; } - //qDebug() << "N: " << n; - return n; } - // Parsing failed. - cmd = c + cmd; - return -1; + if (n != 0) + result = result + (add ? n - 1 : -(n - 1)); + *cmd = cmd->mid(i).trimmed(); + + return result; } void FakeVimHandler::Private::setCurrentRange(const Range &range) @@ -3467,13 +4370,100 @@ void FakeVimHandler::Private::setCurrentRange(const Range &range) m_rangemode = range.rangemode; } -Range FakeVimHandler::Private::rangeFromCurrentLine() const +bool FakeVimHandler::Private::parseExCommmand(QString *line, ExCommand *cmd) { - Range range; - int line = cursorLine() + 1; - range.beginPos = firstPositionInLine(line); - range.endPos = lastPositionInLine(line); - return range; + *cmd = ExCommand(); + if (line->isEmpty()) + return false; + + // remove leading colons and spaces + line->remove(QRegExp("^\\s*(:+\\s*)*")); + + // parse range first + if (!parseLineRange(line, cmd)) + return false; + + // get first command from command line + QChar close; + bool subst = false; + int i = 0; + for (; i < line->size(); ++i) { + const QChar &c = line->at(i); + if (c == '\\') { + ++i; // skip escaped character + } else if (close.isNull()) { + if (c == '|') { + // split on | + break; + } else if (c == '/') { + subst = i > 0 && (line->at(i - 1) == 's'); + close = c; + } else if (c == '"' || c == '\'') { + close = c; + } + } else if (c == close) { + if (subst) + subst = false; + else + close = QChar(); + } + } + + cmd->cmd = line->mid(0, i).trimmed(); + + // command arguments starts with first non-letter character + cmd->args = cmd->cmd.section(QRegExp("(?=[^a-zA-Z])"), 1); + if (!cmd->args.isEmpty()) { + cmd->cmd.chop(cmd->args.size()); + cmd->args = cmd->args.trimmed(); + + // '!' at the end of command + cmd->hasBang = cmd->args.startsWith('!'); + if (cmd->hasBang) + cmd->args = cmd->args.mid(1).trimmed(); + } + + // remove the first command from command line + line->remove(0, i + 1); + + return true; +} + +bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd) +{ + // FIXME: that seems to be different for %w and %s + if (line->startsWith(QLatin1Char('%'))) + line->replace(0, 1, "1,$"); + + int beginLine = parseLineAddress(line); + int endLine; + if (line->startsWith(',')) { + *line = line->mid(1).trimmed(); + endLine = parseLineAddress(line); + } else { + endLine = beginLine; + } + if (beginLine == -1 || endLine == -1) + return false; + + const int beginPos = firstPositionInLine(qMin(beginLine, endLine) + 1, false); + const int endPos = lastPositionInLine(qMax(beginLine, endLine) + 1, false); + cmd->range = Range(beginPos, endPos, RangeLineMode); + cmd->count = beginLine; + + return true; +} + +void FakeVimHandler::Private::parseRangeCount(const QString &line, Range *range) const +{ + bool ok; + const int count = qAbs(line.trimmed().toInt(&ok)); + if (ok) { + const int beginLine = document()->findBlock(range->endPos).blockNumber() + 1; + const int endLine = qMin(beginLine + count - 1, document()->blockCount()); + range->beginPos = firstPositionInLine(beginLine, false); + range->endPos = lastPositionInLine(endLine, false); + } } // use handleExCommand for invoking commands that might move the cursor @@ -3483,127 +4473,93 @@ void FakeVimHandler::Private::handleCommand(const QString &cmd) } bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) - // :substitute { - QString flags; - QRegExp pattern; - QString replacement; - int count = 0; - - if (cmd.cmd.startsWith("&&")) { - flags = cmd.cmd.mid(2); - if (flags.isEmpty()) - flags = m_lastSubstituteFlags; - pattern = m_lastSubstitutePattern; - replacement = m_lastSubstituteReplacement; - count = cmd.args.section(QLatin1Char(' '), 1, 1).toInt(); - } else if (cmd.cmd.startsWith(QLatin1Char('&'))) { - flags = cmd.cmd.mid(1); - if (flags.isEmpty()) - flags = m_lastSubstituteFlags; - pattern = m_lastSubstitutePattern; - replacement = m_lastSubstituteReplacement; - count = cmd.args.section(QLatin1Char(' '), 1, 1).toInt(); - } else if (cmd.matches("s", "substitute")) { - flags = m_lastSubstituteFlags; - if (flags.isEmpty()) - flags = m_lastSubstituteFlags; - pattern = m_lastSubstitutePattern; - replacement = m_lastSubstituteReplacement; - count = cmd.args.section(QLatin1Char(' '), 2, 2).toInt(); - } else { - QString line = cmd.cmd + ' ' + cmd.args; - line = line.trimmed(); - if (line.startsWith(_("substitute"))) - line = line.mid(10); - else if (line.startsWith('s') && line.size() > 1 - && !isalpha(line.at(1).unicode())) - line = line.mid(1); - else - return false; - // we have /{pattern}/{string}/[flags] now - if (line.isEmpty()) - return false; - const QChar separator = line.at(0); - int pos1 = -1; - int pos2 = -1; - int i; - for (i = 1; i < line.size(); ++i) { - if (line.at(i) == separator && line.at(i - 1) != '\\') { - pos1 = i; - break; - } - } - if (pos1 == -1) - return false; - for (++i; i < line.size(); ++i) { - if (line.at(i) == separator && line.at(i - 1) != '\\') { - pos2 = i; - break; - } - } - if (pos2 == -1) - pos2 = line.size(); + // :substitute + if (!cmd.matches("s", "substitute") + && !(cmd.cmd.isEmpty() && !cmd.args.isEmpty() && QString("&~").contains(cmd.args[0]))) { + return false; + } - QString needle = line.mid(1, pos1 - 1); - replacement = line.mid(pos1 + 1, pos2 - pos1 - 1); - flags = line.mid(pos2 + 1); + int count = 1; + QString line = cmd.args; + const int countIndex = line.lastIndexOf(QRegExp("\\d+$")); + if (countIndex != -1) { + count = line.mid(countIndex).toInt(); + line = line.mid(0, countIndex).trimmed(); + } - needle.replace('$', '\n'); - needle.replace("\\\n", "\\$"); - pattern = vimPatternToQtPattern(needle, hasConfig(ConfigSmartCase)); + if (cmd.cmd.isEmpty()) { + // keep previous substitution flags on '&&' and '~&' + if (line.size() > 1 && line[1] == '&') + g.lastSubstituteFlags += line.mid(2); + else + g.lastSubstituteFlags = line.mid(1); + if (line[0] == '~') + g.lastSubstitutePattern = g.lastSearch; + } else { + if (line.isEmpty()) { + g.lastSubstituteFlags.clear(); + } else { + // we have /{pattern}/{string}/[flags] now + const QChar separator = line.at(0); + int pos1 = findUnescaped(separator, line, 1); + if (pos1 == -1) + return false; + int pos2 = findUnescaped(separator, line, pos1 + 1);; + if (pos2 == -1) + pos2 = line.size(); - m_lastSubstituteFlags = flags; - m_lastSubstitutePattern = pattern; - m_lastSubstituteReplacement = replacement; + g.lastSubstitutePattern = line.mid(1, pos1 - 1); + g.lastSubstituteReplacement = line.mid(pos1 + 1, pos2 - pos1 - 1); + g.lastSubstituteFlags = line.mid(pos2 + 1); + } } - if (count == 0) - count = 1; + count = qMax(1, count); + QString needle = g.lastSubstitutePattern; - if (flags.contains('i')) - pattern.setCaseSensitivity(Qt::CaseInsensitive); + if (g.lastSubstituteFlags.contains('i')) + needle.prepend("\\c"); - beginEditBlock(); - const bool global = flags.contains('g'); + QRegExp pattern = vimPatternToQtPattern(needle, hasConfig(ConfigSmartCase)); + + QTextBlock lastBlock; + QTextBlock firstBlock; + const bool global = g.lastSubstituteFlags.contains('g'); for (int a = 0; a != count; ++a) { - const Range range = cmd.range.endPos == 0 ? rangeFromCurrentLine() : cmd.range; - const int beginLine = lineForPosition(range.beginPos); - const int endLine = lineForPosition(range.endPos); - for (int line = endLine; line >= beginLine; --line) { - QString origText = lineContents(line); - QString text = origText; - int pos = 0; - while (true) { - pos = pattern.indexIn(text, pos, QRegExp::CaretAtZero); - if (pos == -1) - break; - if (pattern.cap(0).isEmpty()) - break; - QStringList caps = pattern.capturedTexts(); - QString matched = text.mid(pos, caps.at(0).size()); - QString repl = replacement; - for (int i = 1; i < caps.size(); ++i) - repl.replace("\\" + QString::number(i), caps.at(i)); - for (int i = 0; i < repl.size(); ++i) { - if (repl.at(i) == '&' && (i == 0 || repl.at(i - 1) != '\\')) { - repl.replace(i, 1, caps.at(0)); - i += caps.at(0).size(); - } + for (QTextBlock block = document()->findBlock(cmd.range.endPos); + block.isValid() && block.position() + block.length() > cmd.range.beginPos; + block = block.previous()) { + QString text = block.text(); + if (substituteText(&text, pattern, g.lastSubstituteReplacement, global)) { + firstBlock = block; + if (!lastBlock.isValid()) { + lastBlock = block; + beginEditBlock(); } - repl.replace("\\&", "&"); - text = text.left(pos) + repl + text.mid(pos + matched.size()); - pos += repl.size(); - if (!global) - break; + QTextCursor tc = cursor(); + const int pos = block.position(); + const int anchor = pos + block.length() - 1; + tc.setPosition(anchor); + tc.setPosition(pos, KeepAnchor); + tc.insertText(text); } - if (text != origText) - setLineContents(line, text); } } - moveToStartOfLine(); - setTargetColumn(); - endEditBlock(); + + if (lastBlock.isValid()) { + State &state = m_undo.top(); + state.position = CursorPosition(firstBlock.blockNumber(), 0); + + leaveVisualMode(); + setPosition(lastBlock.position()); + setAnchor(); + moveToFirstNonBlankOnLine(); + setTargetColumn(); + + endEditBlock(); + } + return true; } @@ -3650,31 +4606,49 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map else return false; - const int pos = cmd0.args.indexOf(QLatin1Char(' ')); - if (pos == -1) { + QString args = cmd0.args; + bool silent = false; + bool unique = false; + forever { + if (eatString("<silent>", &args)) { + silent = true; + } else if (eatString("<unique>", &args)) { + continue; + } else if (eatString("<special>", &args)) { + continue; + } else if (eatString("<buffer>", &args)) { + notImplementedYet(); + continue; + } else if (eatString("<script>", &args)) { + notImplementedYet(); + continue; + } else if (eatString("<expr>", &args)) { + notImplementedYet(); + return true; + } + break; + } + + const QString lhs = args.section(QRegExp("\\s+"), 0, 0); + const QString rhs = args.section(QRegExp("\\s+"), 1); + if ((rhs.isNull() && type != Unmap) || (!rhs.isNull() && type == Unmap)) { // FIXME: Dump mappings here. //qDebug() << g.mappings; return true; } - QString lhs = cmd0.args.left(pos); - QString rhs = cmd0.args.mid(pos + 1); - Inputs key; - key.parseFrom(lhs); + Inputs key(lhs); //qDebug() << "MAPPING: " << modes << lhs << rhs; switch (type) { case Unmap: foreach (char c, modes) - if (g.mappings.contains(c)) - g.mappings[c].remove(key); + MappingsIterator(&g.mappings, c, key).remove(); break; - case Map: - rhs = rhs; // FIXME: expand rhs. - // Fall through. + case Map: // fall through case Noremap: { - Inputs inputs(rhs); + Inputs inputs(rhs, type == Noremap, silent); foreach (char c, modes) - g.mappings[c].insert(key, inputs); + MappingsIterator(&g.mappings, c).setInputs(key, inputs, unique); break; } } @@ -3691,7 +4665,7 @@ bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd) QString info; info += "# command history\n"; int i = 0; - foreach (const QString &item, g.commandHistory.items()) { + foreach (const QString &item, g.commandBuffer.historyItems()) { ++i; info += QString("%1 %2\n").arg(i, -8).arg(item); } @@ -3736,10 +4710,10 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) if (!cmd.matches("se", "set")) return false; - showBlackMessage(QString()); + clearMessage(); SavedAction *act = theFakeVimSettings()->item(cmd.args); QTC_CHECK(!cmd.args.isEmpty()); // Handled by plugin. - if (act && act->value().type() == QVariant::Bool) { + if (act && act->value().canConvert(QVariant::Bool)) { // Boolean config to be switched on. bool oldValue = act->value().toBool(); if (oldValue == false) @@ -3748,7 +4722,7 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) {} // nothing to do } else if (act) { // Non-boolean to show. - showBlackMessage(cmd.args + '=' + act->value().toString()); + showMessage(MessageInfo, cmd.args + '=' + act->value().toString()); } else if (cmd.args.startsWith(_("no")) && (act = theFakeVimSettings()->item(cmd.args.mid(2)))) { // Boolean config to be switched off. @@ -3763,9 +4737,9 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) QString error = theFakeVimSettings() ->trySetValue(cmd.args.left(p), cmd.args.mid(p + 1)); if (!error.isEmpty()) - showRedMessage(error); + showMessage(MessageError, error); } else { - showRedMessage(FakeVimHandler::tr("Unknown option: ") + cmd.args); + showMessage(MessageError, FakeVimHandler::tr("Unknown option: ") + cmd.args); } updateMiniBuffer(); updateEditor(); @@ -3778,25 +4752,154 @@ bool FakeVimHandler::Private::handleExNormalCommand(const ExCommand &cmd) if (!cmd.matches("norm", "normal")) return false; //qDebug() << "REPLAY NORMAL: " << quoteUnprintable(reNormal.cap(3)); - replay(cmd.args, 1); + replay(cmd.args); return true; } -bool FakeVimHandler::Private::handleExDeleteCommand(const ExCommand &cmd) +bool FakeVimHandler::Private::handleExYankDeleteCommand(const ExCommand &cmd) { - // :d[elete] - if (!cmd.matches("d", "delete")) + // :[range]d[elete] [x] [count] + // :[range]y[ank] [x] [count] + const bool remove = cmd.matches("d", "delete"); + if (!remove && !cmd.matches("y", "yank")) return false; - Range range = cmd.range.endPos == 0 ? rangeFromCurrentLine() : cmd.range; - setCurrentRange(range); - QString reg = cmd.args; - QString text = selectText(range); + // get register from arguments + const bool hasRegisterArg = !cmd.args.isEmpty() && !cmd.args.at(0).isDigit(); + const int r = hasRegisterArg ? cmd.args.at(0).unicode() : m_register; + + // get [count] from arguments + Range range = cmd.range; + parseRangeCount(cmd.args.mid(hasRegisterArg ? 1 : 0).trimmed(), &range); + + yankText(range, r); + + if (remove) { + leaveVisualMode(); + setPosition(range.beginPos); + setUndoPosition(); + setCurrentRange(range); + removeText(currentRange()); + } + + return true; +} + +bool FakeVimHandler::Private::handleExChangeCommand(const ExCommand &cmd) +{ + // :[range]c[hange] + if (!cmd.matches("c", "change")) + return false; + + const bool oldAutoIndent = hasConfig(ConfigAutoIndent); + // Temporarily set autoindent if ! is present. + if (cmd.hasBang) + theFakeVimSetting(ConfigAutoIndent)->setValue(true, false); + + Range range = cmd.range; + range.rangemode = RangeLineModeExclusive; + removeText(range); + insertAutomaticIndentation(true); + + // FIXME: In Vim same or less number of lines can be inserted and position after insertion is + // beginning of last inserted line. + enterInsertMode(); + + if (cmd.hasBang && !oldAutoIndent) + theFakeVimSetting(ConfigAutoIndent)->setValue(false, false); + + return true; +} + +bool FakeVimHandler::Private::handleExMoveCommand(const ExCommand &cmd) +{ + // :[range]m[ove] {address} + if (!cmd.matches("m", "move")) + return false; + + QString lineCode = cmd.args; + + const int startLine = document()->findBlock(cmd.range.beginPos).blockNumber(); + const int endLine = document()->findBlock(cmd.range.endPos).blockNumber(); + const int lines = endLine - startLine + 1; + + int targetLine = lineCode == "0" ? -1 : parseLineAddress(&lineCode); + if (targetLine >= startLine && targetLine < endLine) { + showMessage(MessageError, FakeVimHandler::tr("Move lines into themselves")); + return true; + } + + CursorPosition lastAnchor = mark('<').position; + CursorPosition lastPosition = mark('>').position; + + recordJump(); + setPosition(cmd.range.beginPos); + setUndoPosition(); + + setCurrentRange(cmd.range); + QString text = selectText(cmd.range); removeText(currentRange()); - if (!reg.isEmpty()) { - const int r = reg.at(0).unicode(); - setRegister(r, text, RangeLineMode); + + const bool insertAtEnd = targetLine == document()->blockCount(); + if (targetLine >= startLine) + targetLine -= lines; + QTextBlock block = document()->findBlockByNumber(insertAtEnd ? targetLine : targetLine + 1); + setPosition(block.position()); + setAnchor(); + + if (insertAtEnd) { + moveBehindEndOfLine(); + text.chop(1); + insertText(QString('\n')); + } + insertText(text); + + if (!insertAtEnd) + moveUp(1); + if (hasConfig(ConfigStartOfLine)) + moveToFirstNonBlankOnLine(); + + // correct last selection + leaveVisualMode(); + if (lastAnchor.line >= startLine && lastAnchor.line <= endLine) + lastAnchor.line += targetLine - startLine + 1; + if (lastPosition.line >= startLine && lastPosition.line <= endLine) + lastPosition.line += targetLine - startLine + 1; + setMark('<', lastAnchor); + setMark('>', lastPosition); + + if (lines > 2) + showMessage(MessageInfo, FakeVimHandler::tr("%1 lines moved").arg(lines)); + + return true; +} + +bool FakeVimHandler::Private::handleExJoinCommand(const ExCommand &cmd) +{ + // :[range]j[oin][!] [count] + // FIXME: Argument [count] can follow immediately. + if (!cmd.matches("j", "join")) + return false; + + // get [count] from arguments + bool ok; + int count = cmd.args.toInt(&ok); + + if (ok) { + setPosition(cmd.range.endPos); + } else { + setPosition(cmd.range.beginPos); + const int startLine = document()->findBlock(cmd.range.beginPos).blockNumber(); + const int endLine = document()->findBlock(cmd.range.endPos).blockNumber(); + count = endLine - startLine + 1; } + + moveToStartOfLine(); + setUndoPosition(); + joinLines(count, cmd.hasBang); + + moveToFirstNonBlankOnLine(); + return true; } @@ -3825,7 +4928,7 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) QFile file1(fileName); const bool exists = file1.exists(); if (exists && !forced && !noArgs) { - showRedMessage(FakeVimHandler::tr + showMessage(MessageError, FakeVimHandler::tr ("File \"%1\" exists (add ! to override)").arg(fileName)); } else if (file1.open(QIODevice::ReadWrite)) { // Nobody cared, so act ourselves. @@ -3839,14 +4942,14 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) QTextStream ts(&file2); ts << contents; } else { - showRedMessage(FakeVimHandler::tr + showMessage(MessageError, FakeVimHandler::tr ("Cannot open file \"%1\" for writing").arg(fileName)); } // Check result by reading back. QFile file3(fileName); file3.open(QIODevice::ReadOnly); QByteArray ba = file3.readAll(); - showBlackMessage(FakeVimHandler::tr("\"%1\" %2 %3L, %4C written") + showMessage(MessageInfo, FakeVimHandler::tr("\"%1\" %2 %3L, %4C written") .arg(fileName).arg(exists ? " " : tr(" [New] ")) .arg(ba.count('\n')).arg(ba.size())); //if (quitAll) @@ -3854,7 +4957,7 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) //else if (quit) // passUnknownExCommand(forced ? "q!" : "q"); } else { - showRedMessage(FakeVimHandler::tr + showMessage(MessageError, FakeVimHandler::tr ("Cannot open file \"%1\" for reading").arg(fileName)); } return true; @@ -3877,14 +4980,14 @@ bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd) QString data = ts.readAll(); insertText(data); endEditBlock(); - showBlackMessage(FakeVimHandler::tr("\"%1\" %2L, %3C") + showMessage(MessageInfo, FakeVimHandler::tr("\"%1\" %2L, %3C") .arg(m_currentFileName).arg(data.count('\n')).arg(data.size())); return true; } bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! { - if (!cmd.cmd.startsWith(QLatin1Char('!'))) + if (!cmd.cmd.isEmpty() || !cmd.hasBang) return false; setCurrentRange(cmd.range); @@ -3894,9 +4997,8 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! QProcess proc; proc.start(command); proc.waitForStarted(); -#ifdef Q_OS_WIN - text.replace(_("\n"), _("\r\n")); -#endif + if (Utils::HostOsInfo::isWindowsHost()) + text.replace(_("\n"), _("\r\n")); proc.write(text.toUtf8()); proc.closeWriteChannel(); proc.waitForFinished(); @@ -3911,7 +5013,7 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! endEditBlock(); leaveVisualMode(); //qDebug() << "FILTER: " << command; - showBlackMessage(FakeVimHandler::tr("%n lines filtered", 0, + showMessage(MessageInfo, FakeVimHandler::tr("%n lines filtered", 0, text.count('\n'))); } return true; @@ -3919,23 +5021,35 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! bool FakeVimHandler::Private::handleExShiftCommand(const ExCommand &cmd) { - if (cmd.cmd != "<" && cmd.cmd != ">") + // :[range]{<|>}* [count] + if (!cmd.cmd.isEmpty() || (!cmd.args.startsWith('<') && !cmd.args.startsWith('>'))) return false; + const QChar c = cmd.args.at(0); + + // get number of repetition + int repeat = 1; + int i = 1; + for (; i < cmd.args.size(); ++i) { + const QChar c2 = cmd.args.at(i); + if (c2 == c) + ++repeat; + else if (!c2.isSpace()) + break; + } + + // get [count] from arguments Range range = cmd.range; - if (cmd.range.endPos == 0) - range = rangeFromCurrentLine(); + parseRangeCount(cmd.args.mid(i), &range); + setCurrentRange(range); - int count = qMax(1, cmd.args.toInt()); - if (cmd.cmd == "<") - shiftRegionLeft(count); + if (c == '<') + shiftRegionLeft(repeat); else - shiftRegionRight(count); + shiftRegionRight(repeat); + leaveVisualMode(); - const int beginLine = lineForPosition(range.beginPos); - const int endLine = lineForPosition(range.endPos); - showBlackMessage(FakeVimHandler::tr("%n lines %1ed %2 time", 0, - (endLine - beginLine + 1)).arg(cmd.cmd).arg(count)); + return true; } @@ -3945,31 +5059,32 @@ bool FakeVimHandler::Private::handleExNohlsearchCommand(const ExCommand &cmd) if (!cmd.cmd.startsWith("noh")) return false; - m_searchSelections.clear(); - updateSelection(); + highlightMatches(QString()); return true; } -bool FakeVimHandler::Private::handleExRedoCommand(const ExCommand &cmd) +bool FakeVimHandler::Private::handleExUndoRedoCommand(const ExCommand &cmd) { + // :undo // :redo - if (cmd.cmd != "red" && cmd.cmd != "redo") + bool undo = (cmd.cmd == "u" || cmd.cmd == "un" || cmd.cmd == "undo"); + if (!undo && cmd.cmd != "red" && cmd.cmd != "redo") return false; - redo(); + undoRedo(undo); updateMiniBuffer(); return true; } bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd) { - // :<nr> - if (!cmd.cmd.isEmpty()) + // :{address} + if (!cmd.cmd.isEmpty() || !cmd.args.isEmpty()) return false; - const int beginLine = lineForPosition(cmd.range.beginPos); + const int beginLine = lineForPosition(cmd.range.endPos); setPosition(firstPositionInLine(beginLine)); - showBlackMessage(QString()); + clearMessage(); return true; } @@ -3982,30 +5097,44 @@ bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) QString fileName = cmd.args; QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { - showRedMessage(FakeVimHandler::tr("Cannot open file %1").arg(fileName)); + showMessage(MessageError, FakeVimHandler::tr("Cannot open file %1").arg(fileName)); return true; } bool inFunction = false; - while (!file.atEnd()) { - QByteArray line = file.readLine(); - line = line.trimmed(); + QByteArray line; + while (!file.atEnd() || !line.isEmpty()) { + QByteArray nextline = !file.atEnd() ? file.readLine() : QByteArray(); + + // remove comment + int i = nextline.lastIndexOf('"'); + if (i != -1) + nextline = nextline.remove(i, nextline.size() - i); + + nextline = nextline.trimmed(); + + // multi-line command? + if (nextline.startsWith('\\')) { + line += nextline.mid(1); + continue; + } + if (line.startsWith("function")) { //qDebug() << "IGNORING FUNCTION" << line; inFunction = true; } else if (inFunction && line.startsWith("endfunction")) { inFunction = false; - } else if (line.startsWith("function")) { - //qDebug() << "IGNORING FUNCTION" << line; - inFunction = true; - } else if (line.startsWith('"')) { - // A comment. } else if (!line.isEmpty() && !inFunction) { //qDebug() << "EXECUTING: " << line; ExCommand cmd; - cmd.setContentsFromLine(QString::fromLocal8Bit(line)); - handleExCommandHelper(cmd); + QString commandLine = QString::fromLocal8Bit(line); + while (parseExCommmand(&commandLine, &cmd)) { + if (!handleExCommandHelper(cmd)) + break; + } } + + line = nextline; } file.close(); return true; @@ -4016,7 +5145,7 @@ bool FakeVimHandler::Private::handleExEchoCommand(const ExCommand &cmd) // :echo if (cmd.cmd != "echo") return false; - m_currentMessage = cmd.args; + showMessage(MessageInfo, cmd.args); return true; } @@ -4028,51 +5157,45 @@ void FakeVimHandler::Private::handleExCommand(const QString &line0) line.chop(1); int percent = line.toInt(); setPosition(firstPositionInLine(percent * linesInDocument() / 100)); - showBlackMessage(QString()); + clearMessage(); return; } - // FIXME: that seems to be different for %w and %s - if (line.startsWith(QLatin1Char('%'))) - line = "1,$" + line.mid(1); + //qDebug() << "CMD: " << cmd; - const int beginLine = readLineCode(line); - int endLine = -1; - if (line.startsWith(',')) { - line = line.mid(1); - endLine = readLineCode(line); - } - if (beginLine != -1 && endLine == -1) - endLine = beginLine; + enterCommandMode(g.returnToMode); + + beginLargeEditBlock(); ExCommand cmd; - cmd.setContentsFromLine(line); - if (beginLine != -1) { - const int beginPos = firstPositionInLine(beginLine); - const int endPos = lastPositionInLine(endLine); - cmd.range = Range(beginPos, endPos, RangeLineMode); - cmd.count = beginLine; + QString lastCommand = line; + while (parseExCommmand(&line, &cmd)) { + if (!handleExCommandHelper(cmd)) { + showMessage(MessageError, tr("Not an editor command: %1").arg(lastCommand)); + break; + } + lastCommand = line; } - //qDebug() << "CMD: " << cmd; + endEditBlock(); - enterCommandMode(); - showBlackMessage(QString()); - if (!handleExCommandHelper(cmd)) - showRedMessage(tr("Not an editor command: %1").arg(cmd.cmd)); + resetCommandMode(); } -bool FakeVimHandler::Private::handleExCommandHelper(const ExCommand &cmd) +bool FakeVimHandler::Private::handleExCommandHelper(ExCommand &cmd) { return handleExPluginCommand(cmd) || handleExGotoCommand(cmd) || handleExBangCommand(cmd) || handleExHistoryCommand(cmd) || handleExRegisterCommand(cmd) - || handleExDeleteCommand(cmd) + || handleExYankDeleteCommand(cmd) + || handleExChangeCommand(cmd) + || handleExMoveCommand(cmd) + || handleExJoinCommand(cmd) || handleExMapCommand(cmd) || handleExNohlsearchCommand(cmd) || handleExNormalCommand(cmd) || handleExReadCommand(cmd) - || handleExRedoCommand(cmd) + || handleExUndoRedoCommand(cmd) || handleExSetCommand(cmd) || handleExShiftCommand(cmd) || handleExSourceCommand(cmd) @@ -4111,123 +5234,147 @@ void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar o // Making this unconditional feels better, but is not "vim like". if (oldLine != cursorLine() - cursorLineOnScreen()) scrollToLine(cursorLine() - linesOnScreen() / 2); + recordJump(); setPosition(pos); setTargetColumn(); - updateSelection(); - recordJump(); return; } } } -void FakeVimHandler::Private::search(const SearchData &sd) +QTextCursor FakeVimHandler::Private::search(const SearchData &sd, int startPos, int count, + bool showMessages) { - if (sd.needle.isEmpty()) - return; - - const bool incSearch = hasConfig(ConfigIncSearch); - QTextDocument::FindFlags flags = QTextDocument::FindCaseSensitively; - if (!sd.forward) - flags |= QTextDocument::FindBackward; - QRegExp needleExp = vimPatternToQtPattern(sd.needle, hasConfig(ConfigSmartCase)); + if (!needleExp.isValid()) { + if (showMessages) { + QString error = needleExp.errorString(); + showMessage(MessageError, + FakeVimHandler::tr("Invalid regular expression: %1").arg(error)); + } + if (sd.highlightMatches) + highlightMatches(QString()); + return QTextCursor(); + } - const int oldLine = cursorLine() - cursorLineOnScreen(); + int repeat = count; + const int pos = startPos + (sd.forward ? 1 : -1); - int startPos = position(); - if (sd.mustMove) - sd.forward ? ++startPos : --startPos; + QTextCursor tc; + if (pos >= 0 && pos < document()->characterCount()) { + tc = QTextCursor(document()); + tc.setPosition(pos); + if (sd.forward && afterEndOfLine(document(), pos)) + tc.movePosition(Right); + + if (!tc.isNull()) { + if (sd.forward) + searchForward(&tc, needleExp, &repeat); + else + searchBackward(&tc, needleExp, &repeat); + } + } - m_searchCursor = QTextCursor(); - QTextCursor tc = document()->find(needleExp, startPos, flags); if (tc.isNull()) { - int startPos = sd.forward ? 0 : lastPositionInDocument(); - tc = document()->find(needleExp, startPos, flags); - if (tc.isNull()) { - if (!incSearch) { - highlightMatches(QString()); - showRedMessage(FakeVimHandler::tr("Pattern not found: %1") - .arg(needleExp.pattern())); + if (hasConfig(ConfigWrapScan)) { + tc = QTextCursor(document()); + tc.movePosition(sd.forward ? StartOfDocument : EndOfDocument); + if (sd.forward) + searchForward(&tc, needleExp, &repeat); + else + searchBackward(&tc, needleExp, &repeat); + if (tc.isNull()) { + if (showMessages) { + showMessage(MessageError, + FakeVimHandler::tr("Pattern not found: %1").arg(sd.needle)); + } + } else if (showMessages) { + QString msg = sd.forward + ? FakeVimHandler::tr("search hit BOTTOM, continuing at TOP") + : FakeVimHandler::tr("search hit TOP, continuing at BOTTOM"); + showMessage(MessageWarning, msg); } - updateSelection(); - return; - } - if (!incSearch) { + } else if (showMessages) { QString msg = sd.forward - ? FakeVimHandler::tr("search hit BOTTOM, continuing at TOP") - : FakeVimHandler::tr("search hit TOP, continuing at BOTTOM"); - showRedMessage(msg); + ? FakeVimHandler::tr("search hit BOTTOM without match for: %1") + : FakeVimHandler::tr("search hit TOP without match for: %1"); + showMessage(MessageError, msg.arg(sd.needle)); } } - // Set Cursor. In contrast to the main editor we have the cursor - // position before the anchor position. - setAnchorAndPosition(tc.position(), tc.anchor()); + if (sd.highlightMatches) + highlightMatches(needleExp.pattern()); + + return tc; +} + +void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages) +{ + const int oldLine = cursorLine() - cursorLineOnScreen(); + + QTextCursor tc = search(sd, m_searchStartPosition, count(), showMessages); + if (tc.isNull()) { + tc = cursor(); + tc.setPosition(m_searchStartPosition); + } + + if (isVisualMode()) { + int d = tc.anchor() - tc.position(); + setPosition(tc.position() + d); + } else { + // Set Cursor. In contrast to the main editor we have the cursor + // position before the anchor position. + setAnchorAndPosition(tc.position(), tc.anchor()); + } // Making this unconditional feels better, but is not "vim like". if (oldLine != cursorLine() - cursorLineOnScreen()) scrollToLine(cursorLine() - linesOnScreen() / 2); - if (incSearch && sd.highlightCursor) - m_searchCursor = cursor(); + m_searchCursor = cursor(); setTargetColumn(); +} - if (sd.highlightMatches) - highlightMatches(sd.needle); - updateSelection(); +void FakeVimHandler::Private::searchNext(bool forward) +{ + SearchData sd; + sd.needle = g.lastSearch; + sd.forward = forward ? g.lastSearchForward : !g.lastSearchForward; + sd.highlightMatches = true; + m_searchStartPosition = position(); + showMessage(MessageCommand, (g.lastSearchForward ? '/' : '?') + sd.needle); recordJump(); + search(sd); } void FakeVimHandler::Private::highlightMatches(const QString &needle) { - if (!hasConfig(ConfigHlSearch)) - return; - if (needle == m_oldNeedle) + if (!hasConfig(ConfigHlSearch) || needle == m_oldNeedle) return; m_oldNeedle = needle; - m_searchSelections.clear(); - if (!needle.isEmpty()) { - QTextCursor tc = cursor(); - tc.movePosition(StartOfDocument, MoveAnchor); - QRegExp needleExp = vimPatternToQtPattern(needle, hasConfig(ConfigSmartCase)); - if (!needleExp.isValid()) { - QString error = needleExp.errorString(); - showRedMessage( - FakeVimHandler::tr("Invalid regular expression: %1").arg(error)); - return; - } - - while (!tc.atEnd()) { - tc = tc.document()->find(needleExp, tc.position()); - if (tc.isNull()) - break; - if (!tc.hasSelection()) - tc.movePosition(Right, KeepAnchor, 1); - QTextEdit::ExtraSelection sel; - sel.cursor = tc; - sel.format = tc.blockCharFormat(); - sel.format.setBackground(QColor(177, 177, 0)); - m_searchSelections.append(sel); - if (document()->characterAt(tc.position()) == ParagraphSeparator) - tc.movePosition(Right, MoveAnchor); - } - } - updateSelection(); + updateHighlights(); } void FakeVimHandler::Private::moveToFirstNonBlankOnLine() { - QTextDocument *doc = document(); - int firstPos = block().position(); + QTextCursor tc2 = cursor(); + moveToFirstNonBlankOnLine(&tc2); + setPosition(tc2.position()); +} + +void FakeVimHandler::Private::moveToFirstNonBlankOnLine(QTextCursor *tc) +{ + QTextDocument *doc = tc->document(); + int firstPos = tc->block().position(); for (int i = firstPos, n = firstPos + block().length(); i < n; ++i) { if (!doc->characterAt(i).isSpace() || i == n - 1) { - setPosition(i); + tc->setPosition(i); return; } } - setPosition(block().position()); + tc->setPosition(block().position()); } void FakeVimHandler::Private::indentSelectedText(QChar typedChar) @@ -4245,19 +5392,19 @@ void FakeVimHandler::Private::indentSelectedText(QChar typedChar) setTargetColumn(); setDotCommand("%1==", endLine - beginLine + 1); endEditBlock(); + + const int lines = endLine - beginLine + 1; + if (lines > 2) + showMessage(MessageInfo, FakeVimHandler::tr("%n lines indented", 0, lines)); } void FakeVimHandler::Private::indentText(const Range &range, QChar typedChar) { - int beginLine = lineForPosition(range.beginPos); - int endLine = lineForPosition(range.endPos); - if (beginLine > endLine) - qSwap(beginLine, endLine); - - // LineForPosition has returned 1-based line numbers. - emit q->indentRegion(beginLine - 1, endLine - 1, typedChar); - if (beginLine != endLine) - showBlackMessage("MARKS ARE OFF NOW"); + int beginBlock = document()->findBlock(range.beginPos).blockNumber(); + int endBlock = document()->findBlock(range.endPos).blockNumber(); + if (beginBlock > endBlock) + qSwap(beginBlock, endBlock); + emit q->indentRegion(beginBlock, endBlock, typedChar); } bool FakeVimHandler::Private::isElectricCharacter(QChar c) const @@ -4280,58 +5427,35 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat) targetPos = firstPositionInLine(beginLine); const int sw = config(ConfigShiftWidth).toInt(); + m_movetype = MoveLineWise; beginEditBlock(); - for (int line = beginLine; line <= endLine; ++line) { - QString data = lineContents(line); - const Column col = indentation(data); - data = tabExpand(col.logical + sw * repeat) + data.mid(col.physical); - setLineContents(line, data); + QTextBlock block = document()->findBlockByLineNumber(beginLine - 1); + while (block.isValid() && lineNumber(block) <= endLine) { + const Column col = indentation(block.text()); + QTextCursor tc = cursor(); + tc.setPosition(block.position()); + if (col.physical > 0) + tc.setPosition(tc.position() + col.physical, KeepAnchor); + tc.insertText(tabExpand(col.logical + sw * repeat)); + block = block.next(); } endEditBlock(); setPosition(targetPos); handleStartOfLine(); setTargetColumn(); - setDotCommand("%1>>", endLine - beginLine + 1); + + const int lines = endLine - beginLine + 1; + if (lines > 2) { + showMessage(MessageInfo, + FakeVimHandler::tr("%n lines %1ed %2 time", 0, lines) + .arg(repeat > 0 ? '>' : '<').arg(qAbs(repeat))); + } } void FakeVimHandler::Private::shiftRegionLeft(int repeat) { - int beginLine = lineForPosition(anchor()); - int endLine = lineForPosition(position()); - int targetPos = anchor(); - if (beginLine > endLine) { - qSwap(beginLine, endLine); - targetPos = position(); - } - const int shift = config(ConfigShiftWidth).toInt() * repeat; - const int tab = config(ConfigTabStop).toInt(); - if (hasConfig(ConfigStartOfLine)) - targetPos = firstPositionInLine(beginLine); - - beginEditBlock(); - for (int line = endLine; line >= beginLine; --line) { - int pos = firstPositionInLine(line); - const QString text = lineContents(line); - int amount = 0; - int i = 0; - for (; i < text.size() && amount < shift; ++i) { - if (text.at(i) == ' ') - amount++; - else if (text.at(i) == '\t') - amount += tab; // FIXME: take position into consideration - else - break; - } - removeText(Range(pos, pos + i)); - setPosition(pos); - } - endEditBlock(); - - setPosition(targetPos); - handleStartOfLine(); - setTargetColumn(); - setDotCommand("%1<<", endLine - beginLine + 1); + shiftRegionRight(-repeat); } void FakeVimHandler::Private::moveToTargetColumn() @@ -4339,17 +5463,14 @@ void FakeVimHandler::Private::moveToTargetColumn() const QTextBlock &bl = block(); //Column column = cursorColumn(); //int logical = logical - const int maxcol = bl.length() - 2; + const int pos = lastPositionInLine(bl.blockNumber() + 1, false); if (m_targetColumn == -1) { - setPosition(bl.position() + qMax(0, maxcol)); + setPosition(pos); return; } - const int physical = logicalToPhysicalColumn(m_targetColumn, bl.text()); + const int physical = bl.position() + logicalToPhysicalColumn(m_targetColumn, bl.text()); //qDebug() << "CORRECTING COLUMN FROM: " << logical << "TO" << m_targetColumn; - if (physical >= maxcol) - setPosition(bl.position() + qMax(0, maxcol)); - else - setPosition(bl.position() + physical); + setPosition(qMin(pos, physical)); } /* if simple is given: @@ -4379,6 +5500,32 @@ int FakeVimHandler::Private::charClass(QChar c, bool simple) const return c.isSpace() ? 0 : 1; } +void FakeVimHandler::Private::miniBufferTextEdited(const QString &text, int cursorPos) +{ + if (m_subsubmode != SearchSubSubMode && m_mode != ExMode) { + editor()->setFocus(); + } else if (text.isEmpty()) { + // editing cancelled + handleDefaultKey(Input(Qt::Key_Escape, Qt::NoModifier, QString())); + editor()->setFocus(); + updateCursorShape(); + } else { + CommandBuffer &cmdBuf = (m_mode == ExMode) ? g.commandBuffer : g.searchBuffer; + // prepend prompt character if missing + if (!text.startsWith(cmdBuf.prompt())) { + emit q->commandBufferChanged(cmdBuf.prompt() + text, cmdBuf.cursorPos() + 1, 0, q); + cmdBuf.setContents(text, cursorPos - 1); + } else { + cmdBuf.setContents(text.mid(1), cursorPos - 1); + } + // update search expression + if (m_subsubmode == SearchSubSubMode) { + updateFind(false); + exportSelection(); + } + } +} + // Helper to parse a-z,A-Z,48-57,_ static int someInt(const QString &str) { @@ -4408,36 +5555,93 @@ void FakeVimHandler::Private::setupCharClass() } } -void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward, bool changeWord) +void FakeVimHandler::Private::moveToBoundary(bool simple, bool forward) { - int repeat = count(); QTextDocument *doc = document(); - int n = forward ? lastPositionInDocument() : 0; - int lastClass = -1; - if (changeWord) { - lastClass = charClass(characterAtCursor(), simple); - --repeat; - if (changeWord && block().length() == 1) // empty line - --repeat; - } - while (repeat >= 0) { - QChar c = doc->characterAt(position() + (forward ? 1 : -1)); + QTextCursor tc(doc); + tc.setPosition(position()); + if (forward ? tc.atBlockEnd() : tc.atBlockStart()) + return; + + QChar c = document()->characterAt(tc.position() + (forward ? -1 : 1)); + int lastClass = tc.atStart() ? -1 : charClass(c, simple); + QTextCursor::MoveOperation op = forward ? Right : Left; + while (true) { + c = doc->characterAt(tc.position()); int thisClass = charClass(c, simple); - if (thisClass != lastClass && (lastClass != 0 || changeWord)) - --repeat; - if (repeat == -1) + if (thisClass != lastClass || (forward ? tc.atBlockEnd() : tc.atBlockStart())) { + if (tc != cursor()) + tc.movePosition(forward ? Left : Right); break; + } lastClass = thisClass; - if (position() == n) - break; - forward ? moveRight() : moveLeft(); - if (changeWord && block().length() == 1) // empty line + tc.movePosition(op); + } + setPosition(tc.position()); +} + +void FakeVimHandler::Private::moveToNextBoundary(bool end, int count, bool simple, bool forward) +{ + int repeat = count; + while (repeat > 0 && !(forward ? atDocumentEnd() : atDocumentStart())) { + setPosition(position() + (forward ? 1 : -1)); + moveToBoundary(simple, forward); + if (atBoundary(end, simple)) + --repeat; + } +} + +void FakeVimHandler::Private::moveToNextBoundaryStart(int count, bool simple, bool forward) +{ + moveToNextBoundary(false, count, simple, forward); +} + +void FakeVimHandler::Private::moveToNextBoundaryEnd(int count, bool simple, bool forward) +{ + moveToNextBoundary(true, count, simple, forward); +} + +void FakeVimHandler::Private::moveToBoundaryStart(int count, bool simple, bool forward) +{ + moveToNextBoundaryStart(atBoundary(false, simple) ? count - 1 : count, simple, forward); +} + +void FakeVimHandler::Private::moveToBoundaryEnd(int count, bool simple, bool forward) +{ + moveToNextBoundaryEnd(atBoundary(true, simple) ? count - 1 : count, simple, forward); +} + +void FakeVimHandler::Private::moveToNextWord(bool end, int count, bool simple, bool forward, bool emptyLines) +{ + int repeat = count; + while (repeat > 0 && !(forward ? atDocumentEnd() : atDocumentStart())) { + setPosition(position() + (forward ? 1 : -1)); + moveToBoundary(simple, forward); + if (atWordBoundary(end, simple) && (emptyLines || !atEmptyLine()) ) --repeat; - if (repeat == -1) - break; } } +void FakeVimHandler::Private::moveToNextWordStart(int count, bool simple, bool forward, bool emptyLines) +{ + moveToNextWord(false, count, simple, forward, emptyLines); +} + +void FakeVimHandler::Private::moveToNextWordEnd(int count, bool simple, bool forward, bool emptyLines) +{ + moveToNextWord(true, count, simple, forward, emptyLines); +} + +void FakeVimHandler::Private::moveToWordStart(int count, bool simple, bool forward, bool emptyLines) +{ + moveToNextWordStart(atWordStart(simple) ? count - 1 : count, simple, forward, emptyLines); +} + +void FakeVimHandler::Private::moveToWordEnd(int count, bool simple, bool forward, bool emptyLines) +{ + moveToNextWordEnd(atWordEnd(simple) ? count - 1 : count, simple, forward, emptyLines); +} + bool FakeVimHandler::Private::handleFfTt(QString key) { int key0 = key.size() == 1 ? key.at(0).unicode() : 0; @@ -4480,35 +5684,6 @@ bool FakeVimHandler::Private::handleFfTt(QString key) return false; } -void FakeVimHandler::Private::moveToNextWord(bool simple, bool deleteWord) -{ - int repeat = count(); - int n = lastPositionInDocument(); - int lastClass = charClass(characterAtCursor(), simple); - while (true) { - QChar c = characterAtCursor(); - int thisClass = charClass(c, simple); - if (thisClass != lastClass && thisClass != 0) - --repeat; - if (repeat == 0) - break; - lastClass = thisClass; - moveRight(); - if (deleteWord) { - if (atBlockEnd()) - --repeat; - } else { - if (block().length() == 1) // empty line - --repeat; - } - if (repeat == 0) - break; - if (position() == n) - break; - } - setTargetColumn(); -} - void FakeVimHandler::Private::moveToMatchingParanthesis() { bool moved = false; @@ -4550,7 +5725,12 @@ int FakeVimHandler::Private::columnsOnScreen() const int FakeVimHandler::Private::cursorLine() const { - return block().blockNumber(); + return lineForPosition(position()) - 1; +} + +int FakeVimHandler::Private::cursorBlockNumber() const +{ + return document()->findBlock(qMin(anchor(), position())).blockNumber(); } int FakeVimHandler::Private::physicalCursorColumn() const @@ -4642,10 +5822,48 @@ void FakeVimHandler::Private::scrollUp(int count) scrollToLine(cursorLine() - cursorLineOnScreen() - count); } -int FakeVimHandler::Private::lastPositionInDocument() const +void FakeVimHandler::Private::alignViewportToCursor(AlignmentFlag align, int line, + bool moveToNonBlank) { - QTextBlock block = document()->lastBlock(); - return block.position() + block.length() - 1; + if (line > 0) + setPosition(firstPositionInLine(line)); + if (moveToNonBlank) + moveToFirstNonBlankOnLine(); + + if (align == Qt::AlignTop) + scrollUp(- cursorLineOnScreen()); + else if (align == Qt::AlignVCenter) + scrollUp(linesOnScreen() / 2 - cursorLineOnScreen()); + else if (align == Qt::AlignBottom) + scrollUp(linesOnScreen() - cursorLineOnScreen()); +} + +void FakeVimHandler::Private::setCursorPosition(const CursorPosition &p) +{ + const int firstLine = firstVisibleLine(); + const int firstBlock = document()->findBlockByLineNumber(firstLine).blockNumber(); + const int lastBlock = + document()->findBlockByLineNumber(firstLine + linesOnScreen() - 2).blockNumber(); + bool isLineVisible = firstBlock <= p.line && p.line <= lastBlock; + QTextCursor tc = cursor(); + setCursorPosition(&tc, p); + setCursor(tc); + if (!isLineVisible) + alignViewportToCursor(Qt::AlignVCenter); +} + +void FakeVimHandler::Private::setCursorPosition(QTextCursor *tc, const CursorPosition &p) +{ + const int line = qMin(document()->blockCount() - 1, p.line); + QTextBlock block = document()->findBlockByNumber(line); + const int column = qMin(p.column, block.length() - 1); + tc->setPosition(block.position() + column, KeepAnchor); +} + +int FakeVimHandler::Private::lastPositionInDocument(bool ignoreMode) const +{ + return document()->characterCount() + - (ignoreMode || isVisualMode() || m_mode == InsertMode || m_mode == ReplaceMode ? 1 : 2); } QString FakeVimHandler::Private::selectText(const Range &range) const @@ -4660,8 +5878,8 @@ QString FakeVimHandler::Private::selectText(const Range &range) const QTextCursor tc(document()); int firstPos = firstPositionInLine(lineForPosition(range.beginPos)); int lastLine = lineForPosition(range.endPos); - bool endOfDoc = lastLine == document()->lastBlock().blockNumber() + 1; - int lastPos = endOfDoc ? lastPositionInDocument() : firstPositionInLine(lastLine + 1); + bool endOfDoc = lastLine == lineNumber(document()->lastBlock()); + int lastPos = endOfDoc ? lastPositionInDocument(true) : firstPositionInLine(lastLine + 1); tc.setPosition(firstPos, MoveAnchor); tc.setPosition(lastPos, KeepAnchor); return tc.selection().toPlainText() + QString((endOfDoc? "\n" : "")); @@ -4679,7 +5897,7 @@ QString FakeVimHandler::Private::selectText(const Range &range) const } int len = endColumn - beginColumn + 1; QString contents; - QTextBlock block = document()->findBlockByNumber(beginLine - 1); + QTextBlock block = document()->findBlockByLineNumber(beginLine - 1); for (int i = beginLine; i <= endLine && block.isValid(); ++i) { QString line = block.text(); if (range.rangemode == RangeBlockMode) { @@ -4699,12 +5917,18 @@ QString FakeVimHandler::Private::selectText(const Range &range) const void FakeVimHandler::Private::yankText(const Range &range, int reg) { setRegister(reg, selectText(range), range.rangemode); + + const int lines = document()->findBlock(range.endPos).blockNumber() + - document()->findBlock(range.beginPos).blockNumber() + 1; + if (lines > 2) + showMessage(MessageInfo, FakeVimHandler::tr("%1 lines yanked").arg(lines)); } void FakeVimHandler::Private::transformText(const Range &range, Transformation transformFunc, const QVariant &extra) { QTextCursor tc = cursor(); + int posAfter = range.beginPos; switch (range.rangemode) { case RangeCharMode: { // This can span multiple lines. @@ -4713,10 +5937,9 @@ void FakeVimHandler::Private::transformText(const Range &range, tc.setPosition(range.endPos, KeepAnchor); TransformationData td(tc.selectedText(), extra); (this->*transformFunc)(&td); - tc.removeSelectedText(); tc.insertText(td.to); endEditBlock(); - return; + break; } case RangeLineMode: case RangeLineModeExclusive: { @@ -4744,10 +5967,10 @@ void FakeVimHandler::Private::transformText(const Range &range, } TransformationData td(tc.selectedText(), extra); (this->*transformFunc)(&td); - tc.removeSelectedText(); + posAfter = tc.anchor(); tc.insertText(td.to); endEditBlock(); - return; + break; } case RangeBlockAndTailMode: case RangeBlockMode: { @@ -4759,7 +5982,7 @@ void FakeVimHandler::Private::transformText(const Range &range, int endColumn = qMax(column1, column2); if (range.rangemode == RangeBlockAndTailMode) endColumn = INT_MAX - 1; - QTextBlock block = document()->findBlockByNumber(endLine - 1); + QTextBlock block = document()->findBlockByLineNumber(endLine - 1); beginEditBlock(); for (int i = beginLine; i <= endLine && block.isValid(); ++i) { int bCol = qMin(beginColumn, block.length() - 1); @@ -4768,13 +5991,16 @@ void FakeVimHandler::Private::transformText(const Range &range, tc.setPosition(block.position() + eCol, KeepAnchor); TransformationData td(tc.selectedText(), extra); (this->*transformFunc)(&td); - tc.removeSelectedText(); tc.insertText(td.to); block = block.previous(); } endEditBlock(); + break; } } + + setPosition(posAfter); + setTargetColumn(); } void FakeVimHandler::Private::insertText(const Register ®) @@ -4783,7 +6009,6 @@ void FakeVimHandler::Private::insertText(const Register ®) qDebug() << "WRONG INSERT MODE: " << reg.rangemode; return); setAnchor(); cursor().insertText(reg.contents); - m_lastChangePosition = cursor().position(); //dump("AFTER INSERT"); } @@ -4842,7 +6067,13 @@ void FakeVimHandler::Private::replaceByStringTransform(TransformationData *td) void FakeVimHandler::Private::replaceByCharTransform(TransformationData *td) { - td->to = QString(td->from.size(), td->extraData.toChar()); + // Replace each character but preserve lines. + const int len = td->from.size(); + td->to = QString(len, td->extraData.toChar()); + for (int i = 0; i < len; ++i) { + if (td->from.at(i) == ParagraphSeparator) + td->to[i] = ParagraphSeparator; + } } void FakeVimHandler::Private::pasteText(bool afterCursor) @@ -4883,12 +6114,14 @@ void FakeVimHandler::Private::pasteText(bool afterCursor) switch (rangeMode) { case RangeCharMode: { m_targetColumn = 0; + const int pos = position() + 1; if (pasteAfter && rightDist() > 0) moveRight(); insertText(text.repeated(count())); - if (!pasteAfter && atEndOfLine()) + if (text.contains('\n')) + setPosition(pos); + else moveLeft(); - moveLeft(); break; } case RangeLineMode: @@ -4899,8 +6132,9 @@ void FakeVimHandler::Private::pasteText(bool afterCursor) else moveToStartOfLine(); m_targetColumn = 0; + bool lastLine = false; if (pasteAfter) { - bool lastLine = document()->lastBlock() == this->block(); + lastLine = document()->lastBlock() == this->block(); if (lastLine) { tc.movePosition(EndOfLine, MoveAnchor); tc.insertBlock(); @@ -4908,7 +6142,10 @@ void FakeVimHandler::Private::pasteText(bool afterCursor) moveDown(); } const int pos = position(); - insertText(text.repeated(count())); + if (lastLine) + insertText(text.repeated(count()).left(text.size() * count() - 1)); + else + insertText(text.repeated(count())); setPosition(pos); moveToFirstNonBlankOnLine(); break; @@ -4956,20 +6193,35 @@ void FakeVimHandler::Private::pasteText(bool afterCursor) endEditBlock(); } +void FakeVimHandler::Private::joinLines(int count, bool preserveSpace) +{ + for (int i = qMax(count - 2, 0); i >= 0; --i) { + moveBehindEndOfLine(); + setAnchor(); + moveRight(); + if (preserveSpace) { + removeText(currentRange()); + } else { + while (characterAtCursor() == ' ' || characterAtCursor() == '\t') + moveRight(); + cursor().insertText(QString(QLatin1Char(' '))); + } + } +} + QString FakeVimHandler::Private::lineContents(int line) const { - return document()->findBlockByNumber(line - 1).text(); + return document()->findBlockByLineNumber(line - 1).text(); } void FakeVimHandler::Private::setLineContents(int line, const QString &contents) { - QTextBlock block = document()->findBlockByNumber(line - 1); + QTextBlock block = document()->findBlockByLineNumber(line - 1); QTextCursor tc = cursor(); const int begin = block.position(); const int len = block.length(); tc.setPosition(begin); tc.setPosition(begin + len - 1, KeepAnchor); - tc.removeSelectedText(); tc.insertText(contents); } @@ -5042,23 +6294,51 @@ int FakeVimHandler::Private::blockBoundary(const QString &left, return tc2.position() - end.size(); } +int FakeVimHandler::Private::lineNumber(const QTextBlock &block) const +{ + if (block.isVisible()) + return block.firstLineNumber() + 1; + + // Folded block has line number of the nearest previous visible line. + QTextBlock block2 = block; + while (block2.isValid() && !block2.isVisible()) + block2 = block2.previous(); + return block2.firstLineNumber() + 1; +} -int FakeVimHandler::Private::firstPositionInLine(int line) const +int FakeVimHandler::Private::firstPositionInLine(int line, bool onlyVisibleLines) const { - return document()->findBlockByNumber(line - 1).position(); + QTextBlock block = onlyVisibleLines ? document()->findBlockByLineNumber(line - 1) + : document()->findBlockByNumber(line - 1); + return block.position(); } -int FakeVimHandler::Private::lastPositionInLine(int line) const +int FakeVimHandler::Private::lastPositionInLine(int line, bool onlyVisibleLines) const { - QTextBlock block = document()->findBlockByNumber(line - 1); - return block.position() + block.length() - 1; + QTextBlock block; + if (onlyVisibleLines) { + // respect folds + block = document()->findBlockByLineNumber(line); + if (block.isValid()) { + if (line > 0) + block = block.previous(); + } else { + block = document()->lastBlock(); + } + } else { + block = document()->findBlockByNumber(line - 1); + } + + const int position = block.position() + block.length() - 1; + if (block.length() > 1 && !isVisualMode() && m_mode != InsertMode && m_mode != ReplaceMode) + return position - 1; + return position; } int FakeVimHandler::Private::lineForPosition(int pos) const { - QTextCursor tc = cursor(); - tc.setPosition(pos); - return tc.block().blockNumber() + 1; + QTextBlock block = document()->findBlock(pos); + return lineNumber(block); } void FakeVimHandler::Private::toggleVisualMode(VisualMode visualMode) @@ -5069,33 +6349,27 @@ void FakeVimHandler::Private::toggleVisualMode(VisualMode visualMode) m_positionPastEnd = false; m_anchorPastEnd = false; m_visualMode = visualMode; + m_lastVisualMode = visualMode; const int pos = position(); setAnchorAndPosition(pos, pos); updateMiniBuffer(); - updateSelection(); } } void FakeVimHandler::Private::leaveVisualMode() { - if (isVisualMode()) { - m_lastSelectionCursor = cursor(); - m_lastSelectionMode = m_visualMode; - int from = m_lastSelectionCursor.anchor(); - int to = m_lastSelectionCursor.position(); - if (from > to) - qSwap(from, to); - setMark('<', from); - setMark('>', to); - if (isVisualLineMode()) - m_movetype = MoveLineWise; - else if (isVisualCharMode()) - m_movetype = MoveInclusive; - } + if (!isVisualMode()) + return; + + setMark('<', mark('<').position); + setMark('>', mark('>').position); + if (isVisualLineMode()) + m_movetype = MoveLineWise; + else if (isVisualCharMode()) + m_movetype = MoveInclusive; m_visualMode = NoVisualMode; updateMiniBuffer(); - updateSelection(); } QWidget *FakeVimHandler::Private::editor() const @@ -5105,39 +6379,111 @@ QWidget *FakeVimHandler::Private::editor() const : static_cast<QWidget *>(m_plaintextedit); } -void FakeVimHandler::Private::undo() +void FakeVimHandler::Private::joinPreviousEditBlock() +{ + UNDO_DEBUG("JOIN"); + if (m_breakEditBlock) { + beginEditBlock(); + } else { + if (m_editBlockLevel == 0) + m_cursor = cursor(); + ++m_editBlockLevel; + cursor().joinPreviousEditBlock(); + } +} + +void FakeVimHandler::Private::beginEditBlock(bool rememberPosition) +{ + UNDO_DEBUG("BEGIN EDIT BLOCK"); + if (m_editBlockLevel == 0) + m_cursor = cursor(); + ++m_editBlockLevel; + cursor().beginEditBlock(); + if (rememberPosition) + setUndoPosition(false); + m_breakEditBlock = false; +} + +void FakeVimHandler::Private::endEditBlock() +{ + UNDO_DEBUG("END EDIT BLOCK"); + QTC_ASSERT(m_editBlockLevel > 0, + qDebug() << "beginEditBlock() not called before endEditBlock()!"; return); + --m_editBlockLevel; + cursor().endEditBlock(); + if (m_editBlockLevel == 0) + setCursor(m_cursor); +} + +char FakeVimHandler::Private::currentModeCode() const +{ + if (m_submode != NoSubMode) + return ' '; + else if (m_mode == ExMode) + return 'c'; + else if (isVisualMode()) + return 'v'; + else if (m_mode == CommandMode) + return 'n'; + else + return 'i'; +} + +void FakeVimHandler::Private::undoRedo(bool undo) { // FIXME: That's only an approximaxtion. The real solution might // be to store marks and old userData with QTextBlock setUserData // and retrieve them afterward. - const int current = document()->availableUndoSteps(); - EDITOR(undo()); - const int rev = document()->availableUndoSteps(); - if (current == rev) - showBlackMessage(FakeVimHandler::tr("Already at oldest change")); + QStack<State> &stack = undo ? m_undo : m_redo; + QStack<State> &stack2 = undo ? m_redo : m_undo; + + CursorPosition lastPos(cursor()); + const int current = revision(); + if (undo) + EDITOR(undo()); else - showBlackMessage(QString()); + EDITOR(redo()); + const int rev = revision(); + + // rewind/forward to last saved revision + while (!stack.empty() && stack.top().revision > rev) + stack.pop(); + + if (current == rev) { + const QString msg = undo ? FakeVimHandler::tr("Already at oldest change") + : FakeVimHandler::tr("Already at newest change"); + showMessage(MessageInfo, msg); + return; + } + clearMessage(); + + if (!stack.empty()) { + State &state = stack.top(); + if (state.revision == rev) { + m_lastChangePosition = state.position; + m_marks = state.marks; + m_lastVisualMode = state.lastVisualMode; + setMark('\'', lastPos); + setCursorPosition(m_lastChangePosition); + setAnchor(); + state.revision = current; + stack2.push(stack.pop()); + } + } - if (m_undoCursorPosition.contains(rev)) - setPosition(m_undoCursorPosition[rev]); setTargetColumn(); if (atEndOfLine()) moveLeft(); } -void FakeVimHandler::Private::redo() +void FakeVimHandler::Private::undo() { - const int current = document()->availableUndoSteps(); - EDITOR(redo()); - const int rev = document()->availableUndoSteps(); - if (rev == current) - showBlackMessage(FakeVimHandler::tr("Already at newest change")); - else - showBlackMessage(QString()); + undoRedo(true); +} - if (m_undoCursorPosition.contains(rev)) - setPosition(m_undoCursorPosition[rev]); - setTargetColumn(); +void FakeVimHandler::Private::redo() +{ + undoRedo(false); } void FakeVimHandler::Private::updateCursorShape() @@ -5155,9 +6501,9 @@ void FakeVimHandler::Private::enterReplaceMode() m_mode = ReplaceMode; m_submode = NoSubMode; m_subsubmode = NoSubSubMode; - m_commandPrefix.clear(); m_lastInsertion.clear(); m_lastDeletion.clear(); + g.returnToMode = ReplaceMode; } void FakeVimHandler::Private::enterInsertMode() @@ -5165,36 +6511,57 @@ void FakeVimHandler::Private::enterInsertMode() m_mode = InsertMode; m_submode = NoSubMode; m_subsubmode = NoSubSubMode; - m_commandPrefix.clear(); m_lastInsertion.clear(); m_lastDeletion.clear(); + g.returnToMode = InsertMode; } -void FakeVimHandler::Private::enterCommandMode() +void FakeVimHandler::Private::enterCommandMode(Mode returnToMode) { if (atEndOfLine()) moveLeft(); m_mode = CommandMode; m_submode = NoSubMode; m_subsubmode = NoSubSubMode; - m_commandPrefix.clear(); + g.returnToMode = returnToMode; } -void FakeVimHandler::Private::enterExMode() +void FakeVimHandler::Private::enterExMode(const QString &contents) { + g.currentMessage.clear(); + if (isVisualMode()) + g.commandBuffer.setContents(QString("'<,'>") + contents, contents.size() + 5); + else + g.commandBuffer.setContents(contents, contents.size()); m_mode = ExMode; m_submode = NoSubMode; m_subsubmode = NoSubSubMode; - m_commandPrefix = ':'; } void FakeVimHandler::Private::recordJump() { - m_jumpListUndo.append(cursorPosition()); + CursorPosition pos(cursor()); + setMark('\'', pos); + if (m_jumpListUndo.isEmpty() || m_jumpListUndo.top() != pos) + m_jumpListUndo.push(pos); m_jumpListRedo.clear(); UNDO_DEBUG("jumps: " << m_jumpListUndo); } +void FakeVimHandler::Private::jump(int distance) +{ + QStack<CursorPosition> &from = (distance > 0) ? m_jumpListRedo : m_jumpListUndo; + QStack<CursorPosition> &to = (distance > 0) ? m_jumpListUndo : m_jumpListRedo; + int len = qMin(qAbs(distance), from.size()); + CursorPosition m(cursor()); + setMark('\'', m); + for (int i = 0; i < len; ++i) { + to.push(m); + setCursorPosition(from.top()); + from.pop(); + } +} + Column FakeVimHandler::Private::indentation(const QString &line) const { int ts = config(ConfigTabStop).toInt(); @@ -5267,43 +6634,108 @@ void FakeVimHandler::Private::handleStartOfLine() moveToFirstNonBlankOnLine(); } -void FakeVimHandler::Private::replay(const QString &command, int n) +void FakeVimHandler::Private::replay(const QString &command) { //qDebug() << "REPLAY: " << quoteUnprintable(command); - for (int i = n; --i >= 0; ) { - foreach (QChar c, command) { - //qDebug() << " REPLAY: " << c.unicode(); - handleKey(Input(c)); + Inputs inputs(command); + foreach (Input in, inputs) { + if (handleDefaultKey(in) != EventHandled) + break; + } +} + +QString FakeVimHandler::Private::visualDotCommand() const +{ + QTextCursor start(cursor()); + QTextCursor end(start); + end.setPosition(end.anchor()); + + if (isVisualCharMode()) + return QString("v%1l").arg(qAbs(start.position() - end.position())); + + if (isVisualLineMode()) + return QString("V%1j").arg(qAbs(start.blockNumber() - end.blockNumber())); + + if (isVisualBlockMode()) { + return QString("<c-v>%1l%2j") + .arg(qAbs(start.positionInBlock() - end.positionInBlock())) + .arg(qAbs(start.blockNumber() - end.blockNumber())); + } + + return QString(); +} + +void FakeVimHandler::Private::selectTextObject(bool simple, bool inner) +{ + bool setupAnchor = (position() == anchor()); + + // set anchor if not already set + if (setupAnchor) { + moveToBoundaryStart(1, simple, false); + setAnchor(); + } else { + moveRight(); + if (atEndOfLine()) + moveRight(); + } + + const int repeat = count(); + if (inner) { + moveToBoundaryEnd(repeat, simple); + } else { + for (int i = 0; i < repeat; ++i) { + // select leading spaces + bool leadingSpace = characterAtCursor().isSpace(); + if (leadingSpace) + moveToNextBoundaryStart(1, simple); + + // select word + moveToWordEnd(1, simple); + + // select trailing spaces if no leading space + if (!leadingSpace && document()->characterAt(position() + 1).isSpace() + && !atBlockStart()) { + moveToNextBoundaryEnd(1, simple); + } + + // if there are no trailing spaces in selection select all leading spaces + // after previous character + if (setupAnchor && (!characterAtCursor().isSpace() || atBlockEnd())) { + int min = block().position(); + int pos = anchor(); + while (pos >= min && document()->characterAt(--pos).isSpace()) {} + if (pos >= min) + setAnchorAndPosition(pos + 1, position()); + } + + if (i + 1 < repeat) { + moveRight(); + if (atEndOfLine()) + moveRight(); + } } } + + if (inner) { + m_movetype = MoveInclusive; + } else { + m_movetype = MoveExclusive; + moveRight(); + if (atEndOfLine()) + moveRight(); + } + + setTargetColumn(); } void FakeVimHandler::Private::selectWordTextObject(bool inner) { - Q_UNUSED(inner); // FIXME - m_movetype = MoveExclusive; - moveToWordBoundary(false, false, true); - setAnchor(); - // FIXME: Rework the 'anchor' concept. - //if (isVisualMode()) - // setMark('<', cursor().position()); - moveToWordBoundary(false, true, true); - setTargetColumn(); - m_movetype = MoveInclusive; + selectTextObject(false, inner); } void FakeVimHandler::Private::selectWORDTextObject(bool inner) { - Q_UNUSED(inner); // FIXME - m_movetype = MoveExclusive; - moveToWordBoundary(true, false, true); - setAnchor(); - // FIXME: Rework the 'anchor' concept. - //if (isVisualMode()) - // setMark('<', cursor().position()); - moveToWordBoundary(true, true, true); - setTargetColumn(); - m_movetype = MoveInclusive; + selectTextObject(true, inner); } void FakeVimHandler::Private::selectSentenceTextObject(bool inner) @@ -5316,7 +6748,7 @@ void FakeVimHandler::Private::selectParagraphTextObject(bool inner) Q_UNUSED(inner); } -void FakeVimHandler::Private::selectBlockTextObject(bool inner, +bool FakeVimHandler::Private::selectBlockTextObject(bool inner, char left, char right) { QString sleft = QString(QLatin1Char(left)); @@ -5324,21 +6756,25 @@ void FakeVimHandler::Private::selectBlockTextObject(bool inner, int p1 = blockBoundary(sleft, sright, false, count()); if (p1 == -1) - return; + return false; int p2 = blockBoundary(sleft, sright, true, count()); if (p2 == -1) - return; + return false; if (inner) { p1 += sleft.size(); - --p2; } else { - p2 -= sright.size() - 1; + p2 -= sright.size() - 2; } + if (isVisualMode()) + --p2; + setAnchorAndPosition(p1, p2); - m_movetype = MoveInclusive; + m_movetype = MoveExclusive; + + return true; } static bool isSign(const QChar c) @@ -5346,41 +6782,38 @@ static bool isSign(const QChar c) return c.unicode() == '-' || c.unicode() == '+'; } -void FakeVimHandler::Private::changeNumberTextObject(bool doIncrement) +void FakeVimHandler::Private::changeNumberTextObject(int count) { QTextCursor tc = cursor(); int pos = tc.position(); - const int n = lastPositionInDocument(); + const int n = lastPositionInLine(lineForPosition(pos)) + 1; QTextDocument *doc = document(); QChar c = doc->characterAt(pos); - if (!c.isNumber()) { - if (pos == n || !isSign(c)) + while (!c.isNumber()) { + if (pos == n) return; ++pos; c = doc->characterAt(pos); - if (!c.isNumber()) - return; } int p1 = pos; while (p1 >= 1 && doc->characterAt(p1 - 1).isNumber()) --p1; if (p1 >= 1 && isSign(doc->characterAt(p1 - 1))) --p1; - int p2 = pos; - while (p2 <= n - 1 && doc->characterAt(p2 + 1).isNumber()) + int p2 = pos + 1; + while (p2 <= n - 1 && doc->characterAt(p2).isNumber()) ++p2; - ++p2; - setAnchorAndPosition(p2, p1); + setAnchorAndPosition(p1, p2); QString orig = selectText(currentRange()); int value = orig.toInt(); - value = doIncrement ? value + 1 : value - 1; - QString repl = QString::fromLatin1("%1").arg(value, orig.size(), 10, QLatin1Char('0')); + value += count; + QString repl = QString::fromLatin1("%1").arg(value); replaceText(currentRange(), repl); - moveLeft(); + setPosition(p1 + repl.size() - 1); } -void FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, +bool FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, const QString "e) { QTextCursor tc = cursor(); @@ -5391,49 +6824,76 @@ void FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, while (tc2 <= tc) { tc1 = document()->find(quote, tc2); if (tc1.isNull() || tc1.anchor() > tc.position()) - return; + return false; tc2 = document()->find(quote, tc1); if (tc2.isNull()) - return; + return false; } int p1 = tc1.position(); int p2 = tc2.position(); if (inner) { - p2 -= sz + 1; + p2 = qMax(p1, p2 - sz); if (document()->characterAt(p1) == ParagraphSeparator) ++p1; } else { p1 -= sz; - p2 -= sz; + p2 -= sz - 1; } setAnchorAndPosition(p1, p2); - m_movetype = MoveInclusive; + m_movetype = MoveExclusive; + + return true; } -int FakeVimHandler::Private::mark(int code) const +Mark FakeVimHandler::Private::mark(QChar code) const { - // FIXME: distinguish local and global marks. - //qDebug() << "MARK: " << code << m_marks.value(code, -1) << m_marks; if (isVisualMode()) { if (code == '<') - return position(); + return CursorPosition(document(), qMin(anchor(), position())); if (code == '>') - return anchor(); + return CursorPosition(document(), qMax(anchor(), position())); } if (code == '.') return m_lastChangePosition; - QTextCursor tc = m_marks.value(code); - return tc.isNull() ? -1 : tc.position(); + if (code.isUpper()) + return g.marks.value(code); + + return m_marks.value(code); } -void FakeVimHandler::Private::setMark(int code, int position) +void FakeVimHandler::Private::setMark(QChar code, CursorPosition position) { - // FIXME: distinguish local and global marks. - QTextCursor tc = cursor(); - tc.setPosition(position, MoveAnchor); - m_marks[code] = tc; + if (code.isUpper()) + g.marks[code] = Mark(position, m_currentFileName); + else + m_marks[code] = Mark(position); +} + +bool FakeVimHandler::Private::jumpToMark(QChar mark, bool backTickMode) +{ + Mark m = this->mark(mark); + if (!m.isValid()) { + showMessage(MessageError, msgMarkNotSet(mark)); + return false; + } + if (!m.isLocal(m_currentFileName)) { + emit q->jumpToGlobalMark(mark, backTickMode, m.fileName); + return false; + } + + if (mark == '\'' && !m_jumpListUndo.isEmpty()) + m_jumpListUndo.pop(); + recordJump(); + setCursorPosition(m.position); + if (!backTickMode) + moveToFirstNonBlankOnLine(); + if (m_submode == NoSubMode) + setAnchor(); + setTargetColumn(); + + return true; } RangeMode FakeVimHandler::Private::registerRangeMode(int reg) const @@ -5470,13 +6930,17 @@ void FakeVimHandler::Private::setRegister(int reg, const QString &contents, Rang bool copyToSelection; getRegisterType(reg, ©ToClipboard, ©ToSelection); + QString contents2 = contents; + if (mode == RangeLineMode && !contents2.endsWith('\n')) + contents2.append('\n'); + if (copyToClipboard || copyToSelection) { if (copyToClipboard) - setClipboardData(contents, mode, QClipboard::Clipboard); + setClipboardData(contents2, mode, QClipboard::Clipboard); if (copyToSelection) - setClipboardData(contents, mode, QClipboard::Selection); + setClipboardData(contents2, mode, QClipboard::Selection); } else { - g.registers[reg].contents = contents; + g.registers[reg].contents = contents2; g.registers[reg].rangemode = mode; } } @@ -5569,7 +7033,6 @@ bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev) QMouseEvent *mev = static_cast<QMouseEvent *>(ev); if (mev->button() == Qt::LeftButton) { d->m_visualMode = NoVisualMode; - d->updateSelection(); } } return QObject::eventFilter(ob, ev); @@ -5592,10 +7055,11 @@ bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev) int key = commitString.size() == 1 ? commitString.at(0).unicode() : 0; QKeyEvent kev(QEvent::KeyPress, key, Qt::KeyboardModifiers(), commitString); EventResult res = d->handleEvent(&kev); - return res == EventHandled; + return res == EventHandled || res == EventCancelled; } - if (active && ev->type() == QEvent::KeyPress && ob == d->editor()) { + if (active && ev->type() == QEvent::KeyPress && + (ob == d->editor() || (d->m_mode == ExMode || d->m_subsubmode == SearchSubSubMode))) { QKeyEvent *kev = static_cast<QKeyEvent *>(ev); KEY_DEBUG("KEYPRESS" << kev->key() << kev->text() << QChar(kev->key())); EventResult res = d->handleEvent(kev); @@ -5605,7 +7069,7 @@ bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev) //KEY_DEBUG("HANDLED CODE:" << res); //return res != EventPassedToCore; //return true; - return res == EventHandled; + return res == EventHandled || res == EventCancelled; } if (active && ev->type() == QEvent::ShortcutOverride && ob == d->editor()) { @@ -5620,7 +7084,7 @@ bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev) } if (active && ev->type() == QEvent::FocusIn && ob == d->editor()) { - d->stopIncrementalFind(); + d->focus(); } return QObject::eventFilter(ob, ev); @@ -5648,18 +7112,14 @@ void FakeVimHandler::handleCommand(const QString &cmd) void FakeVimHandler::handleReplay(const QString &keys) { - d->replay(keys, 1); + d->replay(keys); } void FakeVimHandler::handleInput(const QString &keys) { - Mode oldMode = d->m_mode; - d->m_mode = CommandMode; - Inputs inputs; - inputs.parseFrom(keys); + Inputs inputs(keys); foreach (const Input &input, inputs) d->handleKey(input); - d->m_mode = oldMode; } void FakeVimHandler::setCurrentFileName(const QString &fileName) @@ -5672,14 +7132,9 @@ QString FakeVimHandler::currentFileName() const return d->m_currentFileName; } -void FakeVimHandler::showBlackMessage(const QString &msg) -{ - d->showBlackMessage(msg); -} - -void FakeVimHandler::showRedMessage(const QString &msg) +void FakeVimHandler::showMessage(MessageLevel level, const QString &msg) { - d->showRedMessage(msg); + d->showMessage(level, msg); } QWidget *FakeVimHandler::widget() @@ -5705,6 +7160,26 @@ QString FakeVimHandler::tabExpand(int n) const return d->tabExpand(n); } +void FakeVimHandler::miniBufferTextEdited(const QString &text, int cursorPos) +{ + d->miniBufferTextEdited(text, cursorPos); +} + +void FakeVimHandler::setTextCursorPosition(int position) +{ + int pos = qMax(0, qMin(position, d->lastPositionInDocument())); + if (d->isVisualMode()) + d->setPosition(pos); + else + d->setAnchorAndPosition(pos, pos); + d->setTargetColumn(); +} + +bool FakeVimHandler::jumpToLocalMark(QChar mark, bool backTickMode) +{ + return d->jumpToMark(mark, backTickMode); +} + } // namespace Internal } // namespace FakeVim diff --git a/src/plugins/fakevim/fakevimhandler.h b/src/plugins/fakevim/fakevimhandler.h index 833fe60ebc..33b1061f05 100644 --- a/src/plugins/fakevim/fakevimhandler.h +++ b/src/plugins/fakevim/fakevimhandler.h @@ -67,7 +67,6 @@ struct ExCommand const Range &range = Range()); bool matches(const QString &min, const QString &full) const; - void setContentsFromLine(const QString &line); QString cmd; bool hasBang; @@ -76,6 +75,17 @@ struct ExCommand int count; }; +// message levels sorted by severity +enum MessageLevel +{ + MessageMode, // show current mode (format "-- %1 --") + MessageCommand, // show last Ex command or search + MessageInfo, // result of a command + MessageWarning, // warning + MessageError, // error + MessageShowCmd // partial command +}; + class FakeVimHandler : public QObject { Q_OBJECT @@ -93,8 +103,7 @@ public slots: void setCurrentFileName(const QString &fileName); QString currentFileName() const; - void showBlackMessage(const QString &msg); - void showRedMessage(const QString &msg); + void showMessage(MessageLevel level, const QString &msg); // This executes an "ex" style command taking context // information from the current widget. @@ -113,11 +122,19 @@ public slots: int logicalIndentation(const QString &line) const; QString tabExpand(int n) const; + void miniBufferTextEdited(const QString &text, int cursorPos); + + // Set text cursor position. Keeps anchor if in visual mode. + void setTextCursorPosition(int position); + + bool jumpToLocalMark(QChar mark, bool backTickMode); + signals: - void commandBufferChanged(const QString &msg, int pos); + void commandBufferChanged(const QString &msg, int pos, int messageLevel, QObject *eventFilter); void statusDataChanged(const QString &msg); void extraInformationChanged(const QString &msg); void selectionChanged(const QList<QTextEdit::ExtraSelection> &selection); + void highlightMatches(const QString &needle); void writeAllRequested(QString *error); void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor); void checkForElectricCharacter(bool *result, QChar c); @@ -130,6 +147,10 @@ signals: void handleExCommandRequested(bool *handled, const ExCommand &cmd); void requestSetBlockSelection(bool on); void requestHasBlockSelection(bool *on); + void foldToggle(int depth); + void foldAll(bool fold); + void fold(int depth, bool fold); + void jumpToGlobalMark(QChar mark, bool backTickMode, const QString &fileName); public: class Private; diff --git a/src/plugins/fakevim/fakevimoptions.ui b/src/plugins/fakevim/fakevimoptions.ui index ff324ce7c8..4582b6b05b 100644 --- a/src/plugins/fakevim/fakevimoptions.ui +++ b/src/plugins/fakevim/fakevimoptions.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>513</width> - <height>449</height> + <height>461</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_2"> @@ -31,63 +31,7 @@ <string>Vim Behavior</string> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0" colspan="2"> - <widget class="QCheckBox" name="checkBoxAutoIndent"> - <property name="text"> - <string>Automatic indentation</string> - </property> - </widget> - </item> - <item row="0" column="2"> - <widget class="QCheckBox" name="checkBoxStartOfLine"> - <property name="text"> - <string>Start of line</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="2"> - <widget class="QCheckBox" name="checkBoxSmartIndent"> - <property name="text"> - <string>Smart indentation</string> - </property> - </widget> - </item> - <item row="1" column="2"> - <widget class="QCheckBox" name="checkBoxUseCoreSearch"> - <property name="text"> - <string>Use search dialog</string> - </property> - </widget> - </item> - <item row="2" column="2"> - <widget class="QCheckBox" name="checkBoxSmartCase"> - <property name="text"> - <string>Use smartcase</string> - </property> - </widget> - </item> - <item row="2" column="0" colspan="2"> - <widget class="QCheckBox" name="checkBoxExpandTab"> - <property name="text"> - <string>Expand tabulators</string> - </property> - </widget> - </item> - <item row="3" column="2"> - <widget class="QCheckBox" name="checkBoxShowMarks"> - <property name="text"> - <string>Show position of text marks</string> - </property> - </widget> - </item> - <item row="3" column="0" colspan="2"> - <widget class="QCheckBox" name="checkBoxSmartTab"> - <property name="text"> - <string>Smart tabulators</string> - </property> - </widget> - </item> - <item row="4" column="2"> + <item row="5" column="2"> <widget class="QCheckBox" name="checkBoxPassControlKey"> <property name="toolTip"> <string>Pass key sequences like Ctrl-S to Qt Creator core instead of interpreting them in FakeVim. This gives easier access to Qt Creator core functionality at the price of losing some features of FakeVim.</string> @@ -111,17 +55,31 @@ </property> </widget> </item> - <item row="6" column="0"> - <widget class="QLabel" name="labelShiftWidth"> + <item row="0" column="2"> + <widget class="QCheckBox" name="checkBoxStartOfLine"> <property name="text"> - <string>Shift width:</string> + <string>Start of line</string> </property> </widget> </item> - <item row="6" column="1" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item row="1" column="0" colspan="2"> + <widget class="QCheckBox" name="checkBoxSmartIndent"> + <property name="text"> + <string>Smart indentation</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QCheckBox" name="checkBoxAutoIndent"> + <property name="text"> + <string>Automatic indentation</string> + </property> + </widget> + </item> + <item row="8" column="1" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> <item> - <widget class="QSpinBox" name="spinBoxShiftWidth"> + <widget class="QSpinBox" name="spinBoxTabStop"> <property name="minimum"> <number>1</number> </property> @@ -131,7 +89,7 @@ </widget> </item> <item> - <spacer name="horizontalSpacer_2"> + <spacer name="horizontalSpacer_3"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -145,7 +103,24 @@ </item> </layout> </item> - <item row="7" column="0"> + <item row="9" column="0"> + <widget class="QLabel" name="labelBackspace"> + <property name="text"> + <string>Backspace:</string> + </property> + </widget> + </item> + <item row="9" column="1" colspan="2"> + <widget class="QLineEdit" name="lineEditBackspace"/> + </item> + <item row="10" column="0"> + <widget class="QLabel" name="labelIsKeyword"> + <property name="text"> + <string>Keyword characters:</string> + </property> + </widget> + </item> + <item row="8" column="0"> <widget class="QLabel" name="labelTabulator"> <property name="toolTip"> <string>Vim tabstop option</string> @@ -155,20 +130,31 @@ </property> </widget> </item> - <item row="7" column="1" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item row="12" column="0" colspan="3"> + <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QSpinBox" name="spinBoxTabStop"> - <property name="minimum"> - <number>1</number> + <widget class="QPushButton" name="pushButtonCopyTextEditorSettings"> + <property name="text"> + <string>Copy Text Editor Settings</string> </property> - <property name="maximum"> - <number>80</number> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonSetQtStyle"> + <property name="text"> + <string>Set Qt Style</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_3"> + <widget class="QPushButton" name="pushButtonSetPlainStyle"> + <property name="text"> + <string>Set Plain Style</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -182,27 +168,38 @@ </item> </layout> </item> - <item row="8" column="0"> - <widget class="QLabel" name="labelBackspace"> + <item row="7" column="0"> + <widget class="QLabel" name="labelShiftWidth"> <property name="text"> - <string>Backspace:</string> + <string>Shift width:</string> </property> </widget> </item> - <item row="8" column="1" colspan="2"> - <widget class="QLineEdit" name="lineEditBackspace"/> + <item row="2" column="0" colspan="2"> + <widget class="QCheckBox" name="checkBoxExpandTab"> + <property name="text"> + <string>Expand tabulators</string> + </property> + </widget> </item> - <item row="9" column="0"> - <widget class="QLabel" name="labelIsKeyword"> + <item row="4" column="2"> + <widget class="QCheckBox" name="checkBoxShowMarks"> <property name="text"> - <string>Keyword characters:</string> + <string>Show position of text marks</string> </property> </widget> </item> - <item row="9" column="1" colspan="2"> + <item row="3" column="0" colspan="2"> + <widget class="QCheckBox" name="checkBoxSmartTab"> + <property name="text"> + <string>Smart tabulators</string> + </property> + </widget> + </item> + <item row="10" column="1" colspan="2"> <widget class="QLineEdit" name="lineEditIsKeyword"/> </item> - <item row="10" column="0"> + <item row="11" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -218,31 +215,41 @@ </property> </spacer> </item> - <item row="11" column="0" colspan="3"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="pushButtonCopyTextEditorSettings"> - <property name="text"> - <string>Copy Text Editor Settings</string> - </property> - </widget> - </item> + <item row="1" column="2"> + <widget class="QCheckBox" name="checkBoxUseCoreSearch"> + <property name="text"> + <string>Use search dialog</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QCheckBox" name="checkBoxSmartCase"> + <property name="text"> + <string>Use smartcase</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QCheckBox" name="checkBoxWrapScan"> + <property name="text"> + <string>Use wrapscan</string> + </property> + </widget> + </item> + <item row="7" column="1" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> - <widget class="QPushButton" name="pushButtonSetQtStyle"> - <property name="text"> - <string>Set Qt Style</string> + <widget class="QSpinBox" name="spinBoxShiftWidth"> + <property name="minimum"> + <number>1</number> </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButtonSetPlainStyle"> - <property name="text"> - <string>Set Plain Style</string> + <property name="maximum"> + <number>80</number> </property> </widget> </item> <item> - <spacer name="horizontalSpacer"> + <spacer name="horizontalSpacer_2"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -256,6 +263,13 @@ </item> </layout> </item> + <item row="6" column="0"> + <widget class="QCheckBox" name="checkBoxShowCmd"> + <property name="text"> + <string>Show partial command</string> + </property> + </widget> + </item> </layout> </widget> </item> @@ -274,6 +288,30 @@ </item> </layout> </widget> + <tabstops> + <tabstop>checkBoxUseFakeVim</tabstop> + <tabstop>checkBoxReadVimRc</tabstop> + <tabstop>checkBoxAutoIndent</tabstop> + <tabstop>checkBoxSmartIndent</tabstop> + <tabstop>checkBoxExpandTab</tabstop> + <tabstop>checkBoxSmartTab</tabstop> + <tabstop>checkBoxHlSearch</tabstop> + <tabstop>checkBoxIncSearch</tabstop> + <tabstop>checkBoxShowCmd</tabstop> + <tabstop>checkBoxStartOfLine</tabstop> + <tabstop>checkBoxUseCoreSearch</tabstop> + <tabstop>checkBoxSmartCase</tabstop> + <tabstop>checkBoxWrapScan</tabstop> + <tabstop>checkBoxShowMarks</tabstop> + <tabstop>checkBoxPassControlKey</tabstop> + <tabstop>spinBoxShiftWidth</tabstop> + <tabstop>spinBoxTabStop</tabstop> + <tabstop>lineEditBackspace</tabstop> + <tabstop>lineEditIsKeyword</tabstop> + <tabstop>pushButtonCopyTextEditorSettings</tabstop> + <tabstop>pushButtonSetQtStyle</tabstop> + <tabstop>pushButtonSetPlainStyle</tabstop> + </tabstops> <resources/> <connections/> </ui> diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index 8b9769f423..46c49bb2b0 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -69,6 +69,7 @@ #include <find/findplugin.h> #include <find/textfindconstants.h> +#include <find/ifindsupport.h> #include <utils/qtcassert.h> #include <utils/savedaction.h> @@ -77,12 +78,15 @@ #include <cpptools/cpptoolsconstants.h> +#include <extensionsystem/pluginmanager.h> + #include <QAbstractTableModel> #include <QDebug> #include <QFile> #include <QtPlugin> #include <QObject> #include <QSettings> +#include <QStackedWidget> #include <QTextStream> #include <QDesktopServices> @@ -108,49 +112,105 @@ const char SETTINGS_ID[] = "A.General"; const char SETTINGS_EX_CMDS_ID[] = "B.ExCommands"; const char SETTINGS_USER_CMDS_ID[] = "C.UserCommands"; -class MiniBuffer : public QLabel +class MiniBuffer : public QStackedWidget { Q_OBJECT public: - void setContents(const QString &contents, int cursorPos) + MiniBuffer() : m_label(new QLabel(this)), m_edit(new QLineEdit(this)), m_eventFilter(0) { - QString msg = contents; - if (cursorPos != -1) - msg = contents.left(cursorPos) + QChar(10073) + contents.mid(cursorPos); - setText(" " + msg); + m_edit->installEventFilter(this); + connect(m_edit, SIGNAL(textEdited(QString)), SLOT(changed())); + connect(m_edit, SIGNAL(cursorPositionChanged(int,int)), SLOT(changed())); + m_label->setTextInteractionFlags(Qt::TextSelectableByMouse); + + addWidget(m_label); + addWidget(m_edit); } -}; -class MiniBuffer1 : public QLineEdit -{ - Q_OBJECT + void setContents(const QString &contents, int cursorPos, int messageLevel, QObject *eventFilter) + { + if (cursorPos != -1) { + m_edit->blockSignals(true); + m_label->clear(); + m_edit->setText(contents); + m_edit->setCursorPosition(cursorPos); + m_edit->blockSignals(false); + + setCurrentWidget(m_edit); + m_edit->setFocus(); + } else if (contents.isEmpty() && messageLevel != MessageShowCmd) { + hide(); + } else { + show(); + m_label->setText(messageLevel == MessageMode ? "-- " + contents + " --" : contents); + + QString css; + if (messageLevel == MessageError) { + css = QString("border:1px solid rgba(255,255,255,150);" + "background-color:rgba(255,0,0,100);"); + } else if (messageLevel == MessageWarning) { + css = QString("border:1px solid rgba(255,255,255,120);" + "background-color:rgba(255,255,0,20);"); + } else if (messageLevel == MessageShowCmd) { + css = QString("border:1px solid rgba(255,255,255,120);" + "background-color:rgba(100,255,100,30);"); + } + m_label->setStyleSheet(QString( + "*{border-radius:2px;padding-left:4px;padding-right:4px;%1}").arg(css)); -public: - MiniBuffer1() + if (m_edit->hasFocus()) + emit edited(QString(), -1); + + setCurrentWidget(m_label); + } + + if (m_eventFilter != eventFilter) { + if (m_eventFilter != 0) { + m_edit->removeEventFilter(m_eventFilter); + disconnect(SIGNAL(edited(QString,int))); + } + if (eventFilter != 0) { + m_edit->installEventFilter(eventFilter); + connect(this, SIGNAL(edited(QString,int)), + eventFilter, SLOT(miniBufferTextEdited(QString,int))); + } + m_eventFilter = eventFilter; + } + } + + QSize sizeHint() const { - setFrame(false); + QSize size = QWidget::sizeHint(); + // reserve maximal width for line edit widget + return currentWidget() == m_edit ? QSize(maximumWidth(), size.height()) : size; } - void showEvent(QShowEvent *ev) + +signals: + void edited(const QString &text, int cursorPos); + +private slots: + void changed() { - QLineEdit::showEvent(ev); - QColor color = Qt::black; - QPalette pal = parentWidget()->palette(); - pal.setBrush(QPalette::All, QPalette::WindowText, color); - pal.setBrush(QPalette::All, QPalette::ButtonText, color); - pal.setBrush(QPalette::All, QPalette::Foreground, color); - pal.setBrush(QPalette::All, QPalette::Background, color); - //color.setAlpha(100); - //pal.setBrush(QPalette::Disabled, QPalette::WindowText, color); - //pal.setBrush(QPalette::Disabled, QPalette::ButtonText, color); - //pal.setBrush(QPalette::Disabled, QPalette::Foreground, color); - setPalette(pal); + emit edited(m_edit->text(), m_edit->cursorPosition()); } - void setContents(const QString &contents, int cursorPos) + + bool eventFilter(QObject *ob, QEvent *ev) { - setText(contents); - setCursorPosition(cursorPos); + // cancel editing on escape + if (m_eventFilter != 0 && ob == m_edit && ev->type() == QEvent::ShortcutOverride + && static_cast<QKeyEvent*>(ev)->key() == Qt::Key_Escape) { + emit edited(QString(), -1); + ev->accept(); + return true; + } + return false; } + +private: + QLabel *m_label; + QLineEdit *m_edit; + QObject *m_eventFilter; }; /////////////////////////////////////////////////////////////////////// @@ -231,12 +291,18 @@ QWidget *FakeVimOptionPage::createPage(QWidget *parent) m_ui.checkBoxAutoIndent); m_group.insert(theFakeVimSetting(ConfigSmartIndent), m_ui.checkBoxSmartIndent); + m_group.insert(theFakeVimSetting(ConfigIncSearch), m_ui.checkBoxIncSearch); m_group.insert(theFakeVimSetting(ConfigUseCoreSearch), m_ui.checkBoxUseCoreSearch); m_group.insert(theFakeVimSetting(ConfigSmartCase), m_ui.checkBoxSmartCase); + m_group.insert(theFakeVimSetting(ConfigWrapScan), + m_ui.checkBoxWrapScan); + + m_group.insert(theFakeVimSetting(ConfigShowCmd), + m_ui.checkBoxShowCmd); connect(m_ui.pushButtonCopyTextEditorSettings, SIGNAL(clicked()), SLOT(copyTextEditorSettings())); @@ -786,17 +852,24 @@ private slots: void windowCommand(int key); void find(bool reverse); void findNext(bool reverse); + void foldToggle(int depth); + void foldAll(bool fold); + void fold(int depth, bool fold); + void jumpToGlobalMark(QChar mark, bool backTickMode, const QString &fileName); void showSettingsDialog(); void maybeReadVimRc(); void setBlockSelection(bool); void hasBlockSelection(bool*); - void showCommandBuffer(const QString &contents, int cursorPos); + void resetCommandBuffer(); + void showCommandBuffer(const QString &contents, int cursorPos, int messageLevel, + QObject *eventFilter); void showExtraInformation(const QString &msg); void changeSelection(const QList<QTextEdit::ExtraSelection> &selections); + void highlightMatches(const QString &needle); void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor); void checkForElectricCharacter(bool *result, QChar c); - void indentRegion(int beginLine, int endLine, QChar typedChar); + void indentRegion(int beginBlock, int endBlock, QChar typedChar); void handleExCommand(bool *handled, const ExCommand &cmd); void writeSettings(); @@ -990,7 +1063,10 @@ bool FakeVimPluginPrivate::initialize() this, SLOT(handleDelayedQuit(bool,Core::IEditor*)), Qt::QueuedConnection); connect(this, SIGNAL(delayedQuitAllRequested(bool)), this, SLOT(handleDelayedQuitAll(bool)), Qt::QueuedConnection); - maybeReadVimRc(); + + // Vimrc can break test so don't source it if running tests. + if (!ExtensionSystem::PluginManager::runningTests()) + maybeReadVimRc(); // << "MODE: " << theFakeVimSetting(ConfigUseFakeVim)->value(); return true; @@ -1285,6 +1361,107 @@ void FakeVimPluginPrivate::findNext(bool reverse) triggerAction(Find::Constants::FIND_NEXT); } +void FakeVimPluginPrivate::foldToggle(int depth) +{ + IEditor *ieditor = EditorManager::currentEditor(); + BaseTextEditorWidget *editor = qobject_cast<BaseTextEditorWidget *>(ieditor->widget()); + QTC_ASSERT(editor != 0, return); + + QTextBlock block = editor->textCursor().block(); + fold(depth, !BaseTextDocumentLayout::isFolded(block)); +} + +void FakeVimPluginPrivate::foldAll(bool fold) +{ + IEditor *ieditor = EditorManager::currentEditor(); + BaseTextEditorWidget *editor = qobject_cast<BaseTextEditorWidget *>(ieditor->widget()); + QTC_ASSERT(editor != 0, return); + + QTextDocument *doc = editor->document(); + BaseTextDocumentLayout *documentLayout = + qobject_cast<BaseTextDocumentLayout*>(doc->documentLayout()); + QTC_ASSERT(documentLayout != 0, return); + + QTextBlock block = editor->document()->firstBlock(); + while (block.isValid()) { + BaseTextDocumentLayout::doFoldOrUnfold(block, !fold); + block = block.next(); + } + + documentLayout->requestUpdate(); + documentLayout->emitDocumentSizeChanged(); +} + +void FakeVimPluginPrivate::fold(int depth, bool fold) +{ + IEditor *ieditor = EditorManager::currentEditor(); + BaseTextEditorWidget *editor = qobject_cast<BaseTextEditorWidget *>(ieditor->widget()); + QTC_ASSERT(editor != 0, return); + + QTextDocument *doc = editor->document(); + BaseTextDocumentLayout *documentLayout = + qobject_cast<BaseTextDocumentLayout*>(doc->documentLayout()); + QTC_ASSERT(documentLayout != 0, return); + + QTextBlock block = editor->textCursor().block(); + int indent = BaseTextDocumentLayout::foldingIndent(block); + if (fold) { + if (BaseTextDocumentLayout::isFolded(block)) { + while (block.isValid() && (BaseTextDocumentLayout::foldingIndent(block) >= indent + || !block.isVisible())) { + block = block.previous(); + } + } + if (BaseTextDocumentLayout::canFold(block)) + ++indent; + while (depth != 0 && block.isValid()) { + const int indent2 = BaseTextDocumentLayout::foldingIndent(block); + if (BaseTextDocumentLayout::canFold(block) && indent2 < indent) { + BaseTextDocumentLayout::doFoldOrUnfold(block, false); + if (depth > 0) + --depth; + indent = indent2; + } + block = block.previous(); + } + } else { + if (BaseTextDocumentLayout::isFolded(block)) { + if (depth < 0) { + // recursively open fold + while (depth < 0 && block.isValid() + && BaseTextDocumentLayout::foldingIndent(block) >= indent) { + if (BaseTextDocumentLayout::canFold(block)) { + BaseTextDocumentLayout::doFoldOrUnfold(block, true); + if (depth > 0) + --depth; + } + block = block.next(); + } + } else { + if (BaseTextDocumentLayout::canFold(block)) { + BaseTextDocumentLayout::doFoldOrUnfold(block, true); + if (depth > 0) + --depth; + } + } + } + } + + documentLayout->requestUpdate(); + documentLayout->emitDocumentSizeChanged(); +} + +void FakeVimPluginPrivate::jumpToGlobalMark(QChar mark, bool backTickMode, + const QString &fileName) +{ + Core::IEditor *iedit = Core::EditorManager::openEditor(fileName); + if (!iedit) + return; + FakeVimHandler *handler = m_editorToHandler.value(iedit, 0); + if (handler) + handler->jumpToLocalMark(mark, backTickMode); +} + // This class defers deletion of a child FakeVimHandler using deleteLater(). class DeferredDeleter : public QObject { @@ -1331,10 +1508,12 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor) connect(handler, SIGNAL(extraInformationChanged(QString)), SLOT(showExtraInformation(QString))); - connect(handler, SIGNAL(commandBufferChanged(QString,int)), - SLOT(showCommandBuffer(QString,int))); + connect(handler, SIGNAL(commandBufferChanged(QString,int,int,QObject*)), + SLOT(showCommandBuffer(QString,int,int,QObject*))); connect(handler, SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)), SLOT(changeSelection(QList<QTextEdit::ExtraSelection>))); + connect(handler, SIGNAL(highlightMatches(QString)), + SLOT(highlightMatches(QString))); connect(handler, SIGNAL(moveToMatchingParenthesis(bool*,bool*,QTextCursor*)), SLOT(moveToMatchingParenthesis(bool*,bool*,QTextCursor*))); connect(handler, SIGNAL(indentRegion(int,int,QChar)), @@ -1355,6 +1534,14 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor) SLOT(find(bool))); connect(handler, SIGNAL(findNextRequested(bool)), SLOT(findNext(bool))); + connect(handler, SIGNAL(foldToggle(int)), + SLOT(foldToggle(int))); + connect(handler, SIGNAL(foldAll(bool)), + SLOT(foldAll(bool))); + connect(handler, SIGNAL(fold(int,bool)), + SLOT(fold(int,bool))); + connect(handler, SIGNAL(jumpToGlobalMark(QChar,bool,QString)), + SLOT(jumpToGlobalMark(QChar,bool,QString))); connect(handler, SIGNAL(handleExCommandRequested(bool*,ExCommand)), SLOT(handleExCommand(bool*,ExCommand))); @@ -1367,7 +1554,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor) // pop up the bar if (theFakeVimSetting(ConfigUseFakeVim)->value().toBool()) { - showCommandBuffer(QString(), -1); + resetCommandBuffer(); handler->setupWidget(); } } @@ -1399,7 +1586,7 @@ void FakeVimPluginPrivate::setUseFakeVimInternal(bool on) //ICore *core = ICore::instance(); //core->updateAdditionalContexts(Context(), // Context(FAKEVIM_CONTEXT)); - showCommandBuffer(QString(), -1); + resetCommandBuffer(); foreach (IEditor *editor, m_editorToHandler.keys()) { if (BaseTextEditorWidget *textEditor = qobject_cast<BaseTextEditorWidget *>(editor->widget())) { @@ -1476,22 +1663,22 @@ void FakeVimPluginPrivate::handleExCommand(bool *handled, const ExCommand &cmd) QFile file3(fileName); file3.open(QIODevice::ReadOnly); QByteArray ba = file3.readAll(); - handler->showBlackMessage(FakeVimHandler::tr("\"%1\" %2 %3L, %4C written") + handler->showMessage(MessageInfo, FakeVimHandler::tr("\"%1\" %2 %3L, %4C written") .arg(fileName).arg(" ") .arg(ba.count('\n')).arg(ba.size())); if (cmd.cmd == "wq") delayedQuitRequested(cmd.hasBang, m_editorToHandler.key(handler)); } else { - handler->showRedMessage(tr("File not saved")); + handler->showMessage(MessageError, tr("File not saved")); } } else if (cmd.matches("wa", "wall")) { // :w[all] QList<IDocument *> toSave = DocumentManager::modifiedDocuments(); QList<IDocument *> failed = DocumentManager::saveModifiedDocumentsSilently(toSave); if (failed.isEmpty()) - handler->showBlackMessage(tr("Saving succeeded")); + handler->showMessage(MessageInfo, tr("Saving succeeded")); else - handler->showRedMessage(tr("%n files not saved", 0, failed.size())); + handler->showMessage(MessageError, tr("%n files not saved", 0, failed.size())); } else if (cmd.matches("q", "quit")) { // :q[uit] emit delayedQuitRequested(cmd.hasBang, m_editorToHandler.key(handler)); @@ -1614,7 +1801,7 @@ void FakeVimPluginPrivate::moveToMatchingParenthesis(bool *moved, bool *forward, } } -void FakeVimPluginPrivate::indentRegion(int beginLine, int endLine, +void FakeVimPluginPrivate::indentRegion(int beginBlock, int endBlock, QChar typedChar) { FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender()); @@ -1632,14 +1819,14 @@ void FakeVimPluginPrivate::indentRegion(int beginLine, int endLine, ? TabSettings::SpacesOnlyTabPolicy : TabSettings::TabsOnlyTabPolicy; QTextDocument *doc = bt->document(); - QTextBlock startBlock = doc->findBlockByNumber(beginLine); + QTextBlock startBlock = doc->findBlockByNumber(beginBlock); // Record line lenghts for mark adjustments - QVector<int> lineLengths(endLine - beginLine + 1); + QVector<int> lineLengths(endBlock - beginBlock + 1); QTextBlock block = startBlock; - for (int i = beginLine; i <= endLine; ++i) { - lineLengths[i - beginLine] = block.text().length(); + for (int i = beginBlock; i <= endBlock; ++i) { + lineLengths[i - beginBlock] = block.text().length(); if (typedChar == 0 && block.text().simplified().isEmpty()) { // clear empty lines QTextCursor cursor(block); @@ -1657,11 +1844,17 @@ void FakeVimPluginPrivate::quitFakeVim() theFakeVimSetting(ConfigUseFakeVim)->setValue(false); } -void FakeVimPluginPrivate::showCommandBuffer(const QString &contents, int cursorPos) +void FakeVimPluginPrivate::resetCommandBuffer() +{ + showCommandBuffer(QString(), -1, 0, 0); +} + +void FakeVimPluginPrivate::showCommandBuffer(const QString &contents, int cursorPos, + int messageLevel, QObject *eventFilter) { //qDebug() << "SHOW COMMAND BUFFER" << contents; if (MiniBuffer *w = qobject_cast<MiniBuffer *>(m_statusBar->widget())) - w->setContents(contents, cursorPos); + w->setContents(contents, cursorPos, messageLevel, eventFilter); } void FakeVimPluginPrivate::showExtraInformation(const QString &text) @@ -1671,14 +1864,22 @@ void FakeVimPluginPrivate::showExtraInformation(const QString &text) QMessageBox::information(handler->widget(), tr("FakeVim Information"), text); } -void FakeVimPluginPrivate::changeSelection - (const QList<QTextEdit::ExtraSelection> &selection) +void FakeVimPluginPrivate::changeSelection(const QList<QTextEdit::ExtraSelection> &selection) { if (FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender())) if (BaseTextEditorWidget *bt = qobject_cast<BaseTextEditorWidget *>(handler->widget())) bt->setExtraSelections(BaseTextEditorWidget::FakeVimSelection, selection); } +void FakeVimPluginPrivate::highlightMatches(const QString &needle) +{ + IEditor *editor = EditorManager::currentEditor(); + QWidget *w = editor->widget(); + Find::IFindSupport *find = Aggregation::query<Find::IFindSupport>(w); + if (find != 0) + find->highlightAll(needle, Find::FindRegularExpression | Find::FindCaseSensitively); +} + int FakeVimPluginPrivate::currentFile() const { OpenEditorsModel *model = EditorManager::instance()->openedEditorsModel(); @@ -1754,6 +1955,48 @@ void FakeVimPlugin::extensionsInitialized() addAutoReleasedObject(d->m_statusBar); } +#ifdef WITH_TESTS +void FakeVimPlugin::setupTest(QString *title, FakeVimHandler **handler, QWidget **edit) +{ + *title = QString("test.cpp"); + Core::IEditor *iedit = Core::EditorManager::openEditorWithContents(Core::Id(), title); + Core::EditorManager::activateEditor(iedit); + *edit = iedit->widget(); + *handler = d->m_editorToHandler.value(iedit, 0); + (*handler)->handleCommand("set startofline"); + +// *handler = 0; +// m_statusMessage.clear(); +// m_statusData.clear(); +// m_infoMessage.clear(); +// if (m_textedit) { +// m_textedit->setPlainText(lines); +// QTextCursor tc = m_textedit->textCursor(); +// tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); +// m_textedit->setTextCursor(tc); +// m_textedit->setPlainText(lines); +// *handler = new FakeVimHandler(m_textedit); +// } else { +// m_plaintextedit->setPlainText(lines); +// QTextCursor tc = m_plaintextedit->textCursor(); +// tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); +// m_plaintextedit->setTextCursor(tc); +// m_plaintextedit->setPlainText(lines); +// *handler = new FakeVimHandler(m_plaintextedit); +// } + +// QObject::connect(*handler, SIGNAL(commandBufferChanged(QString,int)), +// this, SLOT(changeStatusMessage(QString,int))); +// QObject::connect(*handler, SIGNAL(extraInformationChanged(QString)), +// this, SLOT(changeExtraInformation(QString))); +// QObject::connect(*handler, SIGNAL(statusDataChanged(QString)), +// this, SLOT(changeStatusData(QString))); + +// QCOMPARE(EDITOR(toPlainText()), lines); + (*handler)->handleCommand("set iskeyword=@,48-57,_,192-255,a-z,A-Z"); +} +#endif + } // namespace Internal } // namespace FakeVim diff --git a/src/plugins/fakevim/fakevimplugin.h b/src/plugins/fakevim/fakevimplugin.h index 5b4275355d..8cd60b9b98 100644 --- a/src/plugins/fakevim/fakevimplugin.h +++ b/src/plugins/fakevim/fakevimplugin.h @@ -56,6 +56,104 @@ private: private: friend class FakeVimPluginPrivate; FakeVimPluginPrivate *d; + +#ifdef WITH_TESTS +private slots: + void cleanup(); + void test_vim_movement(); + void test_vim_insert(); + void test_vim_fFtT(); + void test_vim_transform_numbers(); + void test_vim_delete(); + void test_vim_delete_inner_word(); + void test_vim_delete_a_word(); + void test_vim_change_a_word(); + void test_vim_change_replace(); + void test_vim_block_selection(); + void test_vim_repeat(); + void test_vim_search(); + void test_vim_indent(); + void test_vim_marks(); + void test_vim_jumps(); + void test_vim_copy_paste(); + void test_vim_undo_redo(); + void test_vim_letter_case(); + void test_vim_code_autoindent(); + void test_vim_code_folding(); + void test_vim_substitute(); + void test_vim_ex_yank(); + void test_vim_ex_delete(); + void test_vim_ex_change(); + void test_vim_ex_shift(); + void test_vim_ex_move(); + void test_vim_ex_join(); + void test_advanced_commands(); + +//public slots: +// void changeStatusData(const QString &info) { m_statusData = info; } +// void changeStatusMessage(const QString &info, int) { m_statusMessage = info; } +// void changeExtraInformation(const QString &info) { m_infoMessage = info; } + +//private slots: +// // functional tests + void test_vim_indentation(); + + // command mode + void test_vim_command_oO(); + void test_vim_command_put_at_eol(); + void test_vim_command_Cxx_down_dot(); + void test_vim_command_Gyyp(); + void test_vim_command_J(); + void test_vim_command_Yp(); + void test_vim_command_cc(); + void test_vim_command_cw(); + void test_vim_command_cj(); + void test_vim_command_ck(); + void test_vim_command_c_dollar(); + void test_vim_command_C(); + void test_vim_command_dd(); + void test_vim_command_dd_2(); + void test_vim_command_d_dollar(); + void test_vim_command_dgg(); + void test_vim_command_dG(); + void test_vim_command_dj(); + void test_vim_command_dk(); + void test_vim_command_D(); + void test_vim_command_dfx_down(); + void test_vim_command_dollar(); + void test_vim_command_down(); + void test_vim_command_dw(); + void test_vim_command_e(); + void test_vim_command_i(); + void test_vim_command_left(); + void test_vim_command_ma_yank(); + void test_vim_command_r(); + void test_vim_command_right(); + void test_vim_command_up(); + void test_vim_command_w(); + void test_vim_command_x(); + void test_vim_command_yyp(); + void test_vim_command_y_dollar(); + + void test_vim_visual_d(); + void test_vim_Visual_d(); + + // special tests + void test_i_cw_i(); + + // map test should be last one since it changes default behaviour + void test_map(); + +//private: +// QString m_statusMessage; +// QString m_statusData; +// QString m_infoMessage; + +private: + struct TestData; + void setup(TestData *data); + void setupTest(QString *title, FakeVimHandler **handler, QWidget **edit); +#endif }; } // namespace Internal diff --git a/src/plugins/find/find.pro b/src/plugins/find/find.pro index 0f71955f91..59e6f32d93 100644 --- a/src/plugins/find/find.pro +++ b/src/plugins/find/find.pro @@ -12,6 +12,7 @@ HEADERS += findtoolwindow.h \ find_global.h \ findtoolbar.h \ findplugin.h \ + searchresultcolor.h \ searchresulttreeitemdelegate.h \ searchresulttreeitemroles.h \ searchresulttreeitems.h \ @@ -38,4 +39,3 @@ FORMS += findwidget.ui \ finddialog.ui RESOURCES += find.qrc - diff --git a/src/plugins/find/find.qbs b/src/plugins/find/find.qbs index 560bb28fda..7b8287e5be 100644 --- a/src/plugins/find/find.qbs +++ b/src/plugins/find/find.qbs @@ -9,24 +9,19 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "cpp" } - cpp.includePaths: [ - ".", - "..", + cpp.includePaths: base.concat([ "generichighlighter", "tooltip", "snippets", - "codeassist", - "../../libs", - buildDirectory - ] + "codeassist" + ]) files: [ - "find.qrc", - "findwidget.ui", "basetextfind.cpp", "basetextfind.h", "currentdocumentfind.cpp", "currentdocumentfind.h", + "find.qrc", "find_global.h", "finddialog.ui", "findplugin.cpp", @@ -35,10 +30,12 @@ QtcPlugin { "findtoolbar.h", "findtoolwindow.cpp", "findtoolwindow.h", + "findwidget.ui", "ifindfilter.cpp", "ifindfilter.h", "ifindsupport.cpp", "ifindsupport.h", + "searchresultcolor.h", "searchresulttreeitemdelegate.cpp", "searchresulttreeitemdelegate.h", "searchresulttreeitemroles.h", @@ -54,7 +51,6 @@ QtcPlugin { "searchresultwindow.h", "textfindconstants.h", "treeviewfind.cpp", - "treeviewfind.h" + "treeviewfind.h", ] } - diff --git a/src/plugins/find/findtoolbar.cpp b/src/plugins/find/findtoolbar.cpp index 004e96da4e..6d35df5d48 100644 --- a/src/plugins/find/findtoolbar.cpp +++ b/src/plugins/find/findtoolbar.cpp @@ -43,6 +43,7 @@ #include <extensionsystem/pluginmanager.h> +#include <utils/hostosinfo.h> #include <utils/stylehelper.h> #include <utils/flowlayout.h> @@ -292,11 +293,7 @@ bool FindToolBar::eventFilter(QObject *obj, QEvent *event) if ((obj == m_ui.findEdit || obj == m_findCompleter->popup()) && event->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast<QKeyEvent *>(event); -#ifdef Q_OS_MAC - if (ke->key() == Qt::Key_Space && (ke->modifiers() & Qt::MetaModifier)) { -#else - if (ke->key() == Qt::Key_Space && (ke->modifiers() & Qt::ControlModifier)) { -#endif + if (ke->key() == Qt::Key_Space && (ke->modifiers() & Utils::HostOsInfo::controlModifier())) { QString completedText = m_currentDocumentFind->completedFindString(); if (!completedText.isEmpty()) { setFindText(completedText); @@ -313,11 +310,7 @@ bool FindToolBar::eventFilter(QObject *obj, QEvent *event) event->accept(); return true; } -#ifdef Q_OS_MAC - } else if (ke->key() == Qt::Key_Space && (ke->modifiers() & Qt::MetaModifier)) { -#else - } else if (ke->key() == Qt::Key_Space && (ke->modifiers() & Qt::ControlModifier)) { -#endif + } else if (ke->key() == Qt::Key_Space && (ke->modifiers() & Utils::HostOsInfo::controlModifier())) { event->accept(); return true; } diff --git a/src/plugins/find/searchresultcolor.h b/src/plugins/find/searchresultcolor.h new file mode 100644 index 0000000000..964efd69fd --- /dev/null +++ b/src/plugins/find/searchresultcolor.h @@ -0,0 +1,19 @@ +#ifndef SEARCHRESULTCOLOR_H +#define SEARCHRESULTCOLOR_H + +#include <QColor> + +namespace Find { +namespace Internal { + +struct SearchResultColor{ + QColor textBackground; + QColor textForeground; + QColor highlightBackground; + QColor highlightForeground; +}; + +} // namespace Internal +} // namespace Find + +#endif // SEARCHRESULTCOLOR_H diff --git a/src/plugins/find/searchresulttreeitemdelegate.cpp b/src/plugins/find/searchresulttreeitemdelegate.cpp index f6464731c5..5110e3d24f 100644 --- a/src/plugins/find/searchresulttreeitemdelegate.cpp +++ b/src/plugins/find/searchresulttreeitemdelegate.cpp @@ -97,19 +97,8 @@ void SearchResultTreeItemDelegate::paint(QPainter *painter, const QStyleOptionVi int lineNumberAreaWidth = drawLineNumber(painter, opt, textRect, index); textRect.adjust(lineNumberAreaWidth, 0, 0, 0); - // selected text - QString displayString = index.model()->data(index, Qt::DisplayRole).toString(); - drawMarker(painter, index, displayString, textRect); - - // show number of subresults in displayString - if (index.model()->hasChildren(index)) { - displayString += QString::fromLatin1(" (") - + QString::number(index.model()->rowCount(index)) - + QLatin1Char(')'); - } - // text and focus/selection - QItemDelegate::drawDisplay(painter, opt, textRect, displayString); + drawText(painter, opt, textRect, index); QItemDelegate::drawFocus(painter, opt, opt.rect); // check mark @@ -159,20 +148,65 @@ int SearchResultTreeItemDelegate::drawLineNumber(QPainter *painter, const QStyle return lineNumberAreaWidth; } -void SearchResultTreeItemDelegate::drawMarker(QPainter *painter, const QModelIndex &index, const QString text, - const QRect &rect) const +void SearchResultTreeItemDelegate::drawText(QPainter *painter, + const QStyleOptionViewItem &opt, + const QRect &rect, + const QModelIndex &index) const { - int searchTermStart = index.model()->data(index, ItemDataRoles::SearchTermStartRole).toInt(); + QString text = index.model()->data(index, Qt::DisplayRole).toString(); + // show number of subresults in displayString + if (index.model()->hasChildren(index)) { + text += QLatin1String(" (") + + QString::number(index.model()->rowCount(index)) + + QLatin1Char(')'); + } + + const int searchTermStart = index.model()->data(index, ItemDataRoles::SearchTermStartRole).toInt(); int searchTermLength = index.model()->data(index, ItemDataRoles::SearchTermLengthRole).toInt(); - if (searchTermStart < 0 || searchTermStart >= text.length() || searchTermLength < 1) + if (searchTermStart < 0 || searchTermStart >= text.length() || searchTermLength < 1) { + QItemDelegate::drawDisplay(painter, opt, rect, text); return; + } // clip searchTermLength to end of line searchTermLength = qMin(searchTermLength, text.length() - searchTermStart); const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; int searchTermStartPixels = painter->fontMetrics().width(text.left(searchTermStart)); int searchTermLengthPixels = painter->fontMetrics().width(text.mid(searchTermStart, searchTermLength)); + + // Text before the highlighting + QRect beforeHighlightRect(rect); + beforeHighlightRect.setRight(beforeHighlightRect.left() + searchTermStartPixels); + QStyleOptionViewItem noHighlightOpt = opt; + noHighlightOpt.rect = beforeHighlightRect; + noHighlightOpt.textElideMode = Qt::ElideNone; + QItemDelegate::drawDisplay(painter, noHighlightOpt, + beforeHighlightRect, text.mid(0, searchTermStart)); + + // Highlight background + QRect highlightBackgroundRect(rect); + highlightBackgroundRect.setLeft(highlightBackgroundRect.left() + + searchTermStartPixels + textMargin - 1); // -1: Cosmetics + highlightBackgroundRect.setRight(highlightBackgroundRect.left() + + searchTermLengthPixels + 1); // +1: Cosmetics + const QColor highlightBackground = + index.model()->data(index, ItemDataRoles::ResultHighlightBackgroundColor).value<QColor>(); + painter->fillRect(highlightBackgroundRect, QBrush(highlightBackground)); + + // Highlight text QRect resultHighlightRect(rect); - resultHighlightRect.setLeft(resultHighlightRect.left() + searchTermStartPixels + textMargin - 1); // -1: Cosmetics - resultHighlightRect.setRight(resultHighlightRect.left() + searchTermLengthPixels + 1); // +1: Cosmetics - painter->fillRect(resultHighlightRect, QBrush(qRgb(255, 240, 120))); + resultHighlightRect.setLeft(beforeHighlightRect.right()); + resultHighlightRect.setRight(resultHighlightRect.left() + searchTermLengthPixels + textMargin); + QStyleOptionViewItem highlightOpt = noHighlightOpt; + const QColor highlightForeground = + index.model()->data(index, ItemDataRoles::ResultHighlightForegroundColor).value<QColor>(); + highlightOpt.palette.setColor(QPalette::Text, highlightForeground); + QItemDelegate::drawDisplay(painter, highlightOpt, resultHighlightRect, + text.mid(searchTermStart, searchTermLength)); + + // Text after the Highlight + QRect afterHighlightRect(rect); + afterHighlightRect.setLeft(resultHighlightRect.right()); + noHighlightOpt.rect = afterHighlightRect; + QItemDelegate::drawDisplay(painter, noHighlightOpt, afterHighlightRect, + text.mid(searchTermStart + searchTermLength)); } diff --git a/src/plugins/find/searchresulttreeitemdelegate.h b/src/plugins/find/searchresulttreeitemdelegate.h index ef1aed121b..e2ff90555a 100644 --- a/src/plugins/find/searchresulttreeitemdelegate.h +++ b/src/plugins/find/searchresulttreeitemdelegate.h @@ -43,7 +43,8 @@ public: private: int drawLineNumber(QPainter *painter, const QStyleOptionViewItemV3 &option, const QRect &rect, const QModelIndex &index) const; - void drawMarker(QPainter *painter, const QModelIndex &index, const QString text, const QRect &rect) const; + void drawText(QPainter *painter, const QStyleOptionViewItem &opt, + const QRect &rect, const QModelIndex &index) const; static const int m_minimumLineNumberDigits = 6; }; diff --git a/src/plugins/find/searchresulttreeitemroles.h b/src/plugins/find/searchresulttreeitemroles.h index 892dd2c607..f633a76775 100644 --- a/src/plugins/find/searchresulttreeitemroles.h +++ b/src/plugins/find/searchresulttreeitemroles.h @@ -42,6 +42,8 @@ enum Roles ResultLineRole, ResultLineNumberRole, ResultIconRole, + ResultHighlightBackgroundColor, + ResultHighlightForegroundColor, SearchTermStartRole, SearchTermLengthRole, IsGeneratedRole diff --git a/src/plugins/find/searchresulttreemodel.cpp b/src/plugins/find/searchresulttreemodel.cpp index 683ecf3e29..b2f75305e8 100644 --- a/src/plugins/find/searchresulttreemodel.cpp +++ b/src/plugins/find/searchresulttreemodel.cpp @@ -30,6 +30,7 @@ #include "searchresulttreemodel.h" #include "searchresulttreeitems.h" #include "searchresulttreeitemroles.h" +#include "searchresultcolor.h" #include <QApplication> #include <QFont> @@ -64,10 +65,11 @@ void SearchResultTreeModel::setShowReplaceUI(bool show) m_showReplaceUI = show; } -void SearchResultTreeModel::setTextEditorFont(const QFont &font) +void SearchResultTreeModel::setTextEditorFont(const QFont &font, const SearchResultColor color) { layoutAboutToBeChanged(); m_textEditorFont = font; + m_color = color; layoutChanged(); } @@ -251,6 +253,14 @@ QVariant SearchResultTreeModel::data(const SearchResultTreeItem *row, int role) else result = QVariant(); break; + case Qt::TextColorRole: + if (row->item.useTextEditorFont) + result = m_color.textForeground; + break; + case Qt::BackgroundRole: + if (row->item.useTextEditorFont) + result = m_color.textBackground; + break; case ItemDataRoles::ResultLineRole: case Qt::DisplayRole: result = row->item.text; @@ -264,6 +274,14 @@ QVariant SearchResultTreeModel::data(const SearchResultTreeItem *row, int role) case ItemDataRoles::ResultIconRole: result = row->item.icon; break; + case ItemDataRoles::ResultHighlightBackgroundColor: + if (row->item.useTextEditorFont) + result = m_color.highlightBackground; + break; + case ItemDataRoles::ResultHighlightForegroundColor: + if (row->item.useTextEditorFont) + result = m_color.highlightForeground; + break; case ItemDataRoles::SearchTermStartRole: result = row->item.textMarkPos; break; @@ -410,10 +428,11 @@ QList<QModelIndex> SearchResultTreeModel::addResults(const QList<SearchResultIte void SearchResultTreeModel::clear() { + beginResetModel(); m_currentParent = NULL; m_rootItem->clearChildren(); m_editorFontIsUsed = false; - reset(); + endResetModel(); } QModelIndex SearchResultTreeModel::nextIndex(const QModelIndex &idx, bool *wrapped) const diff --git a/src/plugins/find/searchresulttreemodel.h b/src/plugins/find/searchresulttreemodel.h index 8dd368f4bf..328b39d754 100644 --- a/src/plugins/find/searchresulttreemodel.h +++ b/src/plugins/find/searchresulttreemodel.h @@ -31,6 +31,7 @@ #define SEARCHRESULTTREEMODEL_H #include "searchresultwindow.h" +#include "searchresultcolor.h" #include <QAbstractItemModel> #include <QRegExp> @@ -51,7 +52,7 @@ public: ~SearchResultTreeModel(); void setShowReplaceUI(bool show); - void setTextEditorFont(const QFont &font); + void setTextEditorFont(const QFont &font, const SearchResultColor color); Qt::ItemFlags flags(const QModelIndex &index) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; @@ -86,6 +87,7 @@ private: SearchResultTreeItem *m_rootItem; SearchResultTreeItem *m_currentParent; + SearchResultColor m_color; QModelIndex m_currentIndex; QStringList m_currentPath; // the path that belongs to the current parent QFont m_textEditorFont; diff --git a/src/plugins/find/searchresulttreeview.cpp b/src/plugins/find/searchresulttreeview.cpp index 494ece8f8d..15b9c62e6f 100644 --- a/src/plugins/find/searchresulttreeview.cpp +++ b/src/plugins/find/searchresulttreeview.cpp @@ -31,6 +31,7 @@ #include "searchresulttreeitemroles.h" #include "searchresulttreemodel.h" #include "searchresulttreeitemdelegate.h" +#include "searchresultcolor.h" #include <QHeaderView> #include <QKeyEvent> @@ -57,9 +58,9 @@ void SearchResultTreeView::setAutoExpandResults(bool expand) m_autoExpandResults = expand; } -void SearchResultTreeView::setTextEditorFont(const QFont &font) +void SearchResultTreeView::setTextEditorFont(const QFont &font, const SearchResultColor color) { - m_model->setTextEditorFont(font); + m_model->setTextEditorFont(font, color); } void SearchResultTreeView::clear() diff --git a/src/plugins/find/searchresulttreeview.h b/src/plugins/find/searchresulttreeview.h index c439a2a7b3..1a123be455 100644 --- a/src/plugins/find/searchresulttreeview.h +++ b/src/plugins/find/searchresulttreeview.h @@ -38,6 +38,7 @@ namespace Find { namespace Internal { class SearchResultTreeModel; +class SearchResultColor; class SearchResultTreeView : public QTreeView { @@ -47,7 +48,7 @@ public: explicit SearchResultTreeView(QWidget *parent = 0); void setAutoExpandResults(bool expand); - void setTextEditorFont(const QFont &font); + void setTextEditorFont(const QFont &font, const SearchResultColor color); SearchResultTreeModel *model() const; void addResults(const QList<Find::SearchResultItem> &items, SearchResult::AddMode mode); diff --git a/src/plugins/find/searchresultwidget.cpp b/src/plugins/find/searchresultwidget.cpp index bca0ca380b..e61d36c614 100644 --- a/src/plugins/find/searchresultwidget.cpp +++ b/src/plugins/find/searchresultwidget.cpp @@ -32,6 +32,7 @@ #include "searchresulttreemodel.h" #include "searchresulttreeitems.h" #include "searchresulttreeitemroles.h" +#include "searchresultcolor.h" #include "ifindsupport.h" #include "treeviewfind.h" @@ -222,7 +223,7 @@ void SearchResultWidget::addResults(const QList<SearchResultItem> &items, Search updateMatchesFoundLabel(); if (firstItems) { if (showWarningMessage()) { - Core::InfoBarEntry info(QLatin1String(UNDO_WARNING_ID), tr("This change cannot be undone.")); + Core::InfoBarEntry info(Core::Id(UNDO_WARNING_ID), tr("This change cannot be undone.")); info.setCustomButtonInfo(tr("Do not warn again"), this, SLOT(hideNoUndoWarning())); m_infoBar.addInfo(info); } @@ -240,7 +241,7 @@ void SearchResultWidget::addResults(const QList<SearchResultItem> &items, Search } else if (m_count > SEARCHRESULT_WARNING_LIMIT && !m_sizeWarningOverridden && !m_sizeWarningActive) { m_sizeWarningActive = true; emit paused(true); - Core::InfoBarEntry info(QLatin1String(SIZE_WARNING_ID), + Core::InfoBarEntry info(Core::Id(SIZE_WARNING_ID), tr("The search resulted in more than %n items, do you still want to continue?", 0, SEARCHRESULT_WARNING_LIMIT)); info.setCancelButtonInfo(tr("Cancel"), this, SLOT(cancelAfterSizeWarning())); @@ -318,9 +319,9 @@ void SearchResultWidget::notifyVisibilityChanged(bool visible) emit visibilityChanged(visible); } -void SearchResultWidget::setTextEditorFont(const QFont &font) +void SearchResultWidget::setTextEditorFont(const QFont &font, const SearchResultColor color) { - m_searchResultTreeView->setTextEditorFont(font); + m_searchResultTreeView->setTextEditorFont(font, color); } void SearchResultWidget::setAutoExpandResults(bool expand) @@ -367,7 +368,7 @@ void SearchResultWidget::restart() m_searchResultTreeView->clear(); m_count = 0; if (m_sizeWarningActive) - m_infoBar.removeInfo(QLatin1String(SIZE_WARNING_ID)); + m_infoBar.removeInfo(Core::Id(SIZE_WARNING_ID)); m_sizeWarningActive = false; m_sizeWarningOverridden = false; m_cancelButton->setVisible(true); @@ -391,7 +392,7 @@ void SearchResultWidget::setSearchAgainEnabled(bool enabled) void SearchResultWidget::finishSearch(bool canceled) { if (m_sizeWarningActive) - m_infoBar.removeInfo(QLatin1String(SIZE_WARNING_ID)); + m_infoBar.removeInfo(Core::Id(SIZE_WARNING_ID)); m_sizeWarningActive = false; m_sizeWarningOverridden = false; m_replaceTextEdit->setEnabled(m_count > 0); @@ -409,20 +410,20 @@ void SearchResultWidget::sendRequestPopup() void SearchResultWidget::hideNoUndoWarning() { setShowWarningMessage(false); - m_infoBar.removeInfo(QLatin1String(UNDO_WARNING_ID)); + m_infoBar.removeInfo(Core::Id(UNDO_WARNING_ID)); } void SearchResultWidget::continueAfterSizeWarning() { m_sizeWarningOverridden = true; m_sizeWarningActive = false; - m_infoBar.removeInfo(QLatin1String(SIZE_WARNING_ID)); + m_infoBar.removeInfo(Core::Id(SIZE_WARNING_ID)); emit paused(false); } void SearchResultWidget::cancelAfterSizeWarning() { - m_infoBar.removeInfo(QLatin1String(SIZE_WARNING_ID)); + m_infoBar.removeInfo(Core::Id(SIZE_WARNING_ID)); m_sizeWarningOverridden = true; m_sizeWarningActive = false; emit cancelled(); @@ -460,7 +461,7 @@ void SearchResultWidget::searchAgain() bool SearchResultWidget::showWarningMessage() const { - if (m_dontAskAgainGroup.isEmpty() || m_infoBar.containsInfo(QLatin1String(UNDO_WARNING_ID))) + if (m_dontAskAgainGroup.isEmpty() || m_infoBar.containsInfo(Core::Id(UNDO_WARNING_ID))) return false; // read settings QSettings *settings = Core::ICore::settings(); diff --git a/src/plugins/find/searchresultwidget.h b/src/plugins/find/searchresultwidget.h index f9022bdf0e..62c4321c93 100644 --- a/src/plugins/find/searchresultwidget.h +++ b/src/plugins/find/searchresultwidget.h @@ -44,6 +44,7 @@ namespace Find { namespace Internal { class SearchResultTreeView; +class SearchResultColor; class SearchResultWidget : public QWidget { @@ -73,7 +74,7 @@ public: void notifyVisibilityChanged(bool visible); - void setTextEditorFont(const QFont &font); + void setTextEditorFont(const QFont &font, const SearchResultColor color); void setAutoExpandResults(bool expand); void expandAll(); diff --git a/src/plugins/find/searchresultwindow.cpp b/src/plugins/find/searchresultwindow.cpp index 980456178a..f8e89d1929 100644 --- a/src/plugins/find/searchresultwindow.cpp +++ b/src/plugins/find/searchresultwindow.cpp @@ -29,6 +29,7 @@ #include "searchresultwindow.h" #include "searchresultwidget.h" +#include "searchresultcolor.h" #include "findtoolwindow.h" #include <coreplugin/icore.h> @@ -96,6 +97,7 @@ namespace Internal { QList<SearchResult *> m_searchResults; int m_currentIndex; QFont m_font; + SearchResultColor m_color; public slots: void setCurrentIndex(int index); @@ -398,7 +400,7 @@ SearchResult *SearchResultWindow::startNewSearch(const QString &label, connect(widget, SIGNAL(navigateStateChanged()), this, SLOT(navigateStateChanged())); connect(widget, SIGNAL(restarted()), d, SLOT(moveWidgetToTop())); connect(widget, SIGNAL(requestPopup(bool)), d, SLOT(popupRequested(bool))); - widget->setTextEditorFont(d->m_font); + widget->setTextEditorFont(d->m_font, d->m_color); widget->setShowReplaceUI(searchOrSearchAndReplace != SearchOnly); widget->setAutoExpandResults(d->m_expandCollapseAction->isChecked()); widget->setInfo(label, toolTip, searchTerm); @@ -470,11 +472,25 @@ void SearchResultWindow::setFocus() \fn void SearchResultWindow::setTextEditorFont(const QFont &font) \internal */ -void SearchResultWindow::setTextEditorFont(const QFont &font) +void SearchResultWindow::setTextEditorFont(const QFont &font, + const QColor &textForegroundColor, + const QColor &textBackgroundColor, + const QColor &highlightForegroundColor, + const QColor &highlightBackgroundColor) { d->m_font = font; + Internal::SearchResultColor color; + color.textBackground = textBackgroundColor; + color.textForeground = textForegroundColor; + color.highlightBackground = highlightBackgroundColor.isValid() + ? highlightBackgroundColor + : textBackgroundColor; + color.highlightForeground = highlightForegroundColor.isValid() + ? highlightForegroundColor + : textForegroundColor; + d->m_color = color; foreach (Internal::SearchResultWidget *widget, d->m_searchResultWidgets) - widget->setTextEditorFont(font); + widget->setTextEditorFont(font, color); } void SearchResultWindow::openNewSearchPanel() diff --git a/src/plugins/find/searchresultwindow.h b/src/plugins/find/searchresultwindow.h index e625f32e49..dc737d1391 100644 --- a/src/plugins/find/searchresultwindow.h +++ b/src/plugins/find/searchresultwindow.h @@ -157,7 +157,11 @@ public: void goToPrev(); bool canNavigate() const; - void setTextEditorFont(const QFont &font); + void setTextEditorFont(const QFont &font, + const QColor &textForegroundColor, + const QColor &textBackgroundColor, + const QColor &highlightForegroundColor, + const QColor &highlightBackgroundColor); void openNewSearchPanel(); // The search result window owns the returned SearchResult diff --git a/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp b/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp index 056974510f..d065040231 100644 --- a/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp +++ b/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp @@ -105,18 +105,11 @@ void GenericBuildConfiguration::setBuildDirectory(const QString &buildDirectory) emit buildDirectoryChanged(); } -BuildConfigWidget *GenericBuildConfiguration::createConfigWidget() +NamedWidget *GenericBuildConfiguration::createConfigWidget() { - return new GenericBuildSettingsWidget; + return new GenericBuildSettingsWidget(this); } -IOutputParser *GenericBuildConfiguration::createOutputParser() const -{ - ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit()); - return tc ? tc->outputParser() : 0; -} - - /*! \class GenericBuildConfigurationFactory */ @@ -236,7 +229,8 @@ BuildConfiguration::BuildType GenericBuildConfiguration::buildType() const // GenericBuildSettingsWidget //////////////////////////////////////////////////////////////////////////////////// -GenericBuildSettingsWidget::GenericBuildSettingsWidget() : m_buildConfiguration(0) +GenericBuildSettingsWidget::GenericBuildSettingsWidget(GenericBuildConfiguration *bc) + : m_buildConfiguration(0) { QFormLayout *fl = new QFormLayout(this); fl->setContentsMargins(0, -1, 0, -1); @@ -247,18 +241,11 @@ GenericBuildSettingsWidget::GenericBuildSettingsWidget() : m_buildConfiguration( m_pathChooser->setEnabled(true); fl->addRow(tr("Build directory:"), m_pathChooser); connect(m_pathChooser, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged())); -} -QString GenericBuildSettingsWidget::displayName() const -{ - return tr("Generic Manager"); -} - -void GenericBuildSettingsWidget::init(BuildConfiguration *bc) -{ - m_buildConfiguration = static_cast<GenericBuildConfiguration *>(bc); + m_buildConfiguration = bc; m_pathChooser->setBaseDirectory(bc->target()->project()->projectDirectory()); m_pathChooser->setPath(m_buildConfiguration->rawBuildDirectory()); + setDisplayName(tr("Generic Manager")); } void GenericBuildSettingsWidget::buildDirectoryChanged() diff --git a/src/plugins/genericprojectmanager/genericbuildconfiguration.h b/src/plugins/genericprojectmanager/genericbuildconfiguration.h index e1f1edef5c..c3348763dd 100644 --- a/src/plugins/genericprojectmanager/genericbuildconfiguration.h +++ b/src/plugins/genericprojectmanager/genericbuildconfiguration.h @@ -31,7 +31,7 @@ #define GENERICBUILDCONFIGURATION_H #include <projectexplorer/buildconfiguration.h> -#include <projectexplorer/buildstep.h> // for BuildConfigWidget +#include <projectexplorer/namedwidget.h> namespace Utils { class PathChooser; } @@ -49,14 +49,13 @@ class GenericBuildConfiguration : public ProjectExplorer::BuildConfiguration public: explicit GenericBuildConfiguration(ProjectExplorer::Target *parent); - ProjectExplorer::BuildConfigWidget *createConfigWidget(); + ProjectExplorer::NamedWidget *createConfigWidget(); QString buildDirectory() const; QString rawBuildDirectory() const; void setBuildDirectory(const QString &buildDirectory); QVariantMap toMap() const; - ProjectExplorer::IOutputParser *createOutputParser() const; BuildType buildType() const; protected: @@ -90,16 +89,12 @@ private: bool canHandle(const ProjectExplorer::Target *t) const; }; -class GenericBuildSettingsWidget : public ProjectExplorer::BuildConfigWidget +class GenericBuildSettingsWidget : public ProjectExplorer::NamedWidget { Q_OBJECT public: - GenericBuildSettingsWidget(); - - QString displayName() const; - - void init(ProjectExplorer::BuildConfiguration *bc); + GenericBuildSettingsWidget(GenericBuildConfiguration *bc); private slots: void buildDirectoryChanged(); diff --git a/src/plugins/genericprojectmanager/genericmakestep.cpp b/src/plugins/genericprojectmanager/genericmakestep.cpp index 6b13077885..62e52d2923 100644 --- a/src/plugins/genericprojectmanager/genericmakestep.cpp +++ b/src/plugins/genericprojectmanager/genericmakestep.cpp @@ -96,16 +96,11 @@ GenericMakeStep::~GenericMakeStep() { } -GenericBuildConfiguration *GenericMakeStep::genericBuildConfiguration() const -{ - return static_cast<GenericBuildConfiguration *>(buildConfiguration()); -} - bool GenericMakeStep::init() { - GenericBuildConfiguration *bc = genericBuildConfiguration(); + BuildConfiguration *bc = buildConfiguration(); if (!bc) - bc = static_cast<GenericBuildConfiguration *>(target()->activeBuildConfiguration()); + bc = target()->activeBuildConfiguration(); m_tasks.clear(); ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit()); @@ -133,11 +128,9 @@ bool GenericMakeStep::init() setIgnoreReturnValue(m_clean); setOutputParser(new GnuMakeParser()); - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); - if (version) - appendOutputParser(new QtSupport::QtParser); - if (tc) - appendOutputParser(tc->outputParser()); + IOutputParser *parser = target()->kit()->createOutputParser(); + if (parser) + appendOutputParser(parser); outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory()); return AbstractProcessStep::init(); @@ -291,18 +284,18 @@ QString GenericMakeStepConfigWidget::displayName() const void GenericMakeStepConfigWidget::updateMakeOverrrideLabel() { - GenericBuildConfiguration *bc = m_makeStep->genericBuildConfiguration(); + BuildConfiguration *bc = m_makeStep->buildConfiguration(); if (!bc) - bc = static_cast<GenericBuildConfiguration *>(m_makeStep->target()->activeBuildConfiguration()); + bc = m_makeStep->target()->activeBuildConfiguration(); m_ui->makeLabel->setText(tr("Override %1:").arg(m_makeStep->makeCommand(bc->environment()))); } void GenericMakeStepConfigWidget::updateDetails() { - GenericBuildConfiguration *bc = m_makeStep->genericBuildConfiguration(); + BuildConfiguration *bc = m_makeStep->buildConfiguration(); if (!bc) - bc = static_cast<GenericBuildConfiguration *>(m_makeStep->target()->activeBuildConfiguration()); + bc = m_makeStep->target()->activeBuildConfiguration(); ProcessParameters param; param.setMacroExpander(bc->macroExpander()); diff --git a/src/plugins/genericprojectmanager/genericmakestep.h b/src/plugins/genericprojectmanager/genericmakestep.h index 2d1113a2b4..54cd157399 100644 --- a/src/plugins/genericprojectmanager/genericmakestep.h +++ b/src/plugins/genericprojectmanager/genericmakestep.h @@ -39,7 +39,6 @@ QT_END_NAMESPACE namespace GenericProjectManager { namespace Internal { -class GenericBuildConfiguration; class GenericMakeStepConfigWidget; class GenericMakeStepFactory; namespace Ui { class GenericMakeStep; } @@ -55,8 +54,6 @@ public: GenericMakeStep(ProjectExplorer::BuildStepList *parent); ~GenericMakeStep(); - GenericBuildConfiguration *genericBuildConfiguration() const; - bool init(); void run(QFutureInterface<bool> &fi); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 650c6094e8..16e8e8785f 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -39,7 +39,6 @@ #include <cpptools/ModelManagerInterface.h> #include <extensionsystem/pluginmanager.h> #include <projectexplorer/abi.h> -#include <projectexplorer/buildenvironmentwidget.h> #include <projectexplorer/buildsteplist.h> #include <projectexplorer/headerpath.h> #include <projectexplorer/kitinformation.h> @@ -237,7 +236,7 @@ void GenericProject::refresh(RefreshOptions options) parseProject(options); if (options & Files) - m_rootNode->refresh(); + m_rootNode->refresh(oldFileList); CPlusPlus::CppModelManagerInterface *modelManager = CPlusPlus::CppModelManagerInterface::instance(); @@ -251,10 +250,11 @@ void GenericProject::refresh(RefreshOptions options) Kit *k = activeTarget() ? activeTarget()->kit() : KitManager::instance()->defaultKit(); ToolChain *tc = k ? ToolChainKitInformation::toolChain(k) : 0; if (tc) { - part->defines = tc->predefinedMacros(QStringList()); + QStringList cxxflags; // FIXME: Can we do better? + part->defines = tc->predefinedMacros(cxxflags); part->defines += '\n'; - foreach (const HeaderPath &headerPath, tc->systemHeaderPaths(SysRootKitInformation::sysRoot(k))) { + foreach (const HeaderPath &headerPath, tc->systemHeaderPaths(cxxflags, SysRootKitInformation::sysRoot(k))) { if (headerPath.kind() == HeaderPath::FrameworkHeaderPath) part->frameworkPaths.append(headerPath.path()); else @@ -398,13 +398,6 @@ IProjectManager *GenericProject::projectManager() const return m_manager; } -QList<BuildConfigWidget*> GenericProject::subConfigWidgets() -{ - QList<BuildConfigWidget*> list; - list << new BuildEnvironmentWidget; - return list; -} - GenericProjectNode *GenericProject::rootProjectNode() const { return m_rootNode; diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h index 192c959a05..b105fdc8e2 100644 --- a/src/plugins/genericprojectmanager/genericproject.h +++ b/src/plugins/genericprojectmanager/genericproject.h @@ -64,8 +64,6 @@ public: Core::IDocument *document() const; ProjectExplorer::IProjectManager *projectManager() const; - QList<ProjectExplorer::BuildConfigWidget*> subConfigWidgets(); - GenericProjectNode *rootProjectNode() const; QStringList files(FilesMode fileMode) const; diff --git a/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp b/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp index 1c9a6d21cb..b4cf19d02a 100644 --- a/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp +++ b/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp @@ -72,7 +72,7 @@ QStringList ProjectFilesFactory::mimeTypes() const Core::Id ProjectFilesFactory::id() const { - return Constants::FILES_EDITOR_ID; + return Core::Id(Constants::FILES_EDITOR_ID); } QString ProjectFilesFactory::displayName() const @@ -94,7 +94,7 @@ ProjectFilesEditor::ProjectFilesEditor(ProjectFilesEditorWidget *editor) Core::Id ProjectFilesEditor::id() const { - return Constants::FILES_EDITOR_ID; + return Core::Id(Constants::FILES_EDITOR_ID); } bool ProjectFilesEditor::duplicateSupported() const diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.qbs b/src/plugins/genericprojectmanager/genericprojectmanager.qbs index 9b47c6767b..8a47a547cb 100644 --- a/src/plugins/genericprojectmanager/genericprojectmanager.qbs +++ b/src/plugins/genericprojectmanager/genericprojectmanager.qbs @@ -15,39 +15,31 @@ QtcPlugin { Depends { name: "Locator" } Depends { name: "QtSupport" } - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ + "filesselectionwizardpage.cpp", + "filesselectionwizardpage.h", + "genericbuildconfiguration.cpp", + "genericbuildconfiguration.h", + "genericmakestep.cpp", + "genericmakestep.h", + "genericmakestep.ui", + "genericproject.cpp", "genericproject.h", - "genericprojectplugin.h", - "genericprojectmanager.h", + "genericproject.qrc", "genericprojectconstants.h", - "genericprojectnodes.h", - "genericprojectwizard.h", + "genericprojectfileseditor.cpp", "genericprojectfileseditor.h", - "pkgconfigtool.h", - "genericmakestep.h", - "genericbuildconfiguration.h", - "selectablefilesmodel.h", - "filesselectionwizardpage.h", - "genericproject.cpp", - "genericprojectplugin.cpp", "genericprojectmanager.cpp", + "genericprojectmanager.h", "genericprojectnodes.cpp", + "genericprojectnodes.h", + "genericprojectplugin.cpp", + "genericprojectplugin.h", "genericprojectwizard.cpp", - "genericprojectfileseditor.cpp", + "genericprojectwizard.h", "pkgconfigtool.cpp", - "genericmakestep.cpp", - "genericbuildconfiguration.cpp", + "pkgconfigtool.h", "selectablefilesmodel.cpp", - "filesselectionwizardpage.cpp", - "genericmakestep.ui", - "genericproject.qrc", + "selectablefilesmodel.h", ] } - diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.cpp b/src/plugins/genericprojectmanager/genericprojectnodes.cpp index 336800dde3..89b5a683a2 100644 --- a/src/plugins/genericprojectmanager/genericprojectnodes.cpp +++ b/src/plugins/genericprojectmanager/genericprojectnodes.cpp @@ -56,67 +56,76 @@ QString GenericProjectNode::projectFilePath() const return m_projectFile->fileName(); } -void GenericProjectNode::refresh() +QHash<QString, QStringList> sortFilesIntoPaths(const QString &base, const QSet<QString> files) { - // remove the existing nodes. - removeFileNodes(fileNodes(), this); - removeFolderNodes(subFolderNodes(), this); - - //ProjectExplorerPlugin::instance()->setCurrentNode(0); // ### remove me - - FileNode *projectFilesNode = new FileNode(m_project->filesFileName(), - ProjectFileType, - /* generated = */ false); - - FileNode *projectIncludesNode = new FileNode(m_project->includesFileName(), - ProjectFileType, - /* generated = */ false); - - FileNode *projectConfigNode = new FileNode(m_project->configFileName(), - ProjectFileType, - /* generated = */ false); - - QStringList files = m_project->files(); - files.removeAll(m_project->filesFileName()); - files.removeAll(m_project->includesFileName()); - files.removeAll(m_project->configFileName()); - - addFileNodes(QList<FileNode *>() - << projectFilesNode - << projectIncludesNode - << projectConfigNode, - this); - - QStringList filePaths; QHash<QString, QStringList> filesInPath; - const QString base = QFileInfo(path()).absolutePath(); const QDir baseDir(base); foreach (const QString &absoluteFileName, files) { QFileInfo fileInfo(absoluteFileName); - const QString absoluteFilePath = fileInfo.path(); + Utils::FileName absoluteFilePath = Utils::FileName::fromString(fileInfo.path()); QString relativeFilePath; - if (absoluteFilePath.startsWith(base)) { - relativeFilePath = absoluteFilePath.mid(base.length() + 1); + if (absoluteFilePath.isChildOf(baseDir)) { + relativeFilePath = absoluteFilePath.relativeChildPath(Utils::FileName::fromString(base)).toString(); } else { // `file' is not part of the project. - relativeFilePath = baseDir.relativeFilePath(absoluteFilePath); + relativeFilePath = baseDir.relativeFilePath(absoluteFilePath.toString()); } - if (! filePaths.contains(relativeFilePath)) - filePaths.append(relativeFilePath); - filesInPath[relativeFilePath].append(absoluteFileName); } + return filesInPath; +} + +void GenericProjectNode::refresh(QSet<QString> oldFileList) +{ + if (oldFileList.isEmpty()) { + // Only do this once + FileNode *projectFilesNode = new FileNode(m_project->filesFileName(), + ProjectFileType, + /* generated = */ false); + + FileNode *projectIncludesNode = new FileNode(m_project->includesFileName(), + ProjectFileType, + /* generated = */ false); + + FileNode *projectConfigNode = new FileNode(m_project->configFileName(), + ProjectFileType, + /* generated = */ false); + + addFileNodes(QList<FileNode *>() + << projectFilesNode + << projectIncludesNode + << projectConfigNode, + this); + } - FolderByName folderByName; - foreach (const QString &filePath, filePaths) { + // Do those separately + oldFileList.remove(m_project->filesFileName()); + oldFileList.remove(m_project->includesFileName()); + oldFileList.remove(m_project->configFileName()); + + QSet<QString> newFileList = m_project->files().toSet(); + newFileList.remove(m_project->filesFileName()); + newFileList.remove(m_project->includesFileName()); + newFileList.remove(m_project->configFileName()); + + QSet<QString> removed = oldFileList; + removed.subtract(newFileList); + QSet<QString> added = newFileList; + added.subtract(oldFileList); + + QString baseDir = QFileInfo(path()).absolutePath(); + QHash<QString, QStringList> filesInPaths = sortFilesIntoPaths(baseDir, added); + foreach (const QString &filePath, filesInPaths.keys()) { QStringList components = filePath.split(QLatin1Char('/')); - FolderNode *folder = findOrCreateFolderByName(&folderByName, components, components.size()); + FolderNode *folder = findFolderByName(components, components.size()); + if (!folder) + folder = createFolderByName(components, components.size()); QList<FileNode *> fileNodes; - foreach (const QString &file, filesInPath.value(filePath)) { + foreach (const QString &file, filesInPaths.value(filePath)) { FileType fileType = SourceType; // ### FIXME FileNode *fileNode = new FileNode(file, fileType, /*generated = */ false); fileNodes.append(fileNode); @@ -124,18 +133,45 @@ void GenericProjectNode::refresh() addFileNodes(fileNodes, folder); } + + filesInPaths = sortFilesIntoPaths(baseDir, removed); + foreach (const QString &filePath, filesInPaths.keys()) { + QStringList components = filePath.split(QLatin1Char('/')); + FolderNode *folder = findFolderByName(components, components.size()); + + QList<FileNode *> fileNodes; + foreach (const QString &file, filesInPaths.value(filePath)) { + foreach (FileNode *fn, folder->fileNodes()) + if (fn->path() == file) + fileNodes.append(fn); + } + + removeFileNodes(fileNodes, folder); + } + + foreach (FolderNode *fn, subFolderNodes()) + removeEmptySubFolders(this, fn); + } -FolderNode *GenericProjectNode::findOrCreateFolderByName - (FolderByName *folderByName, const QStringList &components, int end) +void GenericProjectNode::removeEmptySubFolders(FolderNode *gparent, FolderNode *parent) { - if (!end) - return 0; + foreach (FolderNode *fn, parent->subFolderNodes()) + removeEmptySubFolders(parent, fn); + + if (parent->subFolderNodes().isEmpty() && parent->fileNodes().isEmpty()) + removeFolderNodes(QList<FolderNode*>() << parent, gparent); +} + +FolderNode *GenericProjectNode::createFolderByName(const QStringList &components, int end) +{ + if (end == 0) + return this; QString folderName; for (int i = 0; i < end; ++i) { folderName.append(components.at(i)); - folderName += QLatin1Char('/'); // ### FIXME + folderName += QLatin1Char('/'); } const QString component = components.at(end - 1); @@ -143,22 +179,41 @@ FolderNode *GenericProjectNode::findOrCreateFolderByName if (component.isEmpty()) return this; - else if (FolderNode *folder = folderByName->value(folderName)) - return folder; - const QString baseDir = QFileInfo(path()).path(); FolderNode *folder = new FolderNode(baseDir + QLatin1Char('/') + folderName); folder->setDisplayName(component); - folderByName->insert(folderName, folder); - FolderNode *parent = findOrCreateFolderByName(folderByName, components, end - 1); + FolderNode *parent = findFolderByName(components, end - 1); if (!parent) - parent = this; + parent = createFolderByName(components, end - 1); addFolderNodes(QList<FolderNode*>() << folder, parent); return folder; } +FolderNode *GenericProjectNode::findFolderByName(const QStringList &components, int end) +{ + if (end == 0) + return this; + + QString folderName; + for (int i = 0; i < end; ++i) { + folderName.append(components.at(i)); + folderName += QLatin1Char('/'); + } + + FolderNode *parent = findFolderByName(components, end - 1); + + if (!parent) + return 0; + + const QString baseDir = QFileInfo(path()).path(); + foreach (FolderNode *fn, parent->subFolderNodes()) + if (fn->path() == baseDir + QLatin1Char('/') + folderName) + return fn; + return 0; +} + bool GenericProjectNode::hasBuildTargets() const { return true; diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.h b/src/plugins/genericprojectmanager/genericprojectnodes.h index 82249749d6..a34e0dfdfb 100644 --- a/src/plugins/genericprojectmanager/genericprojectnodes.h +++ b/src/plugins/genericprojectmanager/genericprojectnodes.h @@ -34,6 +34,7 @@ #include <QStringList> #include <QHash> +#include <QSet> namespace Core { class IDocument; @@ -77,12 +78,13 @@ public: QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node); - void refresh(); + void refresh(QSet<QString> oldFileList = QSet<QString>()); private: typedef QHash<QString, FolderNode *> FolderByName; - FolderNode *findOrCreateFolderByName(FolderByName *folderByName, - const QStringList &components, int end); + FolderNode *createFolderByName(const QStringList &components, int end); + FolderNode *findFolderByName(const QStringList &components, int end); + void removeEmptySubFolders(FolderNode *gparent, FolderNode *parent); private: GenericProject *m_project; diff --git a/src/plugins/git/commitdata.cpp b/src/plugins/git/commitdata.cpp index 87a18d5a72..a68b166f63 100644 --- a/src/plugins/git/commitdata.cpp +++ b/src/plugins/git/commitdata.cpp @@ -88,58 +88,67 @@ void CommitData::clear() files.clear(); } -static CommitData::FileState stateFor(const QChar &c) +static FileStates stateFor(const QChar &c) { switch (c.unicode()) { case ' ': - return CommitData::UntrackedFile; + return UntrackedFile; case 'M': - return CommitData::ModifiedFile; + return ModifiedFile; case 'A': - return CommitData::AddedFile; + return AddedFile; case 'D': - return CommitData::DeletedFile; + return DeletedFile; case 'R': - return CommitData::RenamedFile; + return RenamedFile; case 'C': - return CommitData::CopiedFile; + return CopiedFile; case 'U': - return CommitData::UpdatedFile; + return UnmergedFile; default: - return CommitData::UnknownFileState; + return UnknownFileState; } } -static bool checkLine(const QString &stateInfo, const QString &file, QList<CommitData::StateFilePair> *files) +bool CommitData::checkLine(const QString &stateInfo, const QString &file) { QTC_ASSERT(stateInfo.count() == 2, return false); - QTC_ASSERT(files, return false); if (stateInfo == QLatin1String("??")) { - files->append(qMakePair(CommitData::UntrackedFile, file)); + files.append(qMakePair(FileStates(UntrackedFile), file)); return true; } - CommitData::FileState stagedState = stateFor(stateInfo.at(0)); - if (stagedState == CommitData::UnknownFileState) + FileStates xState = stateFor(stateInfo.at(0)); + FileStates yState = stateFor(stateInfo.at(1)); + if (xState == UnknownFileState || yState == UnknownFileState) return false; - stagedState = static_cast<CommitData::FileState>(stagedState | CommitData::StagedFile); - if (stagedState != CommitData::StagedFile) - files->append(qMakePair(stagedState, file)); - - CommitData::FileState state = stateFor(stateInfo.at(1)); - if (state == CommitData::UnknownFileState) - return false; + bool isMerge = (xState == UnmergedFile || yState == UnmergedFile || + ((xState == yState) && (xState == AddedFile || xState == DeletedFile))); + if (isMerge) { + if (xState == yState) { + if (xState == UnmergedFile) + xState = ModifiedFile; + files.append(qMakePair(xState | UnmergedFile | UnmergedUs | UnmergedThem, file)); + } else if (xState == UnmergedFile) { + files.append(qMakePair(yState | UnmergedFile | UnmergedThem, file)); + } else { + files.append(qMakePair(xState | UnmergedFile | UnmergedUs, file)); + } + } else { + xState |= StagedFile; + if (xState != StagedFile) + files.append(qMakePair(xState, file)); - if (state != CommitData::UntrackedFile) { - QString newFile = file; - if (stagedState == CommitData::RenamedStagedFile || stagedState == CommitData::CopiedStagedFile) - newFile = file.mid(file.indexOf(QLatin1String(" -> ")) + 4); + if (yState != UntrackedFile) { + QString newFile = file; + if (xState & (RenamedFile | CopiedFile)) + newFile = file.mid(file.indexOf(QLatin1String(" -> ")) + 4); - files->append(qMakePair(state, newFile)); + files.append(qMakePair(yState, newFile)); + } } - return true; } @@ -165,24 +174,24 @@ bool CommitData::parseFilesFromStatus(const QString &output) QString file = line.mid(3); if (file.startsWith(QLatin1Char('"'))) file.remove(0, 1).chop(1); - if (!checkLine(line.mid(0, 2), file, &files)) + if (!checkLine(line.mid(0, 2), file)) return false; } return true; } -QStringList CommitData::filterFiles(const CommitData::FileState &state) const +QStringList CommitData::filterFiles(const FileStates &state) const { QStringList result; foreach (const StateFilePair &p, files) { - if (state == AllStates || state == p.first) + if (state == p.first) result.append(p.second); } return result; } -QString CommitData::stateDisplayName(const FileState &state) +QString CommitData::stateDisplayName(const FileStates &state) { QString resultState; if (state == UntrackedFile) @@ -200,8 +209,14 @@ QString CommitData::stateDisplayName(const FileState &state) resultState.append(QCoreApplication::translate("Git::Internal::CommitData", "renamed")); else if (state & CopiedFile) resultState.append(QCoreApplication::translate("Git::Internal::CommitData", "copied")); - else if (state & UpdatedFile) - resultState.append(QCoreApplication::translate("Git::Internal::CommitData", "updated")); + if (state & UnmergedUs) { + if (state & UnmergedThem) + resultState.append(QCoreApplication::translate("Git::Internal::CommitData", " by both")); + else + resultState.append(QCoreApplication::translate("Git::Internal::CommitData", " by us")); + } else if (state & UnmergedThem) { + resultState.append(QCoreApplication::translate("Git::Internal::CommitData", " by them")); + } return resultState; } diff --git a/src/plugins/git/commitdata.h b/src/plugins/git/commitdata.h index 99b2511827..2e55a53392 100644 --- a/src/plugins/git/commitdata.h +++ b/src/plugins/git/commitdata.h @@ -64,33 +64,29 @@ struct GitSubmitEditorPanelData QDebug operator<<(QDebug d, const GitSubmitEditorPanelData &); +enum FileState { + UntrackedFile = 0, + + StagedFile = 0x01, + ModifiedFile = 0x02, + AddedFile = 0x04, + DeletedFile = 0x08, + RenamedFile = 0x10, + CopiedFile = 0x20, + UnmergedFile = 0x40, + + UnmergedUs = 0x100, + UnmergedThem = 0x200, + + UnknownFileState = 0x800 +}; +Q_DECLARE_FLAGS(FileStates, FileState) + class CommitData { public: - enum FileState { - UntrackedFile = 0, - - StagedFile = 0x01, - ModifiedFile = 0x02, - AddedFile = 0x04, - DeletedFile = 0x08, - RenamedFile = 0x10, - CopiedFile = 0x20, - UpdatedFile = 0x40, - - ModifiedStagedFile = StagedFile | ModifiedFile, - AddedStagedFile = StagedFile | AddedFile, - DeletedStagedFile = StagedFile | DeletedFile, - RenamedStagedFile = StagedFile | RenamedFile, - CopiedStagedFile = StagedFile | CopiedFile, - UpdatedStagedFile = StagedFile | UpdatedFile, - - AllStates = UpdatedFile | CopiedFile | RenamedFile | DeletedFile | AddedFile | ModifiedFile | StagedFile, - UnknownFileState - }; - // A pair of state string/file name ('modified', 'file.cpp'). - typedef QPair<FileState, QString> StateFilePair; + typedef QPair<FileStates, QString> StateFilePair; void clear(); // Parse the files and the branch of panelInfo @@ -99,9 +95,9 @@ public: // Convenience to retrieve the file names from // the specification list. Optionally filter for a certain state - QStringList filterFiles(const FileState &state = AllStates) const; + QStringList filterFiles(const FileStates &state) const; - static QString stateDisplayName(const FileState &state); + static QString stateDisplayName(const FileStates &state); QString amendSHA1; QString commitEncoding; @@ -109,9 +105,14 @@ public: GitSubmitEditorPanelData panelData; QList<StateFilePair> files; + +private: + bool checkLine(const QString &stateInfo, const QString &file); }; } // namespace Internal } // namespace Git +Q_DECLARE_OPERATORS_FOR_FLAGS(Git::Internal::FileStates) + #endif // COMMITDATA_H diff --git a/src/plugins/git/gerrit/gerritmodel.cpp b/src/plugins/git/gerrit/gerritmodel.cpp index 2ad922e030..9af51c1367 100644 --- a/src/plugins/git/gerrit/gerritmodel.cpp +++ b/src/plugins/git/gerrit/gerritmodel.cpp @@ -43,9 +43,14 @@ #include <QUrl> #include <QTextStream> #include <QDesktopServices> +#include <QMessageBox> +#include <QPushButton> #include <QTextStream> #include <QDebug> #include <QScopedPointer> +#include <QTimer> +#include <QApplication> +#include <QMessageBox> #if QT_VERSION >= 0x050000 # include <QJsonDocument> # include <QJsonValue> @@ -258,6 +263,7 @@ private slots: void processFinished(int exitCode, QProcess::ExitStatus); void readyReadStandardError(); void readyReadStandardOutput(); + void timeout(); private: void startQuery(const QString &query); @@ -266,6 +272,7 @@ private: const QSharedPointer<GerritParameters> m_parameters; const QStringList m_queries; QProcess m_process; + QTimer m_timer; QString m_binary; QByteArray m_output; int m_currentQuery; @@ -273,6 +280,8 @@ private: QStringList m_baseArguments; }; +enum { timeOutMS = 30000 }; + QueryContext::QueryContext(const QStringList &queries, const QSharedPointer<GerritParameters> &p, QObject *parent) @@ -297,12 +306,18 @@ QueryContext::QueryContext(const QStringList &queries, << QLatin1String("--format=JSON"); m_binary = m_baseArguments.front(); m_baseArguments.pop_front(); + + m_timer.setInterval(timeOutMS); + m_timer.setSingleShot(true); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(timeout())); } QueryContext::~QueryContext() { if (m_progress.isRunning()) m_progress.reportFinished(); + if (m_timer.isActive()) + m_timer.stop(); m_process.disconnect(this); Utils::SynchronousProcess::stopProcess(m_process); } @@ -323,6 +338,7 @@ void QueryContext::startQuery(const QString &query) arguments.push_back(query); VcsBase::VcsBaseOutputWindow::instance() ->appendCommand(m_process.workingDirectory(), m_binary, arguments); + m_timer.start(); m_process.start(m_binary, arguments); m_process.closeWriteChannel(); } @@ -347,6 +363,8 @@ void QueryContext::processError(QProcess::ProcessError e) void QueryContext::processFinished(int exitCode, QProcess::ExitStatus es) { + if (m_timer.isActive()) + m_timer.stop(); if (es != QProcess::NormalExit) { errorTermination(tr("%1 crashed.").arg(m_binary)); return; @@ -376,6 +394,32 @@ void QueryContext::readyReadStandardOutput() m_output.append(m_process.readAllStandardOutput()); } +void QueryContext::timeout() +{ + if (m_process.state() != QProcess::Running) + return; + + QWidget *parent = QApplication::activeModalWidget(); + if (!parent) + parent = QApplication::activeWindow(); + QMessageBox box(QMessageBox::Question, tr("Timeout"), + tr("The gerrit process has not responded within %1s.\n" + "Most likely this is caused by problems with SSH-authentication.\n" + "Would you like to terminate it?"). + arg(timeOutMS / 1000), QMessageBox::NoButton, parent); + QPushButton *terminateButton = box.addButton(tr("Terminate"), QMessageBox::YesRole); + box.addButton(tr("Keep running"), QMessageBox::NoRole); + connect(&m_process, SIGNAL(finished(int)), &box, SLOT(reject())); + box.exec(); + if (m_process.state() != QProcess::Running) + return; + if (box.clickedButton() == terminateButton) { + Utils::SynchronousProcess::stopProcess(m_process); + } else { + m_timer.start(); + } +} + GerritModel::GerritModel(const QSharedPointer<GerritParameters> &p, QObject *parent) : QStandardItemModel(0, ColumnCount, parent) , m_parameters(p) diff --git a/src/plugins/git/gerrit/gerritoptionspage.h b/src/plugins/git/gerrit/gerritoptionspage.h index e27729c0c4..a4111ae83f 100644 --- a/src/plugins/git/gerrit/gerritoptionspage.h +++ b/src/plugins/git/gerrit/gerritoptionspage.h @@ -34,7 +34,7 @@ #include <QWidget> #include <QSharedPointer> -#include <QWeakPointer> +#include <QPointer> QT_BEGIN_NAMESPACE class QLineEdit; @@ -84,7 +84,7 @@ public: private: const QSharedPointer<GerritParameters> &m_parameters; - QWeakPointer<GerritOptionsWidget> m_widget; + QPointer<GerritOptionsWidget> m_widget; }; } // namespace Internal diff --git a/src/plugins/git/gerrit/gerritparameters.cpp b/src/plugins/git/gerrit/gerritparameters.cpp index 007c14cb51..7a3c6c1801 100644 --- a/src/plugins/git/gerrit/gerritparameters.cpp +++ b/src/plugins/git/gerrit/gerritparameters.cpp @@ -35,6 +35,7 @@ #else # include <utils/environment.h> #endif +#include <utils/hostosinfo.h> #include <utils/pathchooser.h> #include <QDebug> #include <QFileInfo> @@ -71,16 +72,16 @@ static inline QString detectSsh() #endif if (!ssh.isEmpty()) return ssh; -#ifdef Q_OS_WIN // Windows: Use ssh.exe from git if it cannot be found. - const QString git = GerritPlugin::gitBinary(); - if (!git.isEmpty()) { - // Is 'git\cmd' in the path (folder containing .bats)? - QString path = QFileInfo(git).absolutePath(); - if (path.endsWith(QLatin1String("cmd"), Qt::CaseInsensitive)) - path.replace(path.size() - 3, 3, QLatin1String("bin")); - ssh = path + QLatin1Char('/') + QLatin1String(defaultSshC); + if (Utils::HostOsInfo::isWindowsHost()) { // Windows: Use ssh.exe from git if it cannot be found. + const QString git = GerritPlugin::gitBinary(); + if (!git.isEmpty()) { + // Is 'git\cmd' in the path (folder containing .bats)? + QString path = QFileInfo(git).absolutePath(); + if (path.endsWith(QLatin1String("cmd"), Qt::CaseInsensitive)) + path.replace(path.size() - 3, 3, QLatin1String("bin")); + ssh = path + QLatin1Char('/') + QLatin1String(defaultSshC); + } } -#endif return ssh; } diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp index 815b4886b5..bc35d31c8f 100644 --- a/src/plugins/git/gerrit/gerritplugin.cpp +++ b/src/plugins/git/gerrit/gerritplugin.cpp @@ -33,10 +33,10 @@ #include "gerritmodel.h" #include "gerritoptionspage.h" -#include <gitplugin.h> -#include <gitclient.h> -#include <gitversioncontrol.h> -#include <gitconstants.h> +#include "../gitplugin.h" +#include "../gitclient.h" +#include "../gitversioncontrol.h" +#include "../gitconstants.h" #include <vcsbase/vcsbaseconstants.h> #include <vcsbase/vcsbaseeditor.h> diff --git a/src/plugins/git/gerrit/gerritplugin.h b/src/plugins/git/gerrit/gerritplugin.h index 0ab90870b7..9e096f393e 100644 --- a/src/plugins/git/gerrit/gerritplugin.h +++ b/src/plugins/git/gerrit/gerritplugin.h @@ -31,8 +31,8 @@ #define GERRIT_INTERNAL_GERRITPLUGIN_H #include <QObject> +#include <QPointer> #include <QSharedPointer> -#include <QWeakPointer> namespace Core { class ActionContainer; @@ -70,7 +70,7 @@ private: void fetch(const QSharedPointer<Gerrit::Internal::GerritChange> &change, int mode); QSharedPointer<GerritParameters> m_parameters; - QWeakPointer<GerritDialog> m_dialog; + QPointer<GerritDialog> m_dialog; }; } // namespace Internal diff --git a/src/plugins/git/git.pro b/src/plugins/git/git.pro index fb887a2e55..873ad6bacd 100644 --- a/src/plugins/git/git.pro +++ b/src/plugins/git/git.pro @@ -28,7 +28,8 @@ HEADERS += gitplugin.h \ remotemodel.h \ remotedialog.h \ branchadddialog.h \ - resetdialog.h + resetdialog.h \ + mergetool.h SOURCES += gitplugin.cpp \ gitclient.cpp \ @@ -50,7 +51,8 @@ SOURCES += gitplugin.cpp \ remotemodel.cpp \ remotedialog.cpp \ branchadddialog.cpp \ - resetdialog.cpp + resetdialog.cpp \ + mergetool.cpp FORMS += changeselectiondialog.ui \ settingspage.ui \ diff --git a/src/plugins/git/git.qbs b/src/plugins/git/git.qbs index 64ce4ff905..ec5a0af292 100644 --- a/src/plugins/git/git.qbs +++ b/src/plugins/git/git.qbs @@ -14,28 +14,16 @@ QtcPlugin { Depends { name: "cpp" } cpp.defines: base.concat(["QT_NO_CAST_FROM_ASCII"]) - cpp.includePaths: [ - ".", - "gitorious", - "gerrit", - "..", - "../../libs", - buildDirectory - ] files: [ - "branchadddialog.ui", - "branchdialog.ui", - "git.qrc", - "gitsubmitpanel.ui", - "remoteadditiondialog.ui", - "stashdialog.ui", "annotationhighlighter.cpp", "annotationhighlighter.h", "branchadddialog.cpp", "branchadddialog.h", + "branchadddialog.ui", "branchdialog.cpp", "branchdialog.h", + "branchdialog.ui", "branchmodel.cpp", "branchmodel.h", "changeselectiondialog.cpp", @@ -47,6 +35,7 @@ QtcPlugin { "clonewizardpage.h", "commitdata.cpp", "commitdata.h", + "git.qrc", "gitclient.cpp", "gitclient.h", "gitconstants.h", @@ -60,10 +49,14 @@ QtcPlugin { "gitsubmiteditor.h", "gitsubmiteditorwidget.cpp", "gitsubmiteditorwidget.h", + "gitsubmitpanel.ui", "gitutils.cpp", "gitutils.h", "gitversioncontrol.cpp", "gitversioncontrol.h", + "mergetool.cpp", + "mergetool.h", + "remoteadditiondialog.ui", "remotedialog.cpp", "remotedialog.h", "remotedialog.ui", @@ -75,29 +68,30 @@ QtcPlugin { "settingspage.h", "settingspage.ui", "stashdialog.cpp", - "stashdialog.h" + "stashdialog.h", + "stashdialog.ui", ] Group { prefix: "gitorious/" files: [ - "gitorioushostwidget.ui", - "gitoriousprojectwidget.ui", - "gitoriousrepositorywizardpage.ui", "gitorious.cpp", "gitorious.h", "gitoriousclonewizard.cpp", "gitoriousclonewizard.h", "gitorioushostwidget.cpp", "gitorioushostwidget.h", + "gitorioushostwidget.ui", "gitorioushostwizardpage.cpp", "gitorioushostwizardpage.h", "gitoriousprojectwidget.cpp", "gitoriousprojectwidget.h", + "gitoriousprojectwidget.ui", "gitoriousprojectwizardpage.cpp", "gitoriousprojectwizardpage.h", "gitoriousrepositorywizardpage.cpp", - "gitoriousrepositorywizardpage.h" + "gitoriousrepositorywizardpage.h", + "gitoriousrepositorywizardpage.ui", ] } @@ -113,8 +107,7 @@ QtcPlugin { "gerritparameters.cpp", "gerritparameters.h", "gerritplugin.cpp", - "gerritplugin.h" + "gerritplugin.h", ] } } - diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index f70b3438c2..4bdca7a125 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -35,6 +35,7 @@ #include "gitplugin.h" #include "gitsubmiteditor.h" #include "gitversioncontrol.h" +#include "mergetool.h" #include <vcsbase/submitfilemodel.h> @@ -51,6 +52,7 @@ #include <coreplugin/variablemanager.h> #include <texteditor/itexteditor.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/qtcprocess.h> #include <utils/synchronousprocess.h> @@ -571,6 +573,13 @@ void GitClient::diffBranch(const QString &workingDirectory, executeGit(workingDirectory, cmdArgs, editor); } +void GitClient::merge(const QString &workingDirectory, const QStringList &unmergedFileNames) +{ + MergeTool *mergeTool = new MergeTool(this); + if (!mergeTool->start(workingDirectory, unmergedFileNames)) + delete mergeTool; +} + void GitClient::status(const QString &workingDirectory) { // @TODO: Use "--no-color" once it is supported @@ -1097,64 +1106,51 @@ static inline QString msgCannotDetermineBranch(const QString &workingDirectory, return GitClient::tr("Cannot retrieve branch of \"%1\": %2").arg(QDir::toNativeSeparators(workingDirectory), why); } -// Retrieve head revision/branch -bool GitClient::synchronousTopRevision(const QString &workingDirectory, QString *revision, - QString *branch, QString *errorMessageIn) +// Retrieve head branch +QString GitClient::synchronousBranch(const QString &workingDirectory) +{ + QByteArray outputTextData; + QStringList arguments; + arguments << QLatin1String("symbolic-ref") << QLatin1String("HEAD"); + // if HEAD is detached, the command is expected to fail. + if (!fullySynchronousGit(workingDirectory, arguments, &outputTextData)) + return QString(); + QString branch = commandOutputFromLocal8Bit(outputTextData); + branch.remove(QLatin1Char('\n')); + + // Must strip the "refs/heads/" prefix manually since the --short switch + // of git symbolic-ref only got introduced with git 1.7.10, which is not + // available for all popular Linux distributions yet. + const QString refsHeadsPrefix = QLatin1String("refs/heads/"); + if (branch.startsWith(refsHeadsPrefix)) + branch.remove(0, refsHeadsPrefix.count()); + + return branch; +} + +// Retrieve head revision +QString GitClient::synchronousTopRevision(const QString &workingDirectory, QString *errorMessageIn) { QByteArray outputTextData; QByteArray errorText; QStringList arguments; QString errorMessage; - do { - // get revision - if (revision) { - revision->clear(); - arguments << QLatin1String("log") << QLatin1String(noColorOption) - << QLatin1String("--max-count=1") << QLatin1String("--pretty=format:%H"); - if (!fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText)) { - errorMessage = tr("Cannot retrieve top revision of \"%1\": %2").arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText)); - break; - } - *revision = commandOutputFromLocal8Bit(outputTextData); - revision->remove(QLatin1Char('\n')); - } // revision desired - // get branch - if (branch) { - branch->clear(); - arguments.clear(); - arguments << QLatin1String("branch") << QLatin1String(noColorOption); - if (!fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText)) { - errorMessage = msgCannotDetermineBranch(workingDirectory, commandOutputFromLocal8Bit(errorText)); - break; - } - /* parse output for current branch: \code -* master - branch2 -\endcode */ - const QString branchPrefix = QLatin1String("* "); - foreach(const QString &line, commandOutputLinesFromLocal8Bit(outputTextData)) { - if (line.startsWith(branchPrefix)) { - *branch = line; - branch->remove(0, branchPrefix.size()); - break; - } - } - if (branch->isEmpty()) { - errorMessage = msgCannotDetermineBranch(workingDirectory, - QString::fromLatin1("Internal error: Failed to parse output: %1").arg(commandOutputFromLocal8Bit(outputTextData))); - break; - } - } // branch - } while (false); - const bool failed = (revision && revision->isEmpty()) || (branch && branch->isEmpty()); - if (failed && !errorMessage.isEmpty()) { - if (errorMessageIn) { + // get revision + arguments << QLatin1String("rev-parse") << QLatin1String("HEAD"); + if (!fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText)) { + errorMessage = tr("Cannot retrieve top revision of \"%1\": %2") + .arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText)); + return QString(); + } + QString revision = commandOutputFromLocal8Bit(outputTextData); + revision.remove(QLatin1Char('\n')); + if (revision.isEmpty() && !errorMessage.isEmpty()) { + if (errorMessageIn) *errorMessageIn = errorMessage; - } else { + else outputWindow()->appendError(errorMessage); - } } - return !failed; + return revision; } // Format an entry in a one-liner for selection list using git log. @@ -1439,18 +1435,17 @@ VcsBase::Command *GitClient::executeGit(const QString &workingDirectory, QProcessEnvironment GitClient::processEnvironment() const { - QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); QString gitPath = settings()->stringValue(GitSettings::pathKey); if (!gitPath.isEmpty()) { - gitPath += Utils::SynchronousProcess::pathSeparator(); + gitPath += Utils::HostOsInfo::pathListSeparator(); gitPath += environment.value(QLatin1String("PATH")); environment.insert(QLatin1String("PATH"), gitPath); } -#ifdef Q_OS_WIN - if (settings()->boolValue(GitSettings::winSetHomeEnvironmentKey)) + if (Utils::HostOsInfo::isWindowsHost() + && settings()->boolValue(GitSettings::winSetHomeEnvironmentKey)) { environment.insert(QLatin1String("HOME"), QDir::toNativeSeparators(QDir::homePath())); -#endif // Q_OS_WIN + } // Set up SSH and C locale (required by git using perl). VcsBase::VcsBasePlugin::setProcessEnvironment(&environment, false); return environment; @@ -1657,15 +1652,16 @@ bool GitClient::tryLauchingGitK(const QProcessEnvironment &env, const QString &gitBinDirectory, bool silent) { -#ifdef Q_OS_WIN - // Launch 'wish' shell from git binary directory with the gitk located there - const QString binary = gitBinDirectory + QLatin1String("/wish"); - QStringList arguments(gitBinDirectory + QLatin1String("/gitk")); -#else - // Simple: Run gitk from binary path - const QString binary = gitBinDirectory + QLatin1String("/gitk"); + QString binary; QStringList arguments; -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + // Launch 'wish' shell from git binary directory with the gitk located there + binary = gitBinDirectory + QLatin1String("/wish"); + arguments << (gitBinDirectory + QLatin1String("/gitk")); + } else { + // Simple: Run gitk from binary path + binary = gitBinDirectory + QLatin1String("/gitk"); + } VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance(); const QString gitkOpts = settings()->stringValue(GitSettings::gitkOptionsKey); if (!gitkOpts.isEmpty()) @@ -1762,13 +1758,13 @@ bool GitClient::getCommitData(const QString &workingDirectory, } // Filter out untracked files that are not part of the project - QStringList untrackedFiles = commitData->filterFiles(CommitData::UntrackedFile); + QStringList untrackedFiles = commitData->filterFiles(UntrackedFile); VcsBase::VcsBaseSubmitEditor::filterUntrackedFilesOfProject(repoDirectory, &untrackedFiles); QList<CommitData::StateFilePair> filteredFiles; QList<CommitData::StateFilePair>::const_iterator it = commitData->files.constBegin(); for ( ; it != commitData->files.constEnd(); ++it) { - if (it->first == CommitData::UntrackedFile && !untrackedFiles.contains(it->second)) + if (it->first == UntrackedFile && !untrackedFiles.contains(it->second)) continue; filteredFiles.append(*it); } @@ -1848,47 +1844,41 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory, int commitCount = 0; for (int i = 0; i < model->rowCount(); ++i) { - const CommitData::FileState state = static_cast<CommitData::FileState>(model->extraData(i).toInt()); + const FileStates state = static_cast<FileStates>(model->extraData(i).toInt()); QString file = model->file(i); const bool checked = model->checked(i); if (checked) ++commitCount; - if (state == CommitData::UntrackedFile && checked) + if (state == UntrackedFile && checked) filesToAdd.append(file); - if (state == CommitData::ModifiedStagedFile && !checked) { - filesToReset.append(file); - } else if (state == CommitData::AddedStagedFile && !checked) { - filesToReset.append(file); - } else if (state == CommitData::DeletedStagedFile && !checked) { - filesToReset.append(file); - } else if (state == CommitData::RenamedStagedFile && !checked) { - const int pos = file.indexOf(QLatin1String(" -> ")); - const QString newFile = file.mid(pos + 4); - filesToReset.append(newFile); - } else if (state == CommitData::CopiedStagedFile && !checked) { - const QString newFile = file.mid(file.indexOf(renameSeparator) + renameSeparator.count()); - filesToReset.append(newFile); - } else if (state == CommitData::UpdatedStagedFile && !checked) { - QTC_ASSERT(false, continue); // There should not be updated files when commiting! + if ((state & StagedFile) && !checked) { + if (state & (AddedFile | DeletedFile)) { + filesToReset.append(file); + } else if (state & (RenamedFile | CopiedFile)) { + const QString newFile = file.mid(file.indexOf(renameSeparator) + renameSeparator.count()); + filesToReset.append(newFile); + } + } else if (state & UnmergedFile && checked) { + QTC_ASSERT(false, continue); // There should not be unmerged files when commiting! } - if (state == CommitData::ModifiedFile && checked) { + if (state == ModifiedFile && checked) { filesToReset.removeAll(file); filesToAdd.append(file); - } else if (state == CommitData::AddedFile && checked) { + } else if (state == AddedFile && checked) { QTC_ASSERT(false, continue); // these should be untracked! - } else if (state == CommitData::DeletedFile && checked) { + } else if (state == DeletedFile && checked) { filesToReset.removeAll(file); filesToRemove.append(file); - } else if (state == CommitData::RenamedFile && checked) { + } else if (state == RenamedFile && checked) { QTC_ASSERT(false, continue); // git mv directly stages. - } else if (state == CommitData::CopiedFile && checked) { + } else if (state == CopiedFile && checked) { QTC_ASSERT(false, continue); // only is noticed after adding a new file to the index - } else if (state == CommitData::UpdatedFile && checked) { - QTC_ASSERT(false, continue); // There should not be updated files when commiting! + } else if (state == UnmergedFile && checked) { + QTC_ASSERT(false, continue); // There should not be unmerged files when commiting! } } @@ -1977,8 +1967,8 @@ GitClient::RevertResult GitClient::revertI(QStringList files, } // From the status output, determine all modified [un]staged files. - const QStringList allStagedFiles = data.filterFiles(CommitData::ModifiedStagedFile); - const QStringList allUnstagedFiles = data.filterFiles(CommitData::ModifiedFile); + const QStringList allStagedFiles = data.filterFiles(StagedFile | ModifiedFile); + const QStringList allUnstagedFiles = data.filterFiles(ModifiedFile); // Unless a directory was passed, filter all modified files for the // argument file list. QStringList stagedFiles = allStagedFiles; @@ -2046,43 +2036,59 @@ bool GitClient::synchronousFetch(const QString &workingDirectory, const QString return resp.result == Utils::SynchronousProcessResponse::Finished; } -bool GitClient::synchronousPull(const QString &workingDirectory) +bool GitClient::synchronousPullOrRebase(const QString &workingDirectory, const QStringList &arguments, bool rebase) { - return synchronousPull(workingDirectory, settings()->boolValue(GitSettings::pullRebaseKey)); -} - -bool GitClient::synchronousPull(const QString &workingDirectory, bool rebase) -{ - QStringList arguments(QLatin1String("pull")); - if (rebase) - arguments << QLatin1String("--rebase"); // Disable UNIX terminals to suppress SSH prompting. const unsigned flags = VcsBase::VcsBasePlugin::SshPasswordPrompt|VcsBase::VcsBasePlugin::ShowStdOutInLogWindow; const Utils::SynchronousProcessResponse resp = synchronousGit(workingDirectory, arguments, flags); // Notify about changed files or abort the rebase. const bool ok = resp.result == Utils::SynchronousProcessResponse::Finished; - if (ok) { + if (ok) GitPlugin::instance()->gitVersionControl()->emitRepositoryChanged(workingDirectory); - } else { - if (rebase) - syncAbortPullRebase(workingDirectory); - } + else + handleMergeConflicts(workingDirectory, rebase); return ok; } -void GitClient::syncAbortPullRebase(const QString &workingDir) +bool GitClient::synchronousPull(const QString &workingDirectory, bool rebase) { - // Abort rebase to clean if something goes wrong - VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance(); - outwin->appendError(tr("The command 'git pull --rebase' failed, aborting rebase.")); - QStringList arguments; - arguments << QLatin1String("rebase") << QLatin1String("--abort"); - QByteArray stdOut; - QByteArray stdErr; - const bool rc = fullySynchronousGit(workingDir, arguments, &stdOut, &stdErr, true); - outwin->append(commandOutputFromLocal8Bit(stdOut)); - if (!rc) - outwin->appendError(commandOutputFromLocal8Bit(stdErr)); + QStringList arguments(QLatin1String("pull")); + if (rebase) + arguments << QLatin1String("--rebase"); + return synchronousPullOrRebase(workingDirectory, arguments, rebase); +} + +bool GitClient::synchronousRebaseContinue(const QString &workingDirectory) +{ + QStringList arguments(QLatin1String("rebase")); + arguments << QLatin1String("--continue"); + return synchronousPullOrRebase(workingDirectory, arguments, true); +} + +void GitClient::handleMergeConflicts(const QString &workingDir, bool rebase) +{ + QMessageBox mergeOrAbort(QMessageBox::Question, tr("Conflicts detected"), + tr("Conflicts detected"), QMessageBox::Ignore | QMessageBox::Abort); + mergeOrAbort.addButton(tr("Run Merge Tool"), QMessageBox::ActionRole); + switch (mergeOrAbort.exec()) { + case QMessageBox::Abort: { + // Abort merge/rebase to clean if something goes wrong + VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance(); + QStringList arguments; + arguments << QLatin1String(rebase ? "rebase" : "merge") << QLatin1String("--abort"); + QByteArray stdOut; + QByteArray stdErr; + const bool rc = fullySynchronousGit(workingDir, arguments, &stdOut, &stdErr, true); + outwin->append(commandOutputFromLocal8Bit(stdOut)); + if (!rc) + outwin->appendError(commandOutputFromLocal8Bit(stdErr)); + break; + } + case QMessageBox::Ignore: + break; + default: // Merge + merge(workingDir); + } } // Subversion: git svn diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index d1ad524949..21179d8dd4 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -92,6 +92,7 @@ public: void diffBranch(const QString &workingDirectory, const QStringList &diffArgs, const QString &branchName); + void merge(const QString &workingDirectory, const QStringList &unmergedFileNames = QStringList()); void status(const QString &workingDirectory); void graphLog(const QString &workingDirectory) { graphLog(workingDirectory, QString()); } @@ -160,14 +161,14 @@ public: QString synchronousShortDescription(const QString &workingDirectory, const QString &revision); QString synchronousShortDescription(const QString &workingDirectory, const QString &revision, const QString &format); - bool synchronousTopRevision(const QString &workingDirectory, QString *revision = 0, - QString *branch = 0, QString *errorMessage = 0); + QString synchronousBranch(const QString &workingDirectory); + QString synchronousTopRevision(const QString &workingDirectory, QString *errorMessage = 0); bool cloneRepository(const QString &directory, const QByteArray &url); QString vcsGetRepositoryURL(const QString &directory); bool synchronousFetch(const QString &workingDirectory, const QString &remote); - bool synchronousPull(const QString &workingDirectory); bool synchronousPull(const QString &workingDirectory, bool rebase); + bool synchronousRebaseContinue(const QString &workingDirectory); bool synchronousPush(const QString &workingDirectory, const QString &remote = QString()); // git svn support (asynchronous). @@ -266,7 +267,7 @@ private: bool fullySynchronousGit(const QString &workingDirectory, const QStringList &arguments, QByteArray* outputText, - QByteArray* errorText, + QByteArray* errorText = 0, bool logCommandToWindow = true) const; // Synchronous git execution using Utils::SynchronousProcess, with @@ -284,7 +285,8 @@ private: QString *errorMessage, bool revertStaging); void connectRepositoryChanged(const QString & repository, VcsBase::Command *cmd); - void syncAbortPullRebase(const QString &workingDir); + bool synchronousPullOrRebase(const QString &workingDirectory, const QStringList &arguments, bool rebase); + void handleMergeConflicts(const QString &workingDir, bool rebase); bool tryLauchingGitK(const QProcessEnvironment &env, const QString &workingDirectory, const QString &gitBinDirectory, diff --git a/src/plugins/git/gitorious/gitoriousclonewizard.cpp b/src/plugins/git/gitorious/gitoriousclonewizard.cpp index 6552e1e17c..eeefb55ce2 100644 --- a/src/plugins/git/gitorious/gitoriousclonewizard.cpp +++ b/src/plugins/git/gitorious/gitoriousclonewizard.cpp @@ -31,9 +31,9 @@ #include "gitorioushostwizardpage.h" #include "gitoriousprojectwizardpage.h" #include "gitoriousrepositorywizardpage.h" -#include "clonewizardpage.h" -#include <git/gitplugin.h> +#include "../clonewizardpage.h" +#include "../gitplugin.h" #include <coreplugin/iversioncontrol.h> #include <vcsbase/checkoutjobs.h> diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 2d1f0ded42..6a0d7d4638 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -39,12 +39,13 @@ #include "branchdialog.h" #include "remotedialog.h" #include "clonewizard.h" -#include "gitoriousclonewizard.h" +#include "gitorious/gitoriousclonewizard.h" #include "stashdialog.h" #include "settingspage.h" #include "resetdialog.h" +#include "mergetool.h" -#include <gerritplugin.h> +#include "gerrit/gerritplugin.h" #include <coreplugin/icore.h> #include <coreplugin/coreconstants.h> @@ -519,6 +520,10 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) tr("Amend Last Commit..."), Core::Id("Git.AmendCommit"), globalcontext, true, SLOT(startAmendCommit())); + createRepositoryAction(gitContainer, + tr("Merge Tool"), Core::Id("Git.MergeTool"), + globalcontext, true, SLOT(startMergeTool())); + // Subversion in a submenu. gitContainer->addSeparator(globalcontext); @@ -565,6 +570,11 @@ void GitPlugin::submitEditorDiff(const QStringList &unstaged, const QStringList m_gitClient->diff(m_submitRepository, QStringList(), unstaged, staged); } +void GitPlugin::submitEditorMerge(const QStringList &unmerged) +{ + m_gitClient->merge(m_submitRepository, unmerged); +} + void GitPlugin::diffCurrentFile() { const VcsBase::VcsBasePluginState state = currentState(); @@ -708,6 +718,7 @@ Core::IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const Commit if (amend) // Allow for just correcting the message submitEditor->setEmptyFileListEnabled(true); connect(submitEditor, SIGNAL(diff(QStringList,QStringList)), this, SLOT(submitEditorDiff(QStringList,QStringList))); + connect(submitEditor, SIGNAL(merge(QStringList)), this, SLOT(submitEditorMerge(QStringList))); return editor; } @@ -804,14 +815,21 @@ void GitPlugin::push() m_gitClient->synchronousPush(state.topLevel()); } +void GitPlugin::startMergeTool() +{ + const VcsBase::VcsBasePluginState state = currentState(); + QTC_ASSERT(state.hasTopLevel(), return); + m_gitClient->merge(state.topLevel()); +} + // Retrieve member function of git client stored as user data of action static inline GitClientMemberFunc memberFunctionFromAction(const QObject *o) { if (o) { if (const QAction *action = qobject_cast<const QAction *>(o)) { const QVariant v = action->data(); - if (qVariantCanConvert<GitClientMemberFunc>(v)) - return qVariantValue<GitClientMemberFunc>(v); + if (v.canConvert<GitClientMemberFunc>()) + return qvariant_cast<GitClientMemberFunc>(v); } } return 0; @@ -1067,4 +1085,55 @@ GitClient *GitPlugin::gitClient() const return m_gitClient; } +#ifdef WITH_TESTS +#include <QTest> +Q_DECLARE_METATYPE(FileStates) +void GitPlugin::testStatusParsing_data() +{ + QTest::addColumn<FileStates>("first"); + QTest::addColumn<FileStates>("second"); + + QTest::newRow(" M") << FileStates(ModifiedFile) << FileStates(UnknownFileState); + QTest::newRow(" D") << FileStates(DeletedFile) << FileStates(UnknownFileState); + QTest::newRow("M ") << (ModifiedFile | StagedFile) << FileStates(UnknownFileState); + QTest::newRow("MM") << (ModifiedFile | StagedFile) << FileStates(ModifiedFile); + QTest::newRow("MD") << (ModifiedFile | StagedFile) << FileStates(DeletedFile); + QTest::newRow("A ") << (AddedFile | StagedFile) << FileStates(UnknownFileState); + QTest::newRow("AM") << (AddedFile | StagedFile) << FileStates(ModifiedFile); + QTest::newRow("AD") << (AddedFile | StagedFile) << FileStates(DeletedFile); + QTest::newRow("D ") << (DeletedFile | StagedFile) << FileStates(UnknownFileState); + QTest::newRow("DM") << (DeletedFile | StagedFile) << FileStates(ModifiedFile); + QTest::newRow("R ") << (RenamedFile | StagedFile) << FileStates(UnknownFileState); + QTest::newRow("RM") << (RenamedFile | StagedFile) << FileStates(ModifiedFile); + QTest::newRow("RD") << (RenamedFile | StagedFile) << FileStates(DeletedFile); + QTest::newRow("C ") << (CopiedFile | StagedFile) << FileStates(UnknownFileState); + QTest::newRow("CM") << (CopiedFile | StagedFile) << FileStates(ModifiedFile); + QTest::newRow("CD") << (CopiedFile | StagedFile) << FileStates(DeletedFile); + + // Merges + QTest::newRow("DD") << (DeletedFile | UnmergedFile | UnmergedUs | UnmergedThem) << FileStates(UnknownFileState); + QTest::newRow("AA") << (AddedFile | UnmergedFile | UnmergedUs | UnmergedThem) << FileStates(UnknownFileState); + QTest::newRow("UU") << (ModifiedFile | UnmergedFile | UnmergedUs | UnmergedThem) << FileStates(UnknownFileState); + QTest::newRow("AU") << (AddedFile | UnmergedFile | UnmergedUs) << FileStates(UnknownFileState); + QTest::newRow("UD") << (DeletedFile | UnmergedFile | UnmergedThem) << FileStates(UnknownFileState); + QTest::newRow("UA") << (AddedFile | UnmergedFile | UnmergedThem) << FileStates(UnknownFileState); + QTest::newRow("DU") << (DeletedFile | UnmergedFile | UnmergedUs) << FileStates(UnknownFileState); +} + +void GitPlugin::testStatusParsing() +{ + CommitData data; + QFETCH(FileStates, first); + QFETCH(FileStates, second); + QString output = QLatin1String("## master...origin/master [ahead 1]\n"); + output += QString::fromLatin1(QTest::currentDataTag()) + QLatin1String(" main.cpp\n"); + data.parseFilesFromStatus(output); + QCOMPARE(data.files.at(0).first, first); + if (second == UnknownFileState) + QCOMPARE(data.files.size(), 1); + else + QCOMPARE(data.files.at(1).first, second); +} +#endif + Q_EXPORT_PLUGIN(GitPlugin) diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 3d9b9f4659..c3709fa94b 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -105,6 +105,7 @@ private slots: void diffCurrentProject(); void diffRepository(); void submitEditorDiff(const QStringList &unstaged, const QStringList &staged); + void submitEditorMerge(const QStringList &unmerged); void submitCurrentLog(); void logFile(); void blameFile(); @@ -131,7 +132,12 @@ private slots: void fetch(); void pull(); void push(); + void startMergeTool(); +#ifdef WITH_TESTS + void testStatusParsing_data(); + void testStatusParsing(); +#endif protected: virtual void updateActions(VcsBase::VcsBasePlugin::ActionState); virtual bool submitEditorAboutToClose(VcsBase::VcsBaseSubmitEditor *submitEditor); diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp index 22a34c8a57..374989a634 100644 --- a/src/plugins/git/gitsettings.cpp +++ b/src/plugins/git/gitsettings.cpp @@ -29,6 +29,7 @@ #include "gitsettings.h" +#include <utils/hostosinfo.h> #include <QCoreApplication> namespace Git { @@ -50,11 +51,7 @@ GitSettings::GitSettings() setSettingsGroup(QLatin1String("Git")); declareKey(binaryPathKey, QLatin1String("git")); -#ifdef Q_OS_WIN - declareKey(timeoutKey, 60); -#else - declareKey(timeoutKey, 30); -#endif + declareKey(timeoutKey, Utils::HostOsInfo::isWindowsHost() ? 60 : 30); declareKey(pullRebaseKey, false); declareKey(omitAnnotationDateKey, false); declareKey(ignoreSpaceChangesInDiffKey, true); diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp index 7b56aa7fdd..c69a3425af 100644 --- a/src/plugins/git/gitsubmiteditor.cpp +++ b/src/plugins/git/gitsubmiteditor.cpp @@ -70,9 +70,9 @@ void GitSubmitEditor::setCommitData(const CommitData &d) if (!d.files.isEmpty()) { for (QList<CommitData::StateFilePair>::const_iterator it = d.files.constBegin(); it != d.files.constEnd(); ++it) { - const CommitData::FileState state = it->first; + const FileStates state = it->first; const QString file = it->second; - m_model->addFile(file, CommitData::stateDisplayName(state), state & CommitData::StagedFile, + m_model->addFile(file, CommitData::stateDisplayName(state), state & StagedFile, QVariant(static_cast<int>(state))); } } @@ -81,7 +81,8 @@ void GitSubmitEditor::setCommitData(const CommitData &d) void GitSubmitEditor::slotDiffSelected(const QStringList &files) { - // Sort it apart into staged/unstaged files + // Sort it apart into unmerged/staged/unstaged files + QStringList unmergedFiles; QStringList unstagedFiles; QStringList stagedFiles; const int fileColumn = fileNameColumn(); @@ -89,15 +90,19 @@ void GitSubmitEditor::slotDiffSelected(const QStringList &files) for (int r = 0; r < rowCount; r++) { const QString fileName = m_model->item(r, fileColumn)->text(); if (files.contains(fileName)) { - const CommitData::FileState state = static_cast<CommitData::FileState>(m_model->extraData(r).toInt()); - if (state & CommitData::StagedFile) + const FileStates state = static_cast<FileStates>(m_model->extraData(r).toInt()); + if (state & UnmergedFile) + unmergedFiles.push_back(fileName); + else if (state & StagedFile) stagedFiles.push_back(fileName); - else if (state != CommitData::UntrackedFile) + else if (state != UntrackedFile) unstagedFiles.push_back(fileName); } } if (!unstagedFiles.empty() || !stagedFiles.empty()) emit diff(unstagedFiles, stagedFiles); + if (!unmergedFiles.empty()) + emit merge(unmergedFiles); } GitSubmitEditorPanelData GitSubmitEditor::panelData() const diff --git a/src/plugins/git/gitsubmiteditor.h b/src/plugins/git/gitsubmiteditor.h index 41454ac37e..2cacaecc2e 100644 --- a/src/plugins/git/gitsubmiteditor.h +++ b/src/plugins/git/gitsubmiteditor.h @@ -56,6 +56,7 @@ public: signals: void diff(const QStringList &unstagedFiles, const QStringList &stagedFiles); + void merge(const QStringList &unmergedFiles); protected: QByteArray fileContents() const; diff --git a/src/plugins/git/gitutils.cpp b/src/plugins/git/gitutils.cpp index 792de00fc9..7731904afd 100644 --- a/src/plugins/git/gitutils.cpp +++ b/src/plugins/git/gitutils.cpp @@ -87,7 +87,7 @@ bool inputText(QWidget *parent, const QString &title, const QString &prompt, QSt dialog.setLabelText(prompt); dialog.setTextValue(*s); // Nasty hack: - if (QLineEdit *le = qFindChild<QLineEdit*>(&dialog)) + if (QLineEdit *le = dialog.findChild<QLineEdit*>()) le->setMinimumWidth(500); if (dialog.exec() != QDialog::Accepted) return false; diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp index 363df7c945..4e1b8a7eb0 100644 --- a/src/plugins/git/gitversioncontrol.cpp +++ b/src/plugins/git/gitversioncontrol.cpp @@ -56,7 +56,7 @@ QString GitVersionControl::displayName() const Core::Id GitVersionControl::id() const { - return VcsBase::Constants::VCS_ID_GIT; + return Core::Id(VcsBase::Constants::VCS_ID_GIT); } bool GitVersionControl::isConfigured() const @@ -140,7 +140,12 @@ QString GitVersionControl::vcsGetRepositoryURL(const QString &directory) return m_client->vcsGetRepositoryURL(directory); } -/* Snapshots are implement using stashes, relying on stash messages for +QString GitVersionControl::vcsTopic(const QString &directory) +{ + return m_client->synchronousBranch(directory); +} + +/* Snapshots are implemented using stashes, relying on stash messages for * naming as the actual stash names (stash{n}) are rotated as one adds stashes. * Note that the snapshot interface does not care whether we have an unmodified * repository state, in which case git refuses to stash. @@ -161,10 +166,10 @@ QString GitVersionControl::vcsCreateSnapshot(const QString &topLevel) return stashMessage; if (repositoryUnchanged) { // For unchanged repository state: return identifier + top revision - QString topRevision; - QString branch; - if (!m_client->synchronousTopRevision(topLevel, &topRevision, &branch)) + QString topRevision = m_client->synchronousTopRevision(topLevel); + if (topRevision.isEmpty()) return QString(); + QString branch = m_client->synchronousBranch(topLevel); const QChar colon = QLatin1Char(':'); QString id = QLatin1String(stashRevisionIdC); id += colon; @@ -201,9 +206,13 @@ bool GitVersionControl::vcsRestoreSnapshot(const QString &topLevel, const QStrin break; const QString branch = tokens.at(1); const QString revision = tokens.at(2); - success = m_client->synchronousReset(topLevel) - && m_client->synchronousCheckoutBranch(topLevel, branch) - && m_client->synchronousCheckoutFiles(topLevel, QStringList(), revision); + success = m_client->synchronousReset(topLevel); + if (success && !branch.isEmpty()) { + success = m_client->synchronousCheckoutBranch(topLevel, branch) && + m_client->synchronousCheckoutFiles(topLevel, QStringList(), revision); + } else { + success = m_client->synchronousCheckoutBranch(topLevel, revision); + } } else { // Restore stash if it can be resolved. QString stashName; diff --git a/src/plugins/git/gitversioncontrol.h b/src/plugins/git/gitversioncontrol.h index 20d2b2f87a..7f502f897c 100644 --- a/src/plugins/git/gitversioncontrol.h +++ b/src/plugins/git/gitversioncontrol.h @@ -64,6 +64,7 @@ public: bool vcsRemoveSnapshot(const QString &topLevel, const QString &name); bool vcsAnnotate(const QString &file, int line); + QString vcsTopic(const QString &directory); void emitFilesChanged(const QStringList &); void emitRepositoryChanged(const QString &); diff --git a/src/plugins/git/mergetool.cpp b/src/plugins/git/mergetool.cpp new file mode 100644 index 0000000000..30401cc0ee --- /dev/null +++ b/src/plugins/git/mergetool.cpp @@ -0,0 +1,280 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "gitclient.h" +#include "gitplugin.h" +#include "mergetool.h" + +#include <vcsbase/vcsbaseoutputwindow.h> + +#include <QFile> +#include <QMessageBox> +#include <QProcess> +#include <QPushButton> + +namespace Git { +namespace Internal { + +class MergeToolProcess : public QProcess +{ +public: + MergeToolProcess(QObject *parent = 0) : + QProcess(parent), + m_window(VcsBase::VcsBaseOutputWindow::instance()) + { + } + +protected: + qint64 readData(char *data, qint64 maxlen) + { + qint64 res = QProcess::readData(data, maxlen); + if (res > 0) + m_window->append(QString::fromLocal8Bit(data, res)); + return res; + } + + virtual qint64 writeData(const char *data, qint64 len) + { + if (len > 0) + m_window->append(QString::fromLocal8Bit(data, len)); + return QProcess::writeData(data, len); + } + +private: + VcsBase::VcsBaseOutputWindow *m_window; +}; + +MergeTool::MergeTool(QObject *parent) : + QObject(parent), + m_process(0) +{ +} + +MergeTool::~MergeTool() +{ + delete m_process; +} + +bool MergeTool::start(const QString &workingDirectory, const QStringList &files) +{ + QStringList arguments; + arguments << QLatin1String("mergetool") << QLatin1String("-y"); + GitClient *client = GitPlugin::instance()->gitClient(); + if (!files.isEmpty()) { + if (client->gitVersion() < 0x010708) { + QMessageBox::warning(0, tr("Error"), tr("Files input for mergetool requires git >= 1.7.8")); + return false; + } + arguments << files; + } + m_process = new MergeToolProcess(this); + m_process->setWorkingDirectory(workingDirectory); + VcsBase::VcsBaseOutputWindow::instance()->appendCommand(workingDirectory, QLatin1String("git"), arguments); + m_process->start(QLatin1String("git"), arguments); + if (m_process->waitForStarted()) { + connect(m_process, SIGNAL(finished(int)), this, SLOT(done())); + connect(m_process, SIGNAL(readyRead()), this, SLOT(readData())); + } + else { + delete m_process; + m_process = 0; + return false; + } + return true; +} + +MergeTool::FileState MergeTool::waitAndReadStatus(QString &extraInfo) +{ + QByteArray state; + if (m_process->canReadLine() || (m_process->waitForReadyRead(500) && m_process->canReadLine())) { + state = m_process->readLine().trimmed(); + // " {local}: modified file" + // " {remote}: deleted" + if (!state.isEmpty()) { + state = state.mid(state.indexOf(':') + 2); + if (state == "deleted") + return DeletedState; + if (state.startsWith("modified")) + return ModifiedState; + if (state.startsWith("created")) + return CreatedState; + QByteArray submodulePrefix("submodule commit "); + // " {local}: submodule commit <hash>" + if (state.startsWith(submodulePrefix)) { + extraInfo = QString::fromLocal8Bit(state.mid(submodulePrefix.size())); + return SubmoduleState; + } + // " {local}: a symbolic link -> 'foo.cpp'" + QByteArray symlinkPrefix("a symbolic link -> '"); + if (state.startsWith(symlinkPrefix)) { + extraInfo = QString::fromLocal8Bit(state.mid(symlinkPrefix.size())); + extraInfo.chop(1); // remove last quote + return SymbolicLinkState; + } + } + } + return UnknownState; +} + +static MergeTool::MergeType mergeType(const QByteArray &type) +{ + if (type == "Normal") + return MergeTool::NormalMerge; + if (type == "Deleted") + return MergeTool::DeletedMerge; + if (type == "Submodule") + return MergeTool::SubmoduleMerge; + else + return MergeTool::SymbolicLinkMerge; +} + +QString MergeTool::mergeTypeName() +{ + switch (m_mergeType) { + case NormalMerge: return tr("Normal"); + case SubmoduleMerge: return tr("Submodule"); + case DeletedMerge: return tr("Deleted"); + case SymbolicLinkMerge: return tr("Symbolic link"); + } + return QString(); +} + +QString MergeTool::stateName(MergeTool::FileState state, const QString &extraInfo) +{ + switch (state) { + case ModifiedState: return tr("Modified"); + case CreatedState: return tr("Created"); + case DeletedState: return tr("Deleted"); + case SubmoduleState: return tr("Submodule commit %1").arg(extraInfo); + case SymbolicLinkState: return tr("Symbolic link -> %1").arg(extraInfo); + default: break; + } + return QString(); +} + +void MergeTool::chooseAction() +{ + m_merging = (m_mergeType == NormalMerge); + if (m_merging) + return; + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Merge Conflict")); + msgBox.setIcon(QMessageBox::Question); + msgBox.setStandardButtons(QMessageBox::Abort); + msgBox.setText(tr("%1 merge conflict for '%2'\nLocal: %3\nRemote: %4") + .arg(mergeTypeName()) + .arg(m_fileName) + .arg(stateName(m_localState, m_localInfo)) + .arg(stateName(m_remoteState, m_remoteInfo)) + ); + switch (m_mergeType) { + case SubmoduleMerge: + case SymbolicLinkMerge: + addButton(&msgBox, tr("&Local"), 'l'); + addButton(&msgBox, tr("&Remote"), 'r'); + break; + case DeletedMerge: + if (m_localState == CreatedState || m_remoteState == CreatedState) + addButton(&msgBox, tr("&Created"), 'c'); + else + addButton(&msgBox, tr("&Modified"), 'm'); + addButton(&msgBox, tr("&Deleted"), 'd'); + break; + default: + break; + } + + msgBox.exec(); + QByteArray ba; + QVariant key; + QAbstractButton *button = msgBox.clickedButton(); + if (button) + key = button->property("key"); + // either the message box was closed without clicking anything, or abort was clicked + if (!key.isValid()) + key = QVariant(QLatin1Char('a')); // abort + ba.append(key.toChar().toLatin1()); + ba.append('\n'); + m_process->write(ba); +} + +void MergeTool::addButton(QMessageBox *msgBox, const QString &text, char key) +{ + msgBox->addButton(text, QMessageBox::AcceptRole)->setProperty("key", key); +} + +void MergeTool::readData() +{ + while (m_process->bytesAvailable()) { + QByteArray line = m_process->canReadLine() ? m_process->readLine() : m_process->readAllStandardOutput(); + // {Normal|Deleted|Submodule|Symbolic link} merge conflict for 'foo.cpp' + int index = line.indexOf(" merge conflict for "); + if (index != -1) { + m_mergeType = mergeType(line.left(index)); + int quote = line.indexOf('\''); + m_fileName = QString::fromLocal8Bit(line.mid(quote + 1, line.lastIndexOf('\'') - quote - 1)); + m_localState = waitAndReadStatus(m_localInfo); + m_remoteState = waitAndReadStatus(m_remoteInfo); + chooseAction(); + } else if (m_merging && line.startsWith("Continue merging")) { + if (QMessageBox::question(0, tr("Continue Merging"), + tr("Continue merging other unresolved paths?"), + QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { + m_process->write("y\n"); + } else { + m_process->write("n\n"); + } + } + } +} + +void MergeTool::done() +{ + VcsBase::VcsBaseOutputWindow *outputWindow = VcsBase::VcsBaseOutputWindow::instance(); + int exitCode = m_process->exitCode(); + if (!exitCode) { + outputWindow->append(tr("Merge tool process finished successully")); + QString workingDirectory = m_process->workingDirectory(); + GitClient *client = GitPlugin::instance()->gitClient(); + QString gitDir = client->findGitDirForRepository(workingDirectory); + if (QFile::exists(gitDir + QLatin1String("/rebase-apply/rebasing"))) { + if (QMessageBox::question(0, tr("Continue Rebase"), + tr("Continue rebase?"), + QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { + client->synchronousRebaseContinue(workingDirectory); + } + } + } else { + outputWindow->append(tr("Merge tool process terminated with exit code %1").arg(exitCode)); + } + deleteLater(); +} + +} // namespace Internal +} // namespace Git diff --git a/src/plugins/remotelinux/deploymentsettingsassistant.h b/src/plugins/git/mergetool.h index 7bd12bff3d..d91876be5e 100644 --- a/src/plugins/remotelinux/deploymentsettingsassistant.h +++ b/src/plugins/git/mergetool.h @@ -26,44 +26,69 @@ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ -#ifndef DEPLOYMENTSETTINGSASSISTANT_H -#define DEPLOYMENTSETTINGSASSISTANT_H -#include "remotelinux_export.h" +#ifndef MERGETOOL_H +#define MERGETOOL_H #include <QObject> #include <QStringList> -namespace ProjectExplorer { class Project; } +QT_BEGIN_NAMESPACE +class QMessageBox; +QT_END_NAMESPACE -namespace RemoteLinux { -class DeployableFile; -class DeployableFilesPerProFile; -class DeploymentInfo; +namespace Git { +namespace Internal { -namespace Internal { class DeploymentSettingsAssistantInternal; } +class MergeToolProcess; -class REMOTELINUX_EXPORT DeploymentSettingsAssistant : public QObject +class MergeTool : public QObject { Q_OBJECT + enum FileState { + UnknownState, + ModifiedState, + CreatedState, + DeletedState, + SubmoduleState, + SymbolicLinkState + }; + public: - DeploymentSettingsAssistant(DeploymentInfo *deploymentInfo, ProjectExplorer::Project *parent); - ~DeploymentSettingsAssistant(); + explicit MergeTool(QObject *parent = 0); + ~MergeTool(); + bool start(const QString &workingDirectory, const QStringList &files = QStringList()); - bool addDeployableToProFile(const QString &qmakeScope, - const DeployableFilesPerProFile *proFileInfo, - const QString &variableName, const DeployableFile &deployable); + enum MergeType { + NormalMerge, + SubmoduleMerge, + DeletedMerge, + SymbolicLinkMerge + }; private slots: - void handleDeploymentInfoUpdated(); + void readData(); + void done(); private: - bool addLinesToProFile(const QString &qmakeScope, const DeployableFilesPerProFile *proFileInfo, const QStringList &lines); + FileState waitAndReadStatus(QString &extraInfo); + QString mergeTypeName(); + QString stateName(FileState state, const QString &extraInfo); + void chooseAction(); + void addButton(QMessageBox *msgBox, const QString &text, char key); - Internal::DeploymentSettingsAssistantInternal * const d; + MergeToolProcess *m_process; + MergeType m_mergeType; + QString m_fileName; + FileState m_localState; + QString m_localInfo; + FileState m_remoteState; + QString m_remoteInfo; + bool m_merging; }; -} // namespace RemoteLinux +} // namespace Internal +} // namespace Git -#endif // DEPLOYMENTSETTINGSASSISTANT_H +#endif // MERGETOOL_H diff --git a/src/plugins/git/remotemodel.cpp b/src/plugins/git/remotemodel.cpp index a260ac76ac..c2fd62094d 100644 --- a/src/plugins/git/remotemodel.cpp +++ b/src/plugins/git/remotemodel.cpp @@ -185,8 +185,9 @@ void RemoteModel::clear() { if (m_remotes.isEmpty()) return; + beginResetModel(); m_remotes.clear(); - reset(); + endResetModel(); } bool RemoteModel::refresh(const QString &workingDirectory, QString *errorMessage) @@ -199,6 +200,7 @@ bool RemoteModel::refresh(const QString &workingDirectory, QString *errorMessage return false; // Parse output m_workingDirectory = workingDirectory; + beginResetModel(); m_remotes.clear(); const QStringList lines = output.split(QLatin1Char('\n')); for (int r = 0; r < lines.count(); ++r) { @@ -206,7 +208,7 @@ bool RemoteModel::refresh(const QString &workingDirectory, QString *errorMessage if (newRemote.parse(lines.at(r))) m_remotes.push_back(newRemote); } - reset(); + endResetModel(); return true; } diff --git a/src/plugins/git/settingspage.cpp b/src/plugins/git/settingspage.cpp index 4835db76af..cc1fca2943 100644 --- a/src/plugins/git/settingspage.cpp +++ b/src/plugins/git/settingspage.cpp @@ -33,6 +33,7 @@ #include "gitclient.h" #include <vcsbase/vcsbaseconstants.h> +#include <utils/hostosinfo.h> #include <utils/pathchooser.h> #include <QCoreApplication> @@ -50,19 +51,19 @@ SettingsPageWidget::SettingsPageWidget(QWidget *parent) : QWidget(parent) { m_ui.setupUi(this); -#ifdef Q_OS_WIN - const QByteArray currentHome = qgetenv("HOME"); - const QString toolTip - = tr("Set the environment variable HOME to '%1'\n(%2).\n" - "This causes msysgit to look for the SSH-keys in that location\n" - "instead of its installation directory when run outside git bash."). - arg(QDir::homePath(), - currentHome.isEmpty() ? tr("not currently set") : - tr("currently set to '%1'").arg(QString::fromLocal8Bit(currentHome))); - m_ui.winHomeCheckBox->setToolTip(toolTip); -#else - m_ui.winHomeCheckBox->setVisible(false); -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + const QByteArray currentHome = qgetenv("HOME"); + const QString toolTip + = tr("Set the environment variable HOME to '%1'\n(%2).\n" + "This causes msysgit to look for the SSH-keys in that location\n" + "instead of its installation directory when run outside git bash."). + arg(QDir::homePath(), + currentHome.isEmpty() ? tr("not currently set") : + tr("currently set to '%1'").arg(QString::fromLocal8Bit(currentHome))); + m_ui.winHomeCheckBox->setToolTip(toolTip); + } else { + m_ui.winHomeCheckBox->setVisible(false); + } m_ui.repBrowserCommandPathChooser->setExpectedKind(Utils::PathChooser::ExistingCommand); m_ui.repBrowserCommandPathChooser->setPromptDialogTitle(tr("Git Repository Browser Command")); } diff --git a/src/plugins/glsleditor/glsleditor.cpp b/src/plugins/glsleditor/glsleditor.cpp index 28fdf86ab5..4f5bb5d663 100644 --- a/src/plugins/glsleditor/glsleditor.cpp +++ b/src/plugins/glsleditor/glsleditor.cpp @@ -199,7 +199,7 @@ Core::IEditor *GLSLEditorEditable::duplicate(QWidget *parent) Core::Id GLSLEditorEditable::id() const { - return GLSLEditor::Constants::C_GLSLEDITOR_ID; + return Core::Id(GLSLEditor::Constants::C_GLSLEDITOR_ID); } bool GLSLEditorEditable::open(QString *errorString, const QString &fileName, const QString &realFileName) diff --git a/src/plugins/glsleditor/glsleditor.qbs b/src/plugins/glsleditor/glsleditor.qbs index 3df8879e6f..6627277314 100644 --- a/src/plugins/glsleditor/glsleditor.qbs +++ b/src/plugins/glsleditor/glsleditor.qbs @@ -13,43 +13,34 @@ QtcPlugin { Depends { name: "GLSL" } Depends { name: "CPlusPlus" } - Depends { name: "cpp" } - cpp.includePaths: [ - "../..", - "..", - "../../libs", - buildDirectory - ] - files: [ + "GLSLEditor.mimetypes.xml", + "glslautocompleter.cpp", + "glslautocompleter.h", + "glslcompletionassist.cpp", + "glslcompletionassist.h", + "glsleditor.cpp", "glsleditor.h", + "glsleditor.qrc", "glsleditor_global.h", + "glsleditoractionhandler.cpp", "glsleditoractionhandler.h", "glsleditorconstants.h", + "glsleditoreditable.cpp", "glsleditoreditable.h", + "glsleditorfactory.cpp", "glsleditorfactory.h", + "glsleditorplugin.cpp", "glsleditorplugin.h", + "glslfilewizard.cpp", "glslfilewizard.h", + "glslhighlighter.cpp", "glslhighlighter.h", - "glslautocompleter.h", - "glslindenter.h", + "glslhoverhandler.cpp", "glslhoverhandler.h", - "glslcompletionassist.h", - "reuse.h", - "glsleditor.cpp", - "glsleditoractionhandler.cpp", - "glsleditoreditable.cpp", - "glsleditorfactory.cpp", - "glsleditorplugin.cpp", - "glslfilewizard.cpp", - "glslhighlighter.cpp", - "glslautocompleter.cpp", "glslindenter.cpp", - "glslhoverhandler.cpp", - "glslcompletionassist.cpp", + "glslindenter.h", "reuse.cpp", - "glsleditor.qrc", - "GLSLEditor.mimetypes.xml" + "reuse.h", ] } - diff --git a/src/plugins/glsleditor/glsleditorfactory.cpp b/src/plugins/glsleditor/glsleditorfactory.cpp index a611cda527..ddf857ce86 100644 --- a/src/plugins/glsleditor/glsleditorfactory.cpp +++ b/src/plugins/glsleditor/glsleditorfactory.cpp @@ -64,7 +64,7 @@ GLSLEditorFactory::GLSLEditorFactory(QObject *parent) Core::Id GLSLEditorFactory::id() const { - return C_GLSLEDITOR_ID; + return Core::Id(C_GLSLEDITOR_ID); } QString GLSLEditorFactory::displayName() const diff --git a/src/plugins/helloworld/helloworld.qbs b/src/plugins/helloworld/helloworld.qbs index d71e157d85..e5546e282a 100644 --- a/src/plugins/helloworld/helloworld.qbs +++ b/src/plugins/helloworld/helloworld.qbs @@ -6,20 +6,13 @@ QtcPlugin { name: "HelloWorld" Depends { name: "Core" } - Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["widgets", "xml", "network", "script"] } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ + "helloworldplugin.cpp", "helloworldplugin.h", + "helloworldwindow.cpp", "helloworldwindow.h", - "helloworldplugin.cpp", - "helloworldwindow.cpp" ] } diff --git a/src/plugins/help/externalhelpwindow.cpp b/src/plugins/help/externalhelpwindow.cpp index c5781199cc..ca24542b2e 100644 --- a/src/plugins/help/externalhelpwindow.cpp +++ b/src/plugins/help/externalhelpwindow.cpp @@ -35,6 +35,7 @@ #include <coreplugin/coreconstants.h> #include <coreplugin/icore.h> +#include <utils/hostosinfo.h> #include <QAction> #include <QHBoxLayout> @@ -142,17 +143,17 @@ ExternalHelpWindow::ExternalHelpWindow(QWidget *parent) tr("Show Sidebar"), this); connect(action, SIGNAL(triggered()), this, SIGNAL(showHideSidebar())); -#ifdef Q_OS_MAC - reset->setShortcut(QKeySequence(Qt::ALT + Qt::Key_0)); - action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_0)); - ctrlTab->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Tab)); - ctrlShiftTab->setShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Tab)); -#else - reset->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_0)); - action->setShortcut(QKeySequence(Qt::ALT + Qt::Key_0)); - ctrlTab->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Tab)); - ctrlShiftTab->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab)); -#endif + if (Utils::HostOsInfo::isMacHost()) { + reset->setShortcut(QKeySequence(Qt::ALT + Qt::Key_0)); + action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_0)); + ctrlTab->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Tab)); + ctrlShiftTab->setShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Tab)); + } else { + reset->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_0)); + action->setShortcut(QKeySequence(Qt::ALT + Qt::Key_0)); + ctrlTab->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Tab)); + ctrlShiftTab->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab)); + } QToolButton *button = new QToolButton; button->setDefaultAction(action); diff --git a/src/plugins/help/generalsettingspage.cpp b/src/plugins/help/generalsettingspage.cpp index cb0e4b09ee..fc2399fac8 100644 --- a/src/plugins/help/generalsettingspage.cpp +++ b/src/plugins/help/generalsettingspage.cpp @@ -79,7 +79,7 @@ QWidget *GeneralSettingsPage::createPage(QWidget *parent) m_ui->styleComboBox->setEditable(false); Core::HelpManager *manager = Core::HelpManager::instance(); - m_font = qVariantValue<QFont>(manager->customValue(QLatin1String("font"), + m_font = qvariant_cast<QFont>(manager->customValue(QLatin1String("font"), m_font)); updateFontSize(); diff --git a/src/plugins/help/help.qbs b/src/plugins/help/help.qbs index 97eaefe9ec..53dd30c2cd 100644 --- a/src/plugins/help/help.qbs +++ b/src/plugins/help/help.qbs @@ -18,85 +18,75 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "Find" } Depends { name: "Locator" } + Depends { name: "app_version_header" } Depends { name: "cpp" } Properties { condition: qtcore.versionMajor >= 5 cpp.defines: base.concat(["QT_NO_WEBKIT"]) } - cpp.defines: base.concat([ - "QT_CLUCENE_SUPPORT", - "HELP_LIBRARY" - ]) - cpp.includePaths: [ - "../../shared/help", - ".", - "..", - "../..", - "../../libs", - buildDirectory - ] + cpp.defines: base.concat(["QT_CLUCENE_SUPPORT"]) + cpp.includePaths: base.concat("../../shared/help") files: [ + "centralwidget.cpp", "centralwidget.h", + "docsettingspage.cpp", "docsettingspage.h", + "docsettingspage.ui", + "externalhelpwindow.cpp", + "externalhelpwindow.h", + "filtersettingspage.cpp", "filtersettingspage.h", + "filtersettingspage.ui", + "generalsettingspage.cpp", "generalsettingspage.h", + "generalsettingspage.ui", + "help.qrc", "help_global.h", "helpconstants.h", + "helpfindsupport.cpp", "helpfindsupport.h", + "helpindexfilter.cpp", "helpindexfilter.h", - "localhelpmanager.h", + "helpmode.cpp", "helpmode.h", + "helpplugin.cpp", "helpplugin.h", + "helpviewer.cpp", "helpviewer.h", "helpviewer_p.h", - "openpagesmanager.h", - "openpagesmodel.h", - "openpagesswitcher.h", - "openpageswidget.h", - "remotehelpfilter.h", - "searchwidget.h", - "xbelsupport.h", - "externalhelpwindow.h", - "centralwidget.cpp", - "docsettingspage.cpp", - "filtersettingspage.cpp", - "generalsettingspage.cpp", - "helpfindsupport.cpp", - "helpindexfilter.cpp", - "localhelpmanager.cpp", - "helpmode.cpp", - "helpplugin.cpp", - "helpviewer.cpp", "helpviewer_qtb.cpp", "helpviewer_qwv.cpp", + "localhelpmanager.cpp", + "localhelpmanager.h", "openpagesmanager.cpp", + "openpagesmanager.h", "openpagesmodel.cpp", + "openpagesmodel.h", "openpagesswitcher.cpp", + "openpagesswitcher.h", "openpageswidget.cpp", + "openpageswidget.h", "remotehelpfilter.cpp", + "remotehelpfilter.h", + "remotehelpfilter.ui", "searchwidget.cpp", + "searchwidget.h", "xbelsupport.cpp", - "externalhelpwindow.cpp", - "docsettingspage.ui", - "filtersettingspage.ui", - "generalsettingspage.ui", - "remotehelpfilter.ui", - "help.qrc", - "../../shared/help/bookmarkmanager.h", - "../../shared/help/contentwindow.h", - "../../shared/help/filternamedialog.h", - "../../shared/help/indexwindow.h", - "../../shared/help/topicchooser.h", + "xbelsupport.h", + "../../shared/help/bookmarkdialog.ui", "../../shared/help/bookmarkmanager.cpp", + "../../shared/help/bookmarkmanager.h", "../../shared/help/contentwindow.cpp", + "../../shared/help/contentwindow.h", "../../shared/help/filternamedialog.cpp", + "../../shared/help/filternamedialog.h", + "../../shared/help/filternamedialog.ui", "../../shared/help/indexwindow.cpp", + "../../shared/help/indexwindow.h", "../../shared/help/topicchooser.cpp", - "../../shared/help/bookmarkdialog.ui", - "../../shared/help/filternamedialog.ui", - "../../shared/help/topicchooser.ui" + "../../shared/help/topicchooser.h", + "../../shared/help/topicchooser.ui", ] } - diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index 5f7edb0f79..3eeaf50cbc 100644 --- a/src/plugins/help/helpplugin.cpp +++ b/src/plugins/help/helpplugin.cpp @@ -66,6 +66,7 @@ #include <extensionsystem/pluginmanager.h> #include <find/findplugin.h> #include <texteditor/texteditorconstants.h> +#include <utils/hostosinfo.h> #include <utils/styledbar.h> #include <QDir> @@ -252,12 +253,12 @@ bool HelpPlugin::initialize(const QStringList &arguments, QString *error) cmd->setDefaultKeySequence(QKeySequence(Qt::Key_F1)); connect(action, SIGNAL(triggered()), this, SLOT(activateContext())); -#ifndef Q_OS_MAC - action = new QAction(this); - action->setSeparator(true); - cmd = Core::ActionManager::registerAction(action, Core::Id("Help.Separator"), globalcontext); - Core::ActionManager::actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP); -#endif + if (!Utils::HostOsInfo::isMacHost()) { + action = new QAction(this); + action->setSeparator(true); + cmd = Core::ActionManager::registerAction(action, Core::Id("Help.Separator"), globalcontext); + Core::ActionManager::actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP); + } action = new QAction(tr("Technical Support"), this); cmd = Core::ActionManager::registerAction(action, Core::Id("Help.TechSupport"), globalcontext); @@ -269,12 +270,12 @@ bool HelpPlugin::initialize(const QStringList &arguments, QString *error) Core::ActionManager::actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP); connect(action, SIGNAL(triggered()), this, SLOT(slotReportBug())); -#ifndef Q_OS_MAC - action = new QAction(this); - action->setSeparator(true); - cmd = Core::ActionManager::registerAction(action, Core::Id("Help.Separator2"), globalcontext); - Core::ActionManager::actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP); -#endif + if (!Utils::HostOsInfo::isMacHost()) { + action = new QAction(this); + action->setSeparator(true); + cmd = Core::ActionManager::registerAction(action, Core::Id("Help.Separator2"), globalcontext); + Core::ActionManager::actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP); + } action = new QAction(this); Core::ActionManager::registerAction(action, Core::Constants::PRINT, modecontext); @@ -772,7 +773,7 @@ void HelpPlugin::fontChanged() createRightPaneContextViewer(); const QHelpEngine &engine = LocalHelpManager::helpEngine(); - QFont font = qVariantValue<QFont>(engine.customValue(QLatin1String("font"), + QFont font = qvariant_cast<QFont>(engine.customValue(QLatin1String("font"), m_helpViewerForSideBar->viewerFont())); m_helpViewerForSideBar->setFont(font); diff --git a/src/plugins/help/helpviewer_qtb.cpp b/src/plugins/help/helpviewer_qtb.cpp index 59cee629c8..65b56e1967 100644 --- a/src/plugins/help/helpviewer_qtb.cpp +++ b/src/plugins/help/helpviewer_qtb.cpp @@ -35,6 +35,8 @@ #include "helpviewer_p.h" #include "localhelpmanager.h" +#include <utils/hostosinfo.h> + #include <QApplication> #include <QClipboard> #include <QContextMenuEvent> @@ -79,7 +81,7 @@ HelpViewer::~HelpViewer() QFont HelpViewer::viewerFont() const { const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); - return qVariantValue<QFont>(engine.customValue(QLatin1String("font"), + return qvariant_cast<QFont>(engine.customValue(QLatin1String("font"), qApp->font())); } @@ -285,19 +287,15 @@ void HelpViewer::wheelEvent(QWheelEvent *e) void HelpViewer::mousePressEvent(QMouseEvent *e) { -#ifdef Q_OS_LINUX - if (handleForwardBackwardMouseButtons(e)) + if (Utils::HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(e)) return; -#endif QTextBrowser::mousePressEvent(e); } void HelpViewer::mouseReleaseEvent(QMouseEvent *e) { -#ifndef Q_OS_LINUX - if (handleForwardBackwardMouseButtons(e)) + if (!Utils::HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(e)) return; -#endif bool controlPressed = e->modifiers() & Qt::ControlModifier; if ((controlPressed && d->hasAnchorAt(this, e->pos())) || diff --git a/src/plugins/help/helpviewer_qwv.cpp b/src/plugins/help/helpviewer_qwv.cpp index a19ac2e52e..99c89ac61f 100644 --- a/src/plugins/help/helpviewer_qwv.cpp +++ b/src/plugins/help/helpviewer_qwv.cpp @@ -36,6 +36,8 @@ #include "localhelpmanager.h" #include "openpagesmanager.h" +#include <utils/hostosinfo.h> + #include <QDebug> #include <QFileInfo> #include <QString> @@ -54,6 +56,8 @@ #include <utils/networkaccessmanager.h> +#include <cstring> + using namespace Find; using namespace Help; using namespace Help::Internal; @@ -131,6 +135,7 @@ HelpNetworkReply::HelpNetworkReply(const QNetworkRequest &request, , dataLength(fileData.length()) { setRequest(request); + setUrl(request.url()); setOpenMode(QIODevice::ReadOnly); setHeader(QNetworkRequest::ContentTypeHeader, mimeType); @@ -144,7 +149,7 @@ qint64 HelpNetworkReply::readData(char *buffer, qint64 maxlen) { qint64 len = qMin(qint64(data.length()), maxlen); if (len) { - qMemCopy(buffer, data.constData(), len); + std::memcpy(buffer, data.constData(), len); data.remove(0, len); } return len; @@ -175,24 +180,6 @@ QNetworkReply *HelpNetworkAccessManager::createRequest(Operation op, QString url = request.url().toString(); const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); - // TODO: For some reason the url to load is already wrong (passed from webkit) - // though the css file and the references inside should work that way. One - // possible problem might be that the css is loaded at the same level as the - // html, thus a path inside the css like (../images/foo.png) might cd out of - // the virtual folder - if (!engine.findFile(url).isValid()) { - if (url.startsWith(HelpViewer::NsNokia) || url.startsWith(HelpViewer::NsTrolltech)) { - QUrl newUrl = request.url(); - if (!newUrl.path().startsWith(QLatin1String("/qdoc/")) || - !newUrl.path().startsWith(QLatin1String("/doc/"))) { - QString path = newUrl.path(); - newUrl.setPath(QLatin1String("/qdoc/") + path); - if (!engine.findFile(newUrl).isValid()) - newUrl.setPath(QLatin1String("/doc/") + path); - url = newUrl.toString(); - } - } - } const QString &mimeType = HelpViewer::mimeFromUrl(url); const QByteArray &data = engine.findFile(url).isValid() ? engine.fileData(url) @@ -346,7 +333,7 @@ HelpViewer::HelpViewer(qreal zoom, QWidget *parent) connect(page(), SIGNAL(printRequested(QWebFrame*)), this, SIGNAL(printRequested())); setViewerFont(viewerFont()); - setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom); + setZoomFactor(zoom == 0.0 ? 1.0 : zoom); } HelpViewer::~HelpViewer() @@ -359,7 +346,7 @@ QFont HelpViewer::viewerFont() const QFont font(QApplication::font().family(), webSettings->fontSize(QWebSettings::DefaultFontSize)); const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); - return qVariantValue<QFont>(engine.customValue(QLatin1String("font"), + return qvariant_cast<QFont>(engine.customValue(QLatin1String("font"), font)); } @@ -372,22 +359,22 @@ void HelpViewer::setViewerFont(const QFont &font) void HelpViewer::scaleUp() { - setTextSizeMultiplier(textSizeMultiplier() + 0.1); + setZoomFactor(zoomFactor() + 0.1); } void HelpViewer::scaleDown() { - setTextSizeMultiplier(qMax(qreal(0.0), textSizeMultiplier() - qreal(0.1))); + setZoomFactor(qMax(qreal(0.0), zoomFactor() - qreal(0.1))); } void HelpViewer::resetScale() { - setTextSizeMultiplier(1.0); + setZoomFactor(1.0); } qreal HelpViewer::scale() const { - return textSizeMultiplier(); + return zoomFactor(); } QString HelpViewer::title() const @@ -497,10 +484,8 @@ void HelpViewer::wheelEvent(QWheelEvent *event) void HelpViewer::mousePressEvent(QMouseEvent *event) { -#ifdef Q_OS_LINUX - if (handleForwardBackwardMouseButtons(event)) + if (Utils::HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(event)) return; -#endif if (HelpPage *currentPage = static_cast<HelpPage*> (page())) { currentPage->m_pressedButtons = event->buttons(); @@ -512,10 +497,8 @@ void HelpViewer::mousePressEvent(QMouseEvent *event) void HelpViewer::mouseReleaseEvent(QMouseEvent *event) { -#ifndef Q_OS_LINUX - if (handleForwardBackwardMouseButtons(event)) + if (!Utils::HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(event)) return; -#endif QWebView::mouseReleaseEvent(event); } diff --git a/src/plugins/help/openpagesswitcher.cpp b/src/plugins/help/openpagesswitcher.cpp index f5c81b307d..21969b76e0 100644 --- a/src/plugins/help/openpagesswitcher.cpp +++ b/src/plugins/help/openpagesswitcher.cpp @@ -33,6 +33,8 @@ #include "openpagesmodel.h" #include "openpageswidget.h" +#include <utils/hostosinfo.h> + #include <QEvent> #include <QKeyEvent> @@ -53,9 +55,8 @@ OpenPagesSwitcher::OpenPagesSwitcher(OpenPagesModel *model) // We disable the frame on this list view and use a QFrame around it instead. // This improves the look with QGTKStyle. -#ifndef Q_OS_MAC - setFrameStyle(m_openPagesWidget->frameStyle()); -#endif + if (!Utils::HostOsInfo::isMacHost()) + setFrameStyle(m_openPagesWidget->frameStyle()); m_openPagesWidget->setFrameStyle(QFrame::NoFrame); m_openPagesWidget->allowContextMenu(false); @@ -124,11 +125,8 @@ bool OpenPagesSwitcher::eventFilter(QObject *object, QEvent *event) emit setCurrentPage(m_openPagesWidget->currentIndex()); return true; } -#ifdef Q_OS_MAC - const Qt::KeyboardModifier modifier = Qt::AltModifier; -#else - const Qt::KeyboardModifier modifier = Qt::ControlModifier; -#endif + const Qt::KeyboardModifiers modifier = Utils::HostOsInfo::isMacHost() + ? Qt::AltModifier : Qt::ControlModifier; if (key == Qt::Key_Backtab && (ke->modifiers() == (modifier | Qt::ShiftModifier))) gotoNextPage(); diff --git a/src/plugins/help/remotehelpfilter.cpp b/src/plugins/help/remotehelpfilter.cpp index e1ccdad2bc..464c59791b 100644 --- a/src/plugins/help/remotehelpfilter.cpp +++ b/src/plugins/help/remotehelpfilter.cpp @@ -49,6 +49,8 @@ RemoteFilterOptions::RemoteFilterOptions(RemoteHelpFilter *filter, QWidget *pare connect(m_ui.add, SIGNAL(clicked()), this, SLOT(addNewItem())); connect(m_ui.remove, SIGNAL(clicked()), this, SLOT(removeItem())); + connect(m_ui.listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), SLOT(updateRemoveButton())); + updateRemoveButton(); } void RemoteFilterOptions::addNewItem() @@ -57,6 +59,7 @@ void RemoteFilterOptions::addNewItem() m_ui.listWidget->addItem(item); item->setSelected(true); item->setFlags(item->flags() | Qt::ItemIsEditable); + m_ui.listWidget->setCurrentItem(item); m_ui.listWidget->editItem(item); } @@ -68,6 +71,11 @@ void RemoteFilterOptions::removeItem() } } +void RemoteFilterOptions::updateRemoveButton() +{ + m_ui.remove->setEnabled(m_ui.listWidget->currentItem()); +} + // -- RemoteHelpFilter RemoteHelpFilter::RemoteHelpFilter() diff --git a/src/plugins/help/remotehelpfilter.h b/src/plugins/help/remotehelpfilter.h index 7c05cff3af..c76e4f12cb 100644 --- a/src/plugins/help/remotehelpfilter.h +++ b/src/plugins/help/remotehelpfilter.h @@ -78,6 +78,7 @@ public: private slots: void addNewItem(); void removeItem(); + void updateRemoveButton(); private: RemoteHelpFilter *m_filter; diff --git a/src/plugins/help/searchwidget.cpp b/src/plugins/help/searchwidget.cpp index e40bbd0ea4..2bc80ba80a 100644 --- a/src/plugins/help/searchwidget.cpp +++ b/src/plugins/help/searchwidget.cpp @@ -67,7 +67,7 @@ SearchWidget::~SearchWidget() void SearchWidget::zoomIn() { - QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget); + QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>(); if (browser && zoomCount != 10) { zoomCount++; browser->zoomIn(); @@ -76,7 +76,7 @@ void SearchWidget::zoomIn() void SearchWidget::zoomOut() { - QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget); + QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>(); if (browser && zoomCount != -5) { zoomCount--; browser->zoomOut(); @@ -88,7 +88,7 @@ void SearchWidget::resetZoom() if (zoomCount == 0) return; - QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget); + QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>(); if (browser) { browser->zoomOut(zoomCount); zoomCount = 0; @@ -135,7 +135,7 @@ void SearchWidget::showEvent(QShowEvent *event) connect(searchEngine, SIGNAL(searchingFinished(int)), this, SLOT(searchingFinished(int))); - QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget); + QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>(); browser->viewport()->installEventFilter(this); connect(searchEngine, SIGNAL(indexingStarted()), this, @@ -214,7 +214,7 @@ void SearchWidget::indexingFinished() bool SearchWidget::eventFilter(QObject *o, QEvent *e) { - QTextBrowser *browser = qFindChild<QTextBrowser *>(resultWidget); + QTextBrowser *browser = resultWidget->findChild<QTextBrowser *>(); if (browser && o == browser->viewport() && e->type() == QEvent::MouseButtonRelease){ QMouseEvent *me = static_cast<QMouseEvent *>(e); @@ -232,7 +232,7 @@ bool SearchWidget::eventFilter(QObject *o, QEvent *e) void SearchWidget::contextMenuEvent(QContextMenuEvent *contextMenuEvent) { - QTextBrowser *browser = qFindChild<QTextBrowser *>(resultWidget); + QTextBrowser *browser = resultWidget->findChild<QTextBrowser *>(); if (!browser) return; diff --git a/src/plugins/imageviewer/imageviewer.qbs b/src/plugins/imageviewer/imageviewer.qbs index d2257621cc..79e5528baa 100644 --- a/src/plugins/imageviewer/imageviewer.qbs +++ b/src/plugins/imageviewer/imageviewer.qbs @@ -8,31 +8,22 @@ QtcPlugin { Depends { name: "Qt"; submodules: ["widgets", "svg"] } Depends { name: "Core" } - Depends { name: "cpp" } - cpp.includePaths: [ - ".", - "..", - "../../libs", - buildDirectory - ] - files: [ - "imageviewerplugin.h", - "imageviewerfactory.h", - "imageviewerfile.h", - "imageviewer.h", + "ImageViewer.mimetypes.xml", + "imageview.cpp", "imageview.h", - "imageviewerconstants.h", + "imageviewer.cpp", + "imageviewer.h", + "imageviewer.qrc", + "imagevieweractionhandler.cpp", "imagevieweractionhandler.h", - "imageviewerplugin.cpp", + "imageviewerconstants.h", "imageviewerfactory.cpp", + "imageviewerfactory.h", "imageviewerfile.cpp", - "imageviewer.cpp", - "imageview.cpp", - "imagevieweractionhandler.cpp", + "imageviewerfile.h", + "imageviewerplugin.cpp", + "imageviewerplugin.h", "imageviewertoolbar.ui", - "imageviewer.qrc", - "ImageViewer.mimetypes.xml" ] } - diff --git a/src/plugins/imageviewer/imageviewerfactory.cpp b/src/plugins/imageviewer/imageviewerfactory.cpp index 177d311e0a..040ebb8cbf 100644 --- a/src/plugins/imageviewer/imageviewerfactory.cpp +++ b/src/plugins/imageviewer/imageviewerfactory.cpp @@ -95,7 +95,7 @@ QStringList ImageViewerFactory::mimeTypes() const Core::Id ImageViewerFactory::id() const { - return Constants::IMAGEVIEWER_ID; + return Core::Id(Constants::IMAGEVIEWER_ID); } QString ImageViewerFactory::displayName() const diff --git a/src/plugins/locator/basefilefilter.cpp b/src/plugins/locator/basefilefilter.cpp index 45e5d41b9e..1f3e3dd016 100644 --- a/src/plugins/locator/basefilefilter.cpp +++ b/src/plugins/locator/basefilefilter.cpp @@ -30,12 +30,14 @@ #include "basefilefilter.h" #include <coreplugin/editormanager/editormanager.h> +#include <utils/fileutils.h> #include <QDir> #include <QStringMatcher> using namespace Core; using namespace Locator; +using namespace Utils; BaseFileFilter::BaseFileFilter() : m_forceNewSearchList(false) @@ -80,7 +82,7 @@ QList<FilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Locator::FilterEn || (!hasWildcard && matcher.indexIn(name) != -1)) { QFileInfo fi(path); FilterEntry entry(this, fi.fileName(), QString(path + lineNoSuffix)); - entry.extraInfo = QDir::toNativeSeparators(fi.path()); + entry.extraInfo = FileUtils::shortNativePath(FileName(fi)); entry.resolveFileIcon = true; if (name.startsWith(needle)) matches.append(entry); diff --git a/src/plugins/locator/locator.pro b/src/plugins/locator/locator.pro index fab92816fc..7227847c47 100644 --- a/src/plugins/locator/locator.pro +++ b/src/plugins/locator/locator.pro @@ -1,6 +1,6 @@ TEMPLATE = lib TARGET = Locator -DEFINES += LOCATOR_LIBRARY +DEFINES += LOCATOR_LIBRARY QT_NO_CAST_FROM_ASCII include(../../qtcreatorplugin.pri) include(locator_dependencies.pri) HEADERS += locatorplugin.h \ diff --git a/src/plugins/locator/locator.qbs b/src/plugins/locator/locator.qbs index 651fece80a..33380005a6 100644 --- a/src/plugins/locator/locator.qbs +++ b/src/plugins/locator/locator.qbs @@ -9,32 +9,30 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "cpp" } - cpp.includePaths: [ - ".", - "..", + cpp.includePaths: base.concat([ "generichighlighter", "tooltip", "snippets", - "codeassist", - "../../libs", - buildDirectory - ] + "codeassist" + ]) + cpp.defines: base.concat(["QT_NO_CAST_FROM_ASCII"]) files: [ - "directoryfilter.ui", - "filesystemfilter.ui", - "locator.qrc", - "settingspage.ui", "basefilefilter.cpp", "basefilefilter.h", "commandlocator.cpp", "commandlocator.h", "directoryfilter.cpp", "directoryfilter.h", + "directoryfilter.ui", + "executefilter.cpp", "executefilter.h", "filesystemfilter.cpp", "filesystemfilter.h", + "filesystemfilter.ui", "ilocatorfilter.cpp", + "ilocatorfilter.h", + "locator.qrc", "locator_global.h", "locatorconstants.h", "locatorfiltersfilter.cpp", @@ -43,16 +41,14 @@ QtcPlugin { "locatormanager.h", "locatorplugin.cpp", "locatorplugin.h", + "locatorwidget.cpp", + "locatorwidget.h", "opendocumentsfilter.cpp", "opendocumentsfilter.h", "settingspage.cpp", "settingspage.h", - "executefilter.cpp", - "ilocatorfilter.h", - "locatorwidget.cpp", - "locatorwidget.h", + "settingspage.ui", "images/locator.png", - "images/reload.png" + "images/reload.png", ] } - diff --git a/src/plugins/locator/locatorwidget.cpp b/src/plugins/locator/locatorwidget.cpp index 3e6e1ccc3b..343b1e7cd8 100644 --- a/src/plugins/locator/locatorwidget.cpp +++ b/src/plugins/locator/locatorwidget.cpp @@ -44,6 +44,7 @@ #include <coreplugin/coreconstants.h> #include <coreplugin/fileiconprovider.h> #include <utils/filterlineedit.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/runextensions.h> @@ -204,8 +205,9 @@ QVariant LocatorModel::data(const QModelIndex &index, int role) const void LocatorModel::setEntries(const QList<FilterEntry> &entries) { + beginResetModel(); mEntries = entries; - reset(); + endResetModel(); } // =========== CompletionList =========== @@ -221,12 +223,12 @@ CompletionList::CompletionList(QWidget *parent) // This is too slow when done on all results //header()->setResizeMode(QHeaderView::ResizeToContents); setWindowFlags(Qt::ToolTip); -#ifdef Q_OS_MAC - if (horizontalScrollBar()) - horizontalScrollBar()->setAttribute(Qt::WA_MacMiniSize); - if (verticalScrollBar()) - verticalScrollBar()->setAttribute(Qt::WA_MacMiniSize); -#endif + if (Utils::HostOsInfo::isMacHost()) { + if (horizontalScrollBar()) + horizontalScrollBar()->setAttribute(Qt::WA_MacMiniSize); + if (verticalScrollBar()) + verticalScrollBar()->setAttribute(Qt::WA_MacMiniSize); + } } void CompletionList::updatePreferredSize() @@ -408,11 +410,14 @@ bool LocatorWidget::eventFilter(QObject *obj, QEvent *event) } } } else if (obj == m_fileLineEdit && event->type() == QEvent::FocusOut) { -#if defined(Q_OS_WIN) - QFocusEvent *fev = static_cast<QFocusEvent*>(event); - if (fev->reason() != Qt::ActiveWindowFocusReason || - (fev->reason() == Qt::ActiveWindowFocusReason && !m_completionList->isActiveWindow())) -#endif + bool hideList = true; + if (Utils::HostOsInfo::isWindowsHost()) { + QFocusEvent *fev = static_cast<QFocusEvent*>(event); + if (fev->reason() == Qt::ActiveWindowFocusReason && + !(fev->reason() == Qt::ActiveWindowFocusReason && !m_completionList->isActiveWindow())) + hideList = false; + } + if (hideList) m_completionList->hide(); } else if (obj == m_fileLineEdit && event->type() == QEvent::FocusIn) { showPopupNow(); diff --git a/src/plugins/locator/opendocumentsfilter.cpp b/src/plugins/locator/opendocumentsfilter.cpp index 57e90705bc..53b8c9daa4 100644 --- a/src/plugins/locator/opendocumentsfilter.cpp +++ b/src/plugins/locator/opendocumentsfilter.cpp @@ -31,6 +31,7 @@ #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/ieditor.h> +#include <utils/fileutils.h> #include <QFileInfo> #include <QDir> @@ -38,6 +39,7 @@ using namespace Core; using namespace Locator; using namespace Locator::Internal; +using namespace Utils; OpenDocumentsFilter::OpenDocumentsFilter(EditorManager *editorManager) : m_editorManager(editorManager) @@ -71,7 +73,7 @@ QList<FilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locator::Fil if (!fileName.isEmpty()) { QFileInfo fi(fileName); FilterEntry fiEntry(this, fi.fileName(), QString(fileName + lineNoSuffix)); - fiEntry.extraInfo = QDir::toNativeSeparators(fi.path()); + fiEntry.extraInfo = FileUtils::shortNativePath(FileName(fi)); fiEntry.resolveFileIcon = true; value.append(fiEntry); } diff --git a/src/plugins/locator/settingspage.cpp b/src/plugins/locator/settingspage.cpp index 23807c64d5..4a72047f9c 100644 --- a/src/plugins/locator/settingspage.cpp +++ b/src/plugins/locator/settingspage.cpp @@ -48,7 +48,7 @@ using namespace Locator::Internal; SettingsPage::SettingsPage(LocatorPlugin *plugin) : m_plugin(plugin), m_page(0) { - setId(Constants::FILTER_OPTIONS_PAGE); + setId(QLatin1String(Constants::FILTER_OPTIONS_PAGE)); setDisplayName(QCoreApplication::translate("Locator", Locator::Constants::FILTER_OPTIONS_PAGE)); setCategory(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE)); setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::SETTINGS_TR_CATEGORY_CORE)); diff --git a/src/plugins/macros/macros.qbs b/src/plugins/macros/macros.qbs index 1712dc5661..c30877a7cc 100644 --- a/src/plugins/macros/macros.qbs +++ b/src/plugins/macros/macros.qbs @@ -10,19 +10,9 @@ QtcPlugin { Depends { name: "Locator" } Depends { name: "Find" } Depends { name: "TextEditor" } - - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - "../..", - buildDirectory - ] + Depends { name: "app_version_header" } files: [ - "macrooptionswidget.ui", - "macros.qrc", - "savedialog.ui", "actionmacrohandler.cpp", "actionmacrohandler.h", "findmacrohandler.cpp", @@ -41,6 +31,8 @@ QtcPlugin { "macrooptionspage.h", "macrooptionswidget.cpp", "macrooptionswidget.h", + "macrooptionswidget.ui", + "macros.qrc", "macros_global.h", "macrosconstants.h", "macrosplugin.cpp", @@ -49,8 +41,8 @@ QtcPlugin { "macrotextfind.h", "savedialog.cpp", "savedialog.h", + "savedialog.ui", "texteditormacrohandler.cpp", - "texteditormacrohandler.h" + "texteditormacrohandler.h", ] } - diff --git a/src/plugins/madde/Madde.pluginspec.in b/src/plugins/madde/Madde.pluginspec.in index ff3f26eb74..edd4826395 100644 --- a/src/plugins/madde/Madde.pluginspec.in +++ b/src/plugins/madde/Madde.pluginspec.in @@ -15,5 +15,6 @@ Alternatively, this plugin may be used under the terms of the GNU Lesser General <url>http://www.qt-project.org</url> <dependencyList> <dependency name=\"RemoteLinux\" version=\"$$QTCREATOR_VERSION\"/> + <dependency name=\"Qt4ProjectManager\" version=\"$$QTCREATOR_VERSION\"/> </dependencyList> </plugin> diff --git a/src/plugins/madde/debianmanager.cpp b/src/plugins/madde/debianmanager.cpp index 0ff98b8936..582e801f7c 100644 --- a/src/plugins/madde/debianmanager.cpp +++ b/src/plugins/madde/debianmanager.cpp @@ -537,7 +537,7 @@ bool DebianManager::setPackageManagerIcon(const Utils::FileName &debianDir, Core QBuffer buffer(&iconAsBase64); buffer.open(QIODevice::WriteOnly); if (!pixmap.scaled(MaddeDevice::packageManagerIconSize(deviceType)) - .save(&buffer, iconPath.toFileInfo().suffix().toAscii())) { + .save(&buffer, iconPath.toFileInfo().suffix().toLatin1())) { if (error) *error = tr("Could not export image file '%1'.").arg(iconPath.toUserOutput()); return false; @@ -635,7 +635,7 @@ DebianManager::ActionStatus DebianManager::createTemplate(Qt4ProjectManager::Qt4 if (!QFile::rename(location.appendPath(QLatin1String("debian")).toString(), debianDir.toString())) { raiseError(tr("Unable to move new debian directory to '%1'.").arg(debianDir.toUserOutput())); - Utils::FileUtils::removeRecursively(location.toString(), &error); + Utils::FileUtils::removeRecursively(location, &error); return ActionFailed; } diff --git a/src/plugins/madde/madde.pro b/src/plugins/madde/madde.pro index 73bf1efad4..7bf61f30c0 100644 --- a/src/plugins/madde/madde.pro +++ b/src/plugins/madde/madde.pro @@ -36,7 +36,6 @@ HEADERS += \ maemoqemusettings.h \ qt4maemodeployconfiguration.h \ maemodeviceconfigwizard.h \ - maemodeployconfigurationwidget.h \ maemoinstalltosysrootstep.h \ maemodeploymentmounter.h \ maemopackageinstaller.h \ @@ -80,7 +79,6 @@ SOURCES += \ maemoqemusettings.cpp \ qt4maemodeployconfiguration.cpp \ maemodeviceconfigwizard.cpp \ - maemodeployconfigurationwidget.cpp \ maemoinstalltosysrootstep.cpp \ maemodeploymentmounter.cpp \ maemopackageinstaller.cpp \ @@ -107,8 +105,7 @@ FORMS += \ maemodeviceconfigwizardpreviouskeysetupcheckpage.ui \ maemodeviceconfigwizardreusekeyscheckpage.ui \ maemodeviceconfigwizardkeycreationpage.ui \ - maemodeviceconfigwizardkeydeploymentpage.ui \ - maemodeployconfigurationwidget.ui + maemodeviceconfigwizardkeydeploymentpage.ui RESOURCES += qt-maemo.qrc DEFINES += QT_NO_CAST_TO_ASCII diff --git a/src/plugins/madde/madde.qbs b/src/plugins/madde/madde.qbs index 260ca82050..86adadbf5e 100644 --- a/src/plugins/madde/madde.qbs +++ b/src/plugins/madde/madde.qbs @@ -13,31 +13,29 @@ QtcPlugin { Depends { name: "Qt.gui" } Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] cpp.defines: base.concat(['QT_NO_CAST_TO_ASCII']) files: [ + "debianmanager.cpp", + "debianmanager.h", "madde_exports.h", + "maddedevice.cpp", + "maddedevice.h", "maddedeviceconfigurationfactory.cpp", "maddedeviceconfigurationfactory.h", "maddedevicetester.cpp", "maddedevicetester.h", "maddeplugin.cpp", "maddeplugin.h", - "maddeuploadandinstallpackagesteps.cpp", - "maddeuploadandinstallpackagesteps.h", "maddeqemustartstep.cpp", "maddeqemustartstep.h", + "maddeuploadandinstallpackagesteps.cpp", + "maddeuploadandinstallpackagesteps.h", + "maemoapplicationrunnerhelperactions.cpp", + "maemoapplicationrunnerhelperactions.h", "maemoconstants.h", "maemodeploybymountsteps.cpp", "maemodeploybymountsteps.h", - "maemodeployconfigurationwidget.cpp", - "maemodeployconfigurationwidget.h", - "maemodeployconfigurationwidget.ui", "maemodeploymentmounter.cpp", "maemodeploymentmounter.h", "maemodeploystepfactory.cpp", @@ -115,11 +113,5 @@ QtcPlugin { "qt-maemo.qrc", "qt4maemodeployconfiguration.cpp", "qt4maemodeployconfiguration.h", - "maddedevice.cpp", - "maddedevice.h", - "debianmanager.h", - "debianmanager.cpp", - "maemoapplicationrunnerhelperactions.h", - "maemoapplicationrunnerhelperactions.cpp" ] } diff --git a/src/plugins/madde/madde_dependencies.pri b/src/plugins/madde/madde_dependencies.pri index 94d99fc73d..630796bcbf 100644 --- a/src/plugins/madde/madde_dependencies.pri +++ b/src/plugins/madde/madde_dependencies.pri @@ -1 +1,2 @@ +include(../../plugins/qt4projectmanager/qt4projectmanager.pri) include(../../plugins/remotelinux/remotelinux.pri) diff --git a/src/plugins/madde/maemoconstants.h b/src/plugins/madde/maemoconstants.h index b5143fc87a..4e14fb6e85 100644 --- a/src/plugins/madde/maemoconstants.h +++ b/src/plugins/madde/maemoconstants.h @@ -40,12 +40,6 @@ const char HarmattanOsType[] = "HarmattanOsType"; #define PREFIX "Qt4ProjectManager.MaemoRunConfiguration" -#ifdef Q_OS_WIN32 -#define EXEC_SUFFIX ".exe" -#else -#define EXEC_SUFFIX "" -#endif - static const char MAEMO_RC_ID_PREFIX[] = PREFIX ":"; static const QLatin1String LastDeployedHostsKey(PREFIX ".LastDeployedHosts"); diff --git a/src/plugins/madde/maemodeploybymountsteps.cpp b/src/plugins/madde/maemodeploybymountsteps.cpp index 036a225f8c..5b58e32e76 100644 --- a/src/plugins/madde/maemodeploybymountsteps.cpp +++ b/src/plugins/madde/maemodeploybymountsteps.cpp @@ -37,13 +37,13 @@ #include "maemoremotecopyfacility.h" #include "qt4maemodeployconfiguration.h" +#include <projectexplorer/deploymentdata.h> #include <projectexplorer/project.h> #include <projectexplorer/target.h> #include <qt4projectmanager/qt4buildconfiguration.h> #include <remotelinux/abstractremotelinuxdeployservice.h> -#include <remotelinux/deployablefile.h> -#include <remotelinux/deploymentinfo.h> #include <remotelinux/linuxdevice.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <ssh/sshconnection.h> @@ -129,7 +129,7 @@ private: void cancelInstallation(); void handleInstallationSuccess(); - Q_SLOT void handleFileCopied(const RemoteLinux::DeployableFile&deployable); + Q_SLOT void handleFileCopied(const ProjectExplorer::DeployableFile &deployable); MaemoRemoteCopyFacility * const m_copyFacility; mutable QList<DeployableFile> m_filesToCopy; @@ -304,8 +304,8 @@ MaemoMountAndCopyFilesService::MaemoMountAndCopyFilesService(QObject *parent) connect(m_copyFacility, SIGNAL(stdoutData(QString)), SIGNAL(stdOutData(QString))); connect(m_copyFacility, SIGNAL(stderrData(QString)), SIGNAL(stdErrData(QString))); connect(m_copyFacility, SIGNAL(progress(QString)), SIGNAL(progressMessage(QString))); - connect(m_copyFacility, SIGNAL(fileCopied(RemoteLinux::DeployableFile)), - SLOT(handleFileCopied(RemoteLinux::DeployableFile))); + connect(m_copyFacility, SIGNAL(fileCopied(ProjectExplorer::DeployableFile)), + SLOT(handleFileCopied(ProjectExplorer::DeployableFile))); connect(m_copyFacility, SIGNAL(finished(QString)), SLOT(handleInstallationFinished(QString))); } @@ -314,7 +314,7 @@ bool MaemoMountAndCopyFilesService::isDeploymentNecessary() const m_filesToCopy.clear(); for (int i = 0; i < m_deployableFiles.count(); ++i) { const DeployableFile &d = m_deployableFiles.at(i); - if (hasChangedSinceLastDeployment(d) || QFileInfo(d.localFilePath).isDir()) + if (hasChangedSinceLastDeployment(d) || d.localFilePath().toFileInfo().isDir()) m_filesToCopy << d; } return !m_filesToCopy.isEmpty(); @@ -323,29 +323,31 @@ bool MaemoMountAndCopyFilesService::isDeploymentNecessary() const QList<MaemoMountSpecification> MaemoMountAndCopyFilesService::mountSpecifications() const { QList<MaemoMountSpecification> mountSpecs; -#ifdef Q_OS_WIN - bool drivesToMount[26]; - qFill(drivesToMount, drivesToMount + sizeof drivesToMount / sizeof drivesToMount[0], false); - for (int i = 0; i < m_filesToCopy.count(); ++i) { - const QString localDir = QFileInfo(m_filesToCopy.at(i).localFilePath).canonicalPath(); - const char driveLetter = localDir.at(0).toLower().toLatin1(); - if (driveLetter < 'a' || driveLetter > 'z') { - qWarning("Weird: drive letter is '%c'.", driveLetter); - continue; + if (Utils::HostOsInfo::isWindowsHost()) { + bool drivesToMount[26]; + qFill(drivesToMount, drivesToMount + sizeof drivesToMount / sizeof drivesToMount[0], false); + for (int i = 0; i < m_filesToCopy.count(); ++i) { + const QString localDir + = m_filesToCopy.at(i).localFilePath().toFileInfo().canonicalPath(); + const char driveLetter = localDir.at(0).toLower().toLatin1(); + if (driveLetter < 'a' || driveLetter > 'z') { + qWarning("Weird: drive letter is '%c'.", driveLetter); + continue; + } + + const int index = driveLetter - 'a'; + if (drivesToMount[index]) + continue; + + const QString mountPoint = deployMountPoint() + QLatin1Char('/') + + QLatin1Char(driveLetter); + const MaemoMountSpecification mountSpec(localDir.left(3), mountPoint); + mountSpecs << mountSpec; + drivesToMount[index] = true; } - - const int index = driveLetter - 'a'; - if (drivesToMount[index]) - continue; - - const QString mountPoint = deployMountPoint() + QLatin1Char('/') + QLatin1Char(driveLetter); - const MaemoMountSpecification mountSpec(localDir.left(3), mountPoint); - mountSpecs << mountSpec; - drivesToMount[index] = true; + } else { + mountSpecs << MaemoMountSpecification(QLatin1String("/"), deployMountPoint()); } -#else - mountSpecs << MaemoMountSpecification(QLatin1String("/"), deployMountPoint()); -#endif return mountSpecs; } @@ -444,12 +446,7 @@ AbstractRemoteLinuxDeployService *MaemoCopyFilesViaMountStep::deployService() co bool MaemoCopyFilesViaMountStep::initInternal(QString *error) { - QList<DeployableFile> deployableFiles; - const DeploymentInfo * const deploymentInfo = deployConfiguration()->deploymentInfo(); - const int deployableCount = deploymentInfo->deployableCount(); - for (int i = 0; i < deployableCount; ++i) - deployableFiles << deploymentInfo->deployableAt(i); - m_deployService->setDeployableFiles(deployableFiles); + m_deployService->setDeployableFiles(target()->deploymentData().allFiles()); return deployService()->isDeploymentPossible(error); } diff --git a/src/plugins/madde/maemodeployconfigurationwidget.cpp b/src/plugins/madde/maemodeployconfigurationwidget.cpp deleted file mode 100644 index 049848d14f..0000000000 --- a/src/plugins/madde/maemodeployconfigurationwidget.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ -#include "maemodeployconfigurationwidget.h" -#include "ui_maemodeployconfigurationwidget.h" - -#include "maemoglobal.h" -#include "maemoconstants.h" -#include "qt4maemodeployconfiguration.h" - -#include <projectexplorer/kitinformation.h> -#include <projectexplorer/target.h> -#include <qt4projectmanager/qt4nodes.h> -#include <remotelinux/deployablefile.h> -#include <remotelinux/deployablefilesperprofile.h> -#include <remotelinux/deploymentinfo.h> -#include <remotelinux/deploymentsettingsassistant.h> -#include <remotelinux/remotelinuxdeployconfigurationwidget.h> -#include <utils/fileutils.h> -#include <utils/qtcassert.h> - -#include <QFileInfo> -#include <QFileDialog> -#include <QMessageBox> -#include <QPixmap> -#include <QVBoxLayout> - -using namespace ProjectExplorer; -using namespace Qt4ProjectManager; -using namespace RemoteLinux; - -namespace Madde { -namespace Internal { - -MaemoDeployConfigurationWidget::MaemoDeployConfigurationWidget(QWidget *parent) - : DeployConfigurationWidget(parent), - ui(new Ui::MaemoDeployConfigurationWidget), - m_remoteLinuxWidget(new RemoteLinuxDeployConfigurationWidget) -{ - QVBoxLayout *mainLayout = new QVBoxLayout(this); - mainLayout->setSpacing(0); - mainLayout->addWidget(m_remoteLinuxWidget); - QWidget * const subWidget = new QWidget; - ui->setupUi(subWidget); - mainLayout->addWidget(subWidget); - mainLayout->addStretch(1); - - connect(m_remoteLinuxWidget, - SIGNAL(currentModelChanged(const RemoteLinux::DeployableFilesPerProFile*)), - SLOT(handleCurrentModelChanged(const RemoteLinux::DeployableFilesPerProFile*))); - handleCurrentModelChanged(m_remoteLinuxWidget->currentModel()); -} - -MaemoDeployConfigurationWidget::~MaemoDeployConfigurationWidget() -{ - delete ui; -} - -void MaemoDeployConfigurationWidget::init(DeployConfiguration *dc) -{ - m_remoteLinuxWidget->init(dc); - connect(ui->addDesktopFileButton, SIGNAL(clicked()), SLOT(addDesktopFile())); - connect(ui->addIconButton, SIGNAL(clicked()), SLOT(addIcon())); - connect(deployConfiguration()->deploymentInfo(), SIGNAL(modelAboutToBeReset()), - SLOT(handleDeploymentInfoToBeReset())); -} - -Qt4MaemoDeployConfiguration *MaemoDeployConfigurationWidget::deployConfiguration() const -{ - return qobject_cast<Qt4MaemoDeployConfiguration *>(m_remoteLinuxWidget->deployConfiguration()); -} - -void MaemoDeployConfigurationWidget::handleDeploymentInfoToBeReset() -{ - ui->addDesktopFileButton->setEnabled(false); - ui->addIconButton->setEnabled(false); -} - -void MaemoDeployConfigurationWidget::handleCurrentModelChanged(const DeployableFilesPerProFile *proFileInfo) -{ - ui->addDesktopFileButton->setEnabled(canAddDesktopFile(proFileInfo)); - ui->addIconButton->setEnabled(canAddIcon(proFileInfo)); -} - -void MaemoDeployConfigurationWidget::addDesktopFile() -{ - DeployableFilesPerProFile * const proFileInfo = m_remoteLinuxWidget->currentModel(); - QTC_ASSERT(canAddDesktopFile(proFileInfo), return); - - const QString desktopFilePath = QFileInfo(proFileInfo->proFilePath()).path() - + QLatin1Char('/') + proFileInfo->projectName() + QLatin1String(".desktop"); - if (!QFile::exists(desktopFilePath)) { - const QString desktopTemplate = QLatin1String("[Desktop Entry]\nEncoding=UTF-8\n" - "Version=1.0\nType=Application\nTerminal=false\nName=%1\nExec=%2\n" - "Icon=%1\nX-Window-Icon=\nX-HildonDesk-ShowInToolbar=true\n" - "X-Osso-Type=application/x-executable\n"); - Utils::FileSaver saver(desktopFilePath); - saver.write(desktopTemplate.arg(proFileInfo->projectName(), - proFileInfo->remoteExecutableFilePath()).toUtf8()); - if (!saver.finalize(this)) - return; - } - - DeployableFile d; - d.remoteDir = QLatin1String("/usr/share/applications"); - Core::Id deviceType - = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(deployConfiguration()->target()->kit()); - if (deviceType == Maemo5OsType) - d.remoteDir += QLatin1String("/hildon"); - d.localFilePath = desktopFilePath; - if (!deployConfiguration()->deploymentSettingsAssistant() - ->addDeployableToProFile(deployConfiguration()->qmakeScope(), proFileInfo, - QLatin1String("desktopfile"), d)) { - QMessageBox::critical(this, tr("Project File Update Failed"), - tr("Could not update the project file.")); - } else { - ui->addDesktopFileButton->setEnabled(false); - } -} - -void MaemoDeployConfigurationWidget::addIcon() -{ - DeployableFilesPerProFile * const proFileInfo = m_remoteLinuxWidget->currentModel(); - const int iconDim - = MaemoGlobal::applicationIconSize(deployConfiguration()->target()); - const QString origFilePath = QFileDialog::getOpenFileName(this, - tr("Choose Icon (will be scaled to %1x%1 pixels, if necessary)").arg(iconDim), - proFileInfo->projectDir(), QLatin1String("(*.png)")); - if (origFilePath.isEmpty()) - return; - QPixmap pixmap(origFilePath); - if (pixmap.isNull()) { - QMessageBox::critical(this, tr("Invalid Icon"), - tr("Unable to read image")); - return; - } - const QSize iconSize(iconDim, iconDim); - if (pixmap.size() != iconSize) - pixmap = pixmap.scaled(iconSize); - const QString newFileName = proFileInfo->projectName() + QLatin1Char('.') - + QFileInfo(origFilePath).suffix(); - const QString newFilePath = proFileInfo->projectDir() + QLatin1Char('/') + newFileName; - if (!pixmap.save(newFilePath)) { - QMessageBox::critical(this, tr("Failed to Save Icon"), - tr("Could not save icon to '%1'.").arg(newFilePath)); - return; - } - - if (!deployConfiguration()->deploymentSettingsAssistant() - ->addDeployableToProFile(deployConfiguration()->qmakeScope(), proFileInfo, - QLatin1String("icon"), DeployableFile(newFilePath, remoteIconDir()))) { - QMessageBox::critical(this, tr("Project File Update Failed"), - tr("Could not update the project file.")); - } else { - ui->addIconButton->setEnabled(false); - } -} - -bool MaemoDeployConfigurationWidget::canAddDesktopFile(const DeployableFilesPerProFile *proFileInfo) const -{ - return proFileInfo && proFileInfo->isApplicationProject() - && deployConfiguration()->localDesktopFilePath(proFileInfo).isEmpty(); -} - -bool MaemoDeployConfigurationWidget::canAddIcon(const DeployableFilesPerProFile *proFileInfo) const -{ - return proFileInfo && proFileInfo->isApplicationProject() - && remoteIconFilePath(proFileInfo).isEmpty(); -} - -QString MaemoDeployConfigurationWidget::remoteIconFilePath(const DeployableFilesPerProFile *proFileInfo) const -{ - QTC_ASSERT(proFileInfo->projectType() == ApplicationTemplate, return QString()); - - const QStringList imageTypes = QStringList() << QLatin1String("jpg") << QLatin1String("png") - << QLatin1String("svg"); - for (int i = 0; i < proFileInfo->rowCount(); ++i) { - const DeployableFile &d = proFileInfo->deployableAt(i); - const QString extension = QFileInfo(d.localFilePath).suffix(); - if (d.remoteDir.startsWith(remoteIconDir()) && imageTypes.contains(extension)) - return d.remoteDir + QLatin1Char('/') + QFileInfo(d.localFilePath).fileName(); - } - return QString(); -} - -QString MaemoDeployConfigurationWidget::remoteIconDir() const -{ - return QString::fromLatin1("/usr/share/icons/hicolor/%1x%1/apps") - .arg(MaemoGlobal::applicationIconSize(deployConfiguration()->target())); -} - -} // namespace Internal -} // namespace Madde diff --git a/src/plugins/madde/maemodeployconfigurationwidget.ui b/src/plugins/madde/maemodeployconfigurationwidget.ui deleted file mode 100644 index 04f5b74fd9..0000000000 --- a/src/plugins/madde/maemodeployconfigurationwidget.ui +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>Madde::Internal::MaemoDeployConfigurationWidget</class> - <widget class="QWidget" name="Madde::Internal::MaemoDeployConfigurationWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>276</width> - <height>45</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="addDesktopFileButton"> - <property name="text"> - <string>Add Desktop File</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="addIconButton"> - <property name="text"> - <string>Add Launcher Icon...</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/madde/maemoglobal.cpp b/src/plugins/madde/maemoglobal.cpp index bc4dcb907c..eeac3d7f37 100644 --- a/src/plugins/madde/maemoglobal.cpp +++ b/src/plugins/madde/maemoglobal.cpp @@ -39,6 +39,7 @@ #include <qtsupport/qtkitinformation.h> #include <remotelinux/remotelinux_constants.h> #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <QDir> #include <QFileInfo> @@ -50,12 +51,11 @@ using namespace ProjectExplorer; using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Constants; using namespace RemoteLinux; +using namespace Utils; namespace Madde { namespace Internal { -namespace { -static const QLatin1String binQmake("/bin/qmake" EXEC_SUFFIX); -} // namespace +static const QString binQmake = QLatin1String("/bin/qmake" QTC_HOST_EXE_SUFFIX); bool MaemoGlobal::hasMaemoDevice(const Kit *k) { @@ -95,7 +95,7 @@ bool MaemoGlobal::isValidMaemoQtVersion(const QString &qmakePath, Core::Id devic return false; madAdminProc.setReadChannel(QProcess::StandardOutput); - const QByteArray tgtName = targetName(qmakePath).toAscii(); + const QByteArray tgtName = targetName(qmakePath).toLatin1(); while (madAdminProc.canReadLine()) { const QByteArray &line = madAdminProc.readLine(); if (line.contains(tgtName) @@ -140,16 +140,16 @@ QString MaemoGlobal::remoteSourceProfilesCommand() QByteArray remoteCall(":"); foreach (const QByteArray &profile, profiles) remoteCall += "; test -f " + profile + " && source " + profile; - return QString::fromAscii(remoteCall); + return QString::fromLatin1(remoteCall); } -Utils::PortList MaemoGlobal::freePorts(const Kit *k) +PortList MaemoGlobal::freePorts(const Kit *k) { IDevice::ConstPtr device = DeviceKitInformation::device(k); QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k); if (!device || !qtVersion) - return Utils::PortList(); + return PortList(); if (device->machineType() == IDevice::Emulator) { MaemoQemuRuntime rt; const int id = qtVersion->uniqueId(); @@ -166,19 +166,14 @@ QString MaemoGlobal::maddeRoot(const QString &qmakePath) return dir.absolutePath(); } -Utils::FileName MaemoGlobal::maddeRoot(const Kit *k) +FileName MaemoGlobal::maddeRoot(const Kit *k) { return SysRootKitInformation::sysRoot(k).parentDir().parentDir(); } QString MaemoGlobal::targetRoot(const QString &qmakePath) { -#ifdef Q_OS_WIN - Qt::CaseSensitivity cs = Qt::CaseInsensitive; -#else - Qt::CaseSensitivity cs = Qt::CaseSensitive; -#endif - return QDir::cleanPath(qmakePath).remove(binQmake, cs); + return QDir::cleanPath(qmakePath).remove(binQmake, HostOsInfo::fileNameCaseSensitivity()); } QString MaemoGlobal::targetName(const QString &qmakePath) @@ -226,32 +221,26 @@ QString MaemoGlobal::architecture(const QString &qmakePath) return arch; } -void MaemoGlobal::addMaddeEnvironment(Utils::Environment &env, const QString &qmakePath) +void MaemoGlobal::addMaddeEnvironment(Environment &env, const QString &qmakePath) { - Utils::Environment maddeEnv; -#ifdef Q_OS_WIN - const QString root = maddeRoot(qmakePath); - env.prependOrSetPath(root + QLatin1String("/bin")); - env.prependOrSet(QLatin1String("HOME"), - QDesktopServices::storageLocation(QDesktopServices::HomeLocation)); -#else - Q_UNUSED(qmakePath); -#endif - for (Utils::Environment::const_iterator it = maddeEnv.constBegin(); it != maddeEnv.constEnd(); ++it) + Environment maddeEnv; + if (HostOsInfo::isWindowsHost()) { + const QString root = maddeRoot(qmakePath); + env.prependOrSetPath(root + QLatin1String("/bin")); + env.prependOrSet(QLatin1String("HOME"), + QDesktopServices::storageLocation(QDesktopServices::HomeLocation)); + } + for (Environment::const_iterator it = maddeEnv.constBegin(); it != maddeEnv.constEnd(); ++it) env.prependOrSet(it.key(), it.value()); } void MaemoGlobal::transformMaddeCall(QString &command, QStringList &args, const QString &qmakePath) { -#ifdef Q_OS_WIN - const QString root = maddeRoot(qmakePath); - args.prepend(command); - command = root + QLatin1String("/bin/sh.exe"); -#else - Q_UNUSED(command); - Q_UNUSED(args); - Q_UNUSED(qmakePath); -#endif + if (HostOsInfo::isWindowsHost()) { + const QString root = maddeRoot(qmakePath); + args.prepend(command); + command = root + QLatin1String("/bin/sh.exe"); + } } bool MaemoGlobal::callMad(QProcess &proc, const QStringList &args, @@ -276,7 +265,7 @@ bool MaemoGlobal::callMaddeShellScript(QProcess &proc, return false; QString actualCommand = command; QStringList actualArgs = targetArgs(qmakePath, useTarget) + args; - Utils::Environment env(proc.systemEnvironment()); + Environment env(proc.systemEnvironment()); addMaddeEnvironment(env, qmakePath); proc.setEnvironment(env.toStringList()); transformMaddeCall(actualCommand, actualArgs, qmakePath); diff --git a/src/plugins/madde/maemoinstalltosysrootstep.cpp b/src/plugins/madde/maemoinstalltosysrootstep.cpp index 1c1d0699a4..885c5764a5 100644 --- a/src/plugins/madde/maemoinstalltosysrootstep.cpp +++ b/src/plugins/madde/maemoinstalltosysrootstep.cpp @@ -34,19 +34,19 @@ #include "maemopackagecreationstep.h" #include "maemoqtversion.h" -#include <utils/fileutils.h> +#include <projectexplorer/deploymentdata.h> #include <projectexplorer/target.h> #include <qt4projectmanager/qt4buildconfiguration.h> #include <qtsupport/baseqtversion.h> #include <qtsupport/qtkitinformation.h> -#include <remotelinux/deploymentinfo.h> #include <remotelinux/remotelinuxdeployconfiguration.h> +#include <utils/fileutils.h> #include <QDir> #include <QFileInfo> #include <QLatin1Char> +#include <QPointer> #include <QProcess> -#include <QWeakPointer> using namespace ProjectExplorer; using namespace Qt4ProjectManager; @@ -110,7 +110,7 @@ class MaemoCopyFilesToSysrootWidget : public BuildStepConfigWidget { Q_OBJECT public: - MaemoCopyFilesToSysrootWidget(const BuildStep *buildStep) + MaemoCopyFilesToSysrootWidget(BuildStep *buildStep) : m_buildStep(buildStep) { if (m_buildStep) { @@ -125,7 +125,7 @@ public: } virtual bool showWidget() const { return false; } private: - const QWeakPointer<const BuildStep> m_buildStep; + const QPointer<BuildStep> m_buildStep; }; @@ -264,8 +264,7 @@ MaemoCopyToSysrootStep::MaemoCopyToSysrootStep(BuildStepList *bsl, bool MaemoCopyToSysrootStep::init() { - const Qt4BuildConfiguration * const bc - = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration()); + const BuildConfiguration * const bc = target()->activeBuildConfiguration(); if (!bc) { addOutput(tr("Cannot copy to sysroot without build configuration."), ErrorMessageOutput); @@ -281,11 +280,7 @@ bool MaemoCopyToSysrootStep::init() } m_systemRoot = ProjectExplorer::SysRootKitInformation::sysRoot(target()->kit()).toString(); - const DeploymentInfo * const deploymentInfo - = static_cast<RemoteLinuxDeployConfiguration *>(deployConfiguration())->deploymentInfo(); - m_files.clear(); - for (int i = 0; i < deploymentInfo->deployableCount(); ++i) - m_files << deploymentInfo->deployableAt(i); + m_files = target()->deploymentData().allFiles(); return true; } @@ -297,14 +292,14 @@ void MaemoCopyToSysrootStep::run(QFutureInterface<bool> &fi) const QChar sep = QLatin1Char('/'); foreach (const DeployableFile &deployable, m_files) { - const QFileInfo localFileInfo(deployable.localFilePath); + const QFileInfo localFileInfo = deployable.localFilePath().toFileInfo(); const QString targetFilePath = m_systemRoot + sep - + deployable.remoteDir + sep + localFileInfo.fileName(); - sysrootDir.mkpath(deployable.remoteDir.mid(1)); + + deployable.remoteDirectory() + sep + localFileInfo.fileName(); + sysrootDir.mkpath(deployable.remoteDirectory().mid(1)); QString errorMsg; - Utils::FileUtils::removeRecursively(targetFilePath, &errorMsg); - if (!Utils::FileUtils::copyRecursively(deployable.localFilePath, - targetFilePath, &errorMsg)) { + Utils::FileUtils::removeRecursively(Utils::FileName::fromString(targetFilePath), &errorMsg); + if (!Utils::FileUtils::copyRecursively(deployable.localFilePath(), + Utils::FileName::fromString(targetFilePath), &errorMsg)) { emit addOutput(tr("Sysroot installation failed: %1\n" " Continuing anyway.").arg(errorMsg), ErrorMessageOutput); } diff --git a/src/plugins/madde/maemoinstalltosysrootstep.h b/src/plugins/madde/maemoinstalltosysrootstep.h index c712c6badf..cd79e31fd7 100644 --- a/src/plugins/madde/maemoinstalltosysrootstep.h +++ b/src/plugins/madde/maemoinstalltosysrootstep.h @@ -32,7 +32,7 @@ #include <projectexplorer/abstractprocessstep.h> #include <projectexplorer/buildstep.h> -#include <remotelinux/deployablefile.h> +#include <projectexplorer/deployablefile.h> #include <QStringList> @@ -104,7 +104,7 @@ public: static QString displayName(); private: QString m_systemRoot; - QList<RemoteLinux::DeployableFile> m_files; + QList<ProjectExplorer::DeployableFile> m_files; }; class MaemoMakeInstallToSysrootStep : public ProjectExplorer::AbstractProcessStep diff --git a/src/plugins/madde/maemopackagecreationstep.cpp b/src/plugins/madde/maemopackagecreationstep.cpp index 6bebd9a851..1fbb5491ed 100644 --- a/src/plugins/madde/maemopackagecreationstep.cpp +++ b/src/plugins/madde/maemopackagecreationstep.cpp @@ -42,6 +42,7 @@ #include <qtsupport/qtkitinformation.h> #include <utils/environment.h> #include <utils/fileutils.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDateTime> @@ -57,6 +58,7 @@ using ProjectExplorer::BuildStepList; using ProjectExplorer::BuildStepConfigWidget; using ProjectExplorer::Task; using namespace Qt4ProjectManager; +using namespace Utils; namespace Madde { namespace Internal { @@ -225,7 +227,7 @@ bool AbstractMaemoPackageCreationStep::callPackagingCommand(QProcess *proc, void AbstractMaemoPackageCreationStep::preparePackagingProcess(QProcess *proc, const Qt4BuildConfiguration *bc, const QString &workingDir) { - Utils::Environment env = bc->environment(); + Environment env = bc->environment(); if (bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild) { env.appendOrSet(QLatin1String("DEB_BUILD_OPTIONS"), QLatin1String("nostrip"), QLatin1String(" ")); @@ -329,12 +331,12 @@ bool MaemoDebianPackageCreationStep::createPackage(QProcess *buildProc, bool MaemoDebianPackageCreationStep::isMetaDataNewerThan(const QDateTime &packageDate) const { - const Utils::FileName debianPath = DebianManager::debianDirectory(target()); + const FileName debianPath = DebianManager::debianDirectory(target()); if (packageDate <= debianPath.toFileInfo().lastModified()) return true; const QStringList debianFiles = DebianManager::debianFiles(debianPath); foreach (const QString &debianFile, debianFiles) { - Utils::FileName absFilePath = debianPath; + FileName absFilePath = debianPath; absFilePath.appendPath(debianFile); if (packageDate <= absFilePath.toFileInfo().lastModified()) return true; @@ -351,7 +353,7 @@ void MaemoDebianPackageCreationStep::checkProjectName() "Debian packages.\nThey must only use lower-case letters, " "numbers, '-', '+' and '.'.\n""We will try to work around that, " "but you may experience problems."), - Utils::FileName(), -1, Core::Id(TASK_CATEGORY_BUILDSYSTEM))); + FileName(), -1, Core::Id(TASK_CATEGORY_BUILDSYSTEM))); } } @@ -370,7 +372,7 @@ bool MaemoDebianPackageCreationStep::copyDebianFiles(bool inSourceBuild) return false; } QString error; - if (!Utils::FileUtils::removeRecursively(debianDirPath, &error)) { + if (!FileUtils::removeRecursively(FileName::fromString(debianDirPath), &error)) { raiseError(tr("Packaging failed: Could not remove directory '%1': %2") .arg(debianDirPath, error)); return false; @@ -396,7 +398,7 @@ bool MaemoDebianPackageCreationStep::copyDebianFiles(bool inSourceBuild) } if (newFileName == DebianManager::packageName(DebianManager::debianDirectory(target())) + QLatin1String(".aegis")) { - Utils::FileReader reader; + FileReader reader; if (!reader.fetch(srcFile)) { raiseError(tr("Could not read manifest file '%1': %2.") .arg(QDir::toNativeSeparators(srcFile), reader.errorString())); @@ -436,9 +438,8 @@ bool MaemoDebianPackageCreationStep::copyDebianFiles(bool inSourceBuild) QString MaemoDebianPackageCreationStep::packagingCommand(const QString &maddeRoot, const QString &commandName) { QString perl; -#ifdef Q_OS_WIN - perl = maddeRoot + QLatin1String("/bin/perl.exe "); -#endif + if (HostOsInfo::isWindowsHost()) + perl = maddeRoot + QLatin1String("/bin/perl.exe "); return perl + maddeRoot + QLatin1String("/madbin/") + commandName; } @@ -457,7 +458,7 @@ void MaemoDebianPackageCreationStep::ensureShlibdeps(QByteArray &rulesContent) bool MaemoDebianPackageCreationStep::adaptRulesFile( const QString &templatePath, const QString &rulesFilePath) { - Utils::FileReader reader; + FileReader reader; if (!reader.fetch(templatePath)) { raiseError(reader.errorString()); return false; @@ -467,7 +468,7 @@ bool MaemoDebianPackageCreationStep::adaptRulesFile( if (!m_debugBuild) ensureShlibdeps(content); - Utils::FileSaver saver(rulesFilePath); + FileSaver saver(rulesFilePath); saver.write(content); if (!saver.finalize()) { raiseError(saver.errorString()); diff --git a/src/plugins/madde/maemopackagecreationwidget.cpp b/src/plugins/madde/maemopackagecreationwidget.cpp index e873095e85..2a2d88b932 100644 --- a/src/plugins/madde/maemopackagecreationwidget.cpp +++ b/src/plugins/madde/maemopackagecreationwidget.cpp @@ -188,7 +188,7 @@ void MaemoPackageCreationWidget::setPackageManagerIcon() QString imageFilter = tr("Images") + QLatin1String("( "); const QList<QByteArray> &imageTypes = QImageReader::supportedImageFormats(); foreach (const QByteArray &imageType, imageTypes) - imageFilter += "*." + QString::fromAscii(imageType) + QLatin1Char(' '); + imageFilter += "*." + QString::fromLatin1(imageType) + QLatin1Char(' '); imageFilter += QLatin1Char(')'); const QSize iconSize = MaddeDevice::packageManagerIconSize(deviceType); const QString iconFileName = QFileDialog::getOpenFileName(this, diff --git a/src/plugins/madde/maemopublisherfremantlefree.cpp b/src/plugins/madde/maemopublisherfremantlefree.cpp index b4308e9281..604fd0e195 100644 --- a/src/plugins/madde/maemopublisherfremantlefree.cpp +++ b/src/plugins/madde/maemopublisherfremantlefree.cpp @@ -42,8 +42,6 @@ #include <qt4projectmanager/qt4buildconfiguration.h> #include <qtsupport/baseqtversion.h> #include <qtsupport/qtkitinformation.h> -#include <remotelinux/deployablefilesperprofile.h> -#include <remotelinux/deploymentinfo.h> #include <utils/fileutils.h> #include <utils/qtcassert.h> #include <ssh/sshremoteprocessrunner.h> @@ -59,6 +57,7 @@ using namespace Core; using namespace Qt4ProjectManager; using namespace RemoteLinux; using namespace QSsh; +using namespace Utils; namespace Madde { namespace Internal { @@ -128,7 +127,7 @@ void MaemoPublisherFremantleFree::createPackage() if (QFileInfo(tmpDirContainer()).exists()) { emit progressReport(tr("Removing left-over temporary directory...")); QString error; - if (!Utils::FileUtils::removeRecursively(tmpDirContainer(), &error)) { + if (!FileUtils::removeRecursively(FileName::fromString(tmpDirContainer()), &error)) { finishWithFailure(tr("Error removing temporary directory: %1").arg(error), tr("Publishing failed: Could not create source package.")); return; @@ -152,13 +151,6 @@ void MaemoPublisherFremantleFree::createPackage() return; } - QString error; - if (!updateDesktopFiles(&error)) { - finishWithFailure(error, - tr("Publishing failed: Could not create package.")); - return; - } - emit progressReport(tr("Cleaning up temporary directory...")); AbstractMaemoPackageCreationStep::preparePackagingProcess(m_process, m_buildConfig, m_tmpProjectDir); @@ -209,7 +201,7 @@ bool MaemoPublisherFremantleFree::copyRecursively(const QString &srcFilePath, } } else { if (tgtFilePath == m_tmpProjectDir + QLatin1String("/debian/rules")) { - Utils::FileReader reader; + FileReader reader; if (!reader.fetch(srcFilePath)) { emit progressReport(reader.errorString(), ErrorOutput); return false; @@ -219,7 +211,7 @@ bool MaemoPublisherFremantleFree::copyRecursively(const QString &srcFilePath, rulesContents.replace("# Add here commands to configure the package.", "qmake " + QFileInfo(m_project->document()->fileName()).fileName().toLocal8Bit()); MaemoDebianPackageCreationStep::ensureShlibdeps(rulesContents); - Utils::FileSaver saver(tgtFilePath); + FileSaver saver(tgtFilePath); saver.write(rulesContents); if (!saver.finalize()) { emit progressReport(saver.errorString(), ErrorOutput); @@ -251,7 +243,7 @@ bool MaemoPublisherFremantleFree::fixNewlines() const QStringList &fileNames = debianDir.entryList(QDir::Files); foreach (const QString &fileName, fileNames) { QString filePath = debianDir.filePath(fileName); - Utils::FileReader reader; + FileReader reader; if (!reader.fetch(filePath)) return false; QByteArray contents = reader.data(); @@ -259,7 +251,7 @@ bool MaemoPublisherFremantleFree::fixNewlines() if (!contents.contains(crlf)) continue; contents.replace(crlf, "\n"); - Utils::FileSaver saver(filePath); + FileSaver saver(filePath); saver.write(contents); if (!saver.finalize()) return false; @@ -373,7 +365,7 @@ void MaemoPublisherFremantleFree::runDpkgBuildPackage() } foreach (const QString &filePath, d.filesToExclude()) { QString error; - if (!Utils::FileUtils::removeRecursively(filePath, &error)) { + if (!FileUtils::removeRecursively(FileName::fromString(filePath), &error)) { finishWithFailure(error, tr("Publishing failed: Could not create package.")); } @@ -541,65 +533,6 @@ void MaemoPublisherFremantleFree::finishWithFailure(const QString &progressMsg, setState(Inactive); } -bool MaemoPublisherFremantleFree::updateDesktopFiles(QString *error) const -{ - bool success = true; - const Qt4MaemoDeployConfiguration *const deployConfig - = qobject_cast<Qt4MaemoDeployConfiguration *>(m_buildConfig->target()->activeDeployConfiguration()); - QTC_ASSERT(deployConfig, return false); - const DeploymentInfo *const deploymentInfo = deployConfig->deploymentInfo(); - for (int i = 0; i < deploymentInfo->modelCount(); ++i) { - const DeployableFilesPerProFile * const model = deploymentInfo->modelAt(i); - QString desktopFilePath = deployConfig->localDesktopFilePath(model); - if (desktopFilePath.isEmpty()) - continue; - desktopFilePath.replace(model->projectDir(), m_tmpProjectDir); - const QString executableFilePath = model->remoteExecutableFilePath(); - if (executableFilePath.isEmpty()) { - qDebug("%s: Skipping subproject %s with missing deployment information.", - Q_FUNC_INFO, qPrintable(model->proFilePath())); - continue; - } - Utils::FileReader reader; - if (!reader.fetch(desktopFilePath, error)) { - success = false; - continue; - } - QByteArray desktopFileContents = reader.data(); - bool fileNeedsUpdate = addOrReplaceDesktopFileValue(desktopFileContents, - "Exec", executableFilePath.toUtf8()); - if (fileNeedsUpdate) { - Utils::FileSaver saver(desktopFilePath); - saver.write(desktopFileContents); - if (!saver.finalize(error)) - success = false; - } - } - return success; -} - -bool MaemoPublisherFremantleFree::addOrReplaceDesktopFileValue(QByteArray &fileContent, - const QByteArray &key, const QByteArray &newValue) const -{ - const int keyPos = fileContent.indexOf(key + '='); - if (keyPos == -1) { - if (!fileContent.endsWith('\n')) - fileContent += '\n'; - fileContent += key + '=' + newValue + '\n'; - return true; - } - int nextNewlinePos = fileContent.indexOf('\n', keyPos); - if (nextNewlinePos == -1) - nextNewlinePos = fileContent.count(); - const int replacePos = keyPos + key.count() + 1; - const int replaceCount = nextNewlinePos - replacePos; - const QByteArray &oldValue = fileContent.mid(replacePos, replaceCount); - if (oldValue == newValue) - return false; - fileContent.replace(replacePos, replaceCount, newValue); - return true; -} - QStringList MaemoPublisherFremantleFree::findProblems() const { QStringList problems; diff --git a/src/plugins/madde/maemopublisherfremantlefree.h b/src/plugins/madde/maemopublisherfremantlefree.h index f36ba3a8e0..b1b41d2581 100644 --- a/src/plugins/madde/maemopublisherfremantlefree.h +++ b/src/plugins/madde/maemopublisherfremantlefree.h @@ -104,9 +104,6 @@ private: void prepareToSendFile(); void sendFile(); void finishWithFailure(const QString &progressMsg, const QString &resultMsg); - bool updateDesktopFiles(QString *error = 0) const; - bool addOrReplaceDesktopFileValue(QByteArray &fileContent, - const QByteArray &key, const QByteArray &newValue) const; QStringList findProblems() const; const ProjectExplorer::Project * const m_project; diff --git a/src/plugins/madde/maemoqemuruntimeparser.cpp b/src/plugins/madde/maemoqemuruntimeparser.cpp index a7551d83cd..2d13b5b224 100644 --- a/src/plugins/madde/maemoqemuruntimeparser.cpp +++ b/src/plugins/madde/maemoqemuruntimeparser.cpp @@ -32,6 +32,7 @@ #include "maemoqemusettings.h" #include <qtsupport/baseqtversion.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDir> @@ -198,17 +199,17 @@ void MaemoQemuRuntimeParserV1::fillRuntimeInformation(MaemoQemuRuntime *runtime) // This is complex because of extreme MADDE weirdness. const QString root = m_maddeRoot + QLatin1Char('/'); const bool pathIsRelative = QFileInfo(runtime->m_bin).isRelative(); - runtime->m_bin = - #ifdef Q_OS_WIN - root + (pathIsRelative - ? QLatin1String("madlib/") + runtime->m_bin // Fremantle. - : runtime->m_bin) // Harmattan. - + QLatin1String(".exe"); - #else - pathIsRelative - ? root + QLatin1String("madlib/") + runtime->m_bin // Fremantle. - : runtime->m_bin; // Harmattan. - #endif + if (Utils::HostOsInfo::isWindowsHost()) { + runtime->m_bin = + root + (pathIsRelative + ? QLatin1String("madlib/") + runtime->m_bin // Fremantle. + : runtime->m_bin) // Harmattan. + + QLatin1String(".exe"); + } else { + runtime->m_bin = pathIsRelative + ? root + QLatin1String("madlib/") + runtime->m_bin // Fremantle. + : runtime->m_bin; // Harmattan. + } } } } @@ -335,17 +336,17 @@ void MaemoQemuRuntimeParserV2::handleEnvironmentTag(MaemoQemuRuntime &runtime) while (m_madInfoReader.readNextStartElement()) handleVariableTag(runtime); -#ifdef Q_OS_WIN - const QString root = QDir::toNativeSeparators(m_maddeRoot) - + QLatin1Char('/'); - const QLatin1Char colon(';'); - const QLatin1String key("PATH"); - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - runtime.m_normalVars << MaemoQemuRuntime::Variable(key, - root + QLatin1String("bin") + colon + env.value(key)); - runtime.m_normalVars << MaemoQemuRuntime::Variable(key, - root + QLatin1String("madlib") + colon + env.value(key)); -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + const QString root = QDir::toNativeSeparators(m_maddeRoot) + + QLatin1Char('/'); + const QLatin1Char colon(';'); + const QLatin1String key("PATH"); + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + runtime.m_normalVars << MaemoQemuRuntime::Variable(key, + root + QLatin1String("bin") + colon + env.value(key)); + runtime.m_normalVars << MaemoQemuRuntime::Variable(key, + root + QLatin1String("madlib") + colon + env.value(key)); + } } void MaemoQemuRuntimeParserV2::handleVariableTag(MaemoQemuRuntime &runtime) diff --git a/src/plugins/madde/maemoqtversion.cpp b/src/plugins/madde/maemoqtversion.cpp index f79197a41d..f65d5c3ddd 100644 --- a/src/plugins/madde/maemoqtversion.cpp +++ b/src/plugins/madde/maemoqtversion.cpp @@ -34,6 +34,7 @@ #include <projectexplorer/kitinformation.h> #include <qt4projectmanager/qt4projectmanagerconstants.h> #include <qtsupport/qtsupportconstants.h> +#include <utils/hostosinfo.h> #include <QCoreApplication> #include <QFile> @@ -124,10 +125,7 @@ QString MaemoQtVersion::description() const bool MaemoQtVersion::supportsShadowBuilds() const { -#ifdef Q_OS_WIN - return false; -#endif - return true; + return !Utils::HostOsInfo::isWindowsHost(); } Core::Id MaemoQtVersion::deviceType() const diff --git a/src/plugins/madde/maemoremotecopyfacility.cpp b/src/plugins/madde/maemoremotecopyfacility.cpp index 71bf3cfdef..945ed62b52 100644 --- a/src/plugins/madde/maemoremotecopyfacility.cpp +++ b/src/plugins/madde/maemoremotecopyfacility.cpp @@ -32,12 +32,12 @@ #include <ssh/sshconnection.h> #include <ssh/sshremoteprocessrunner.h> +#include <utils/hostosinfo.h> #include <QDir> using namespace ProjectExplorer; using namespace QSsh; -using namespace RemoteLinux; namespace Madde { namespace Internal { @@ -124,19 +124,19 @@ void MaemoRemoteCopyFacility::copyNextFile() const DeployableFile &d = m_deployables.first(); QString sourceFilePath = m_mountPoint; -#ifdef Q_OS_WIN - const QString localFilePath = QDir::fromNativeSeparators(d.localFilePath); - sourceFilePath += QLatin1Char('/') + localFilePath.at(0).toLower() - + localFilePath.mid(2); -#else - sourceFilePath += d.localFilePath; -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + const QString localFilePath = QDir::fromNativeSeparators(d.localFilePath().toString()); + sourceFilePath += QLatin1Char('/') + localFilePath.at(0).toLower() + + localFilePath.mid(2); + } else { + sourceFilePath += d.localFilePath().toString(); + } QString command = QString::fromLatin1("%1 mkdir -p %3 && %1 cp -a %2 %3") .arg(MaemoGlobal::remoteSudo(m_devConf->type(), m_devConf->sshParameters().userName), - sourceFilePath, d.remoteDir); + sourceFilePath, d.remoteDirectory()); emit progress(tr("Copying file '%1' to directory '%2' on the device...") - .arg(d.localFilePath, d.remoteDir)); + .arg(d.localFilePath().toString(), d.remoteDirectory())); m_copyRunner->run(command.toUtf8(), m_devConf->sshParameters()); } diff --git a/src/plugins/madde/maemoremotecopyfacility.h b/src/plugins/madde/maemoremotecopyfacility.h index 15d1d66ef7..ceabe8eeba 100644 --- a/src/plugins/madde/maemoremotecopyfacility.h +++ b/src/plugins/madde/maemoremotecopyfacility.h @@ -30,7 +30,7 @@ #ifndef MAEMOREMOTECOPYFACILITY_H #define MAEMOREMOTECOPYFACILITY_H -#include <remotelinux/deployablefile.h> +#include <projectexplorer/deployablefile.h> #include <projectexplorer/devicesupport/idevice.h> #include <QList> @@ -53,14 +53,14 @@ public: void copyFiles(QSsh::SshConnection *connection, const ProjectExplorer::IDevice::ConstPtr &device, - const QList<RemoteLinux::DeployableFile> &deployables, const QString &mountPoint); + const QList<ProjectExplorer::DeployableFile> &deployables, const QString &mountPoint); void cancel(); signals: void stdoutData(const QString &output); void stderrData(const QString &output); void progress(const QString &message); - void fileCopied(const RemoteLinux::DeployableFile &deployable); + void fileCopied(const ProjectExplorer::DeployableFile &deployable); void finished(const QString &errorMsg = QString()); private slots: @@ -76,7 +76,7 @@ private: QSsh::SshRemoteProcessRunner *m_copyRunner; QSsh::SshRemoteProcessRunner *m_killProcess; ProjectExplorer::IDevice::ConstPtr m_devConf; - QList<RemoteLinux::DeployableFile> m_deployables; + QList<ProjectExplorer::DeployableFile> m_deployables; QString m_mountPoint; bool m_isCopying; // TODO: Redundant due to being in sync with m_copyRunner? }; diff --git a/src/plugins/madde/maemorunconfiguration.h b/src/plugins/madde/maemorunconfiguration.h index eab18edd76..59c6660f94 100644 --- a/src/plugins/madde/maemorunconfiguration.h +++ b/src/plugins/madde/maemorunconfiguration.h @@ -40,7 +40,8 @@ class MaemoRunConfiguration : public RemoteLinux::RemoteLinuxRunConfiguration Q_OBJECT public: - MaemoRunConfiguration(ProjectExplorer::Target *parent, Core::Id id, const QString &proFilePath); + MaemoRunConfiguration(ProjectExplorer::Target *parent, Core::Id id, + const QString &projectFilePath); MaemoRunConfiguration(ProjectExplorer::Target *parent, MaemoRunConfiguration *source); QVariantMap toMap() const; diff --git a/src/plugins/madde/maemorunfactories.cpp b/src/plugins/madde/maemorunfactories.cpp index 8b451113be..c21855a652 100644 --- a/src/plugins/madde/maemorunfactories.cpp +++ b/src/plugins/madde/maemorunfactories.cpp @@ -110,7 +110,8 @@ bool MaemoRunConfigurationFactory::canClone(Target *parent, return false; const RemoteLinuxRunConfiguration * const rlrc = qobject_cast<RemoteLinuxRunConfiguration *>(source); - QString idStr = QString::fromLatin1(source->id().name()) + QLatin1Char('.') + rlrc->proFilePath(); + QString idStr = QString::fromLatin1(source->id().name()) + QLatin1Char('.') + + rlrc->projectFilePath(); return rlrc && canCreate(parent, Core::Id(idStr)); } @@ -178,7 +179,7 @@ QList<RunConfiguration *> MaemoRunConfigurationFactory::runConfigurationsForNode QList<ProjectExplorer::RunConfiguration *> result; foreach (ProjectExplorer::RunConfiguration *rc, t->runConfigurations()) if (MaemoRunConfiguration *mrc = qobject_cast<MaemoRunConfiguration *>(rc)) - if (mrc->proFilePath() == n->path()) + if (mrc->projectFilePath() == n->path()) result << rc; return result; } diff --git a/src/plugins/madde/qt4maemodeployconfiguration.cpp b/src/plugins/madde/qt4maemodeployconfiguration.cpp index 90dfa29438..809479c25e 100644 --- a/src/plugins/madde/qt4maemodeployconfiguration.cpp +++ b/src/plugins/madde/qt4maemodeployconfiguration.cpp @@ -33,23 +33,21 @@ #include "maddeuploadandinstallpackagesteps.h" #include "maemoconstants.h" #include "maemodeploybymountsteps.h" -#include "maemodeployconfigurationwidget.h" #include "maemoglobal.h" #include "maemoinstalltosysrootstep.h" #include "maemopackagecreationstep.h" #include <coreplugin/icore.h> #include <projectexplorer/buildsteplist.h> +#include <projectexplorer/deployablefile.h> #include <projectexplorer/target.h> #include <projectexplorer/projectexplorer.h> #include <qt4projectmanager/qt4buildconfiguration.h> #include <qt4projectmanager/qt4project.h> #include <qtsupport/qtkitinformation.h> #include <qtsupport/qtsupportconstants.h> -#include <remotelinux/deployablefile.h> -#include <remotelinux/deployablefilesperprofile.h> -#include <remotelinux/deploymentinfo.h> #include <remotelinux/remotelinuxcheckforfreediskspacestep.h> +#include <remotelinux/remotelinuxdeployconfigurationwidget.h> #include <utils/qtcassert.h> #include <QFileInfo> @@ -62,38 +60,27 @@ using namespace ProjectExplorer; using namespace Qt4ProjectManager; using namespace RemoteLinux; -const char OldDeployConfigId[] = "2.2MaemoDeployConfig"; -const char DEPLOYMENT_ASSISTANT_SETTING[] = "RemoteLinux.DeploymentAssistant"; - namespace Madde { namespace Internal { Qt4MaemoDeployConfiguration::Qt4MaemoDeployConfiguration(ProjectExplorer::Target *target, const Core::Id id, const QString &displayName) : RemoteLinuxDeployConfiguration(target, id, displayName) -{ init(); } +{ + init(); +} Qt4MaemoDeployConfiguration::Qt4MaemoDeployConfiguration(ProjectExplorer::Target *target, Qt4MaemoDeployConfiguration *source) : RemoteLinuxDeployConfiguration(target, source) -{ init(); } - -QString Qt4MaemoDeployConfiguration::localDesktopFilePath(const DeployableFilesPerProFile *proFileInfo) const { - QTC_ASSERT(proFileInfo->projectType() == ApplicationTemplate, return QString()); - - for (int i = 0; i < proFileInfo->rowCount(); ++i) { - const DeployableFile &d = proFileInfo->deployableAt(i); - if (QFileInfo(d.localFilePath).fileName().endsWith(QLatin1String(".desktop"))) - return d.localFilePath; - } - return QString(); + init(); + cloneSteps(source); } - -DeployConfigurationWidget *Qt4MaemoDeployConfiguration::configurationWidget() const +NamedWidget *Qt4MaemoDeployConfiguration::createConfigWidget() { - return new MaemoDeployConfigurationWidget; + return new RemoteLinuxDeployConfigurationWidget(this); } Qt4MaemoDeployConfiguration::~Qt4MaemoDeployConfiguration() {} @@ -113,33 +100,6 @@ Core::Id Qt4MaemoDeployConfiguration::harmattanId() return Core::Id("DeployToHarmattan"); } -DeploymentSettingsAssistant *Qt4MaemoDeployConfiguration::deploymentSettingsAssistant() -{ - return static_cast<DeploymentSettingsAssistant *>(target()->project()->namedSettings(QLatin1String(DEPLOYMENT_ASSISTANT_SETTING)).value<QObject *>()); -} - -QString Qt4MaemoDeployConfiguration::qmakeScope() const -{ - Core::Id deviceType = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(target()->kit()); - - if (deviceType == Maemo5OsType) - return QLatin1String("maemo5"); - if (deviceType == HarmattanOsType) - return QLatin1String("contains(MEEGO_EDITION,harmattan)"); - return QString("unix"); -} - -QString Qt4MaemoDeployConfiguration::installPrefix() const -{ - Core::Id deviceType = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(target()->kit()); - - if (deviceType == Maemo5OsType) - return QLatin1String("/opt"); - if (deviceType == HarmattanOsType) - return QLatin1String("/opt"); - return QLatin1String("/usr/local"); -} - void Qt4MaemoDeployConfiguration::debianDirChanged(const Utils::FileName &dir) { if (dir == DebianManager::debianDirectory(target())) @@ -246,15 +206,6 @@ void Qt4MaemoDeployConfiguration::addFilesToProject(const QStringList &files) void Qt4MaemoDeployConfiguration::init() { - // Make sure we have deploymentInfo, but create it only once: - DeploymentSettingsAssistant *assistant - = qobject_cast<DeploymentSettingsAssistant *>(target()->project()->namedSettings(QLatin1String(DEPLOYMENT_ASSISTANT_SETTING)).value<QObject *>()); - if (!assistant) { - assistant = new DeploymentSettingsAssistant(deploymentInfo(), static_cast<Qt4ProjectManager::Qt4Project *>(target()->project())); - QVariant data = QVariant::fromValue(static_cast<QObject *>(assistant)); - target()->project()->setNamedSettings(QLatin1String(DEPLOYMENT_ASSISTANT_SETTING), data); - } - connect(target()->project(), SIGNAL(fileListChanged()), this, SLOT(setupPackaging())); } @@ -327,25 +278,16 @@ DeployConfiguration *Qt4MaemoDeployConfigurationFactory::create(Target *parent, bool Qt4MaemoDeployConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const { Core::Id id = idFromMap(map); - return canHandle(parent) - && (availableCreationIds(parent).contains(id) || id == OldDeployConfigId) + return canHandle(parent) && availableCreationIds(parent).contains(id) && MaemoGlobal::supportsMaemoDevice(parent->kit()); } DeployConfiguration *Qt4MaemoDeployConfigurationFactory::restore(Target *parent, const QVariantMap &map) { - if (!canRestore(parent, map)) - return 0; - Core::Id id = idFromMap(map); - Core::Id deviceType = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(parent->kit()); - if (id == OldDeployConfigId) { - if (deviceType == Maemo5OsType) - id = Qt4MaemoDeployConfiguration::fremantleWithPackagingId(); - else if (deviceType == HarmattanOsType) - id = Qt4MaemoDeployConfiguration::harmattanId(); - } + QTC_ASSERT(canRestore(parent, map), return 0); + Qt4MaemoDeployConfiguration * const dc - = qobject_cast<Qt4MaemoDeployConfiguration *>(create(parent, id)); + = qobject_cast<Qt4MaemoDeployConfiguration *>(create(parent, idFromMap(map))); if (!dc->fromMap(map)) { delete dc; return 0; diff --git a/src/plugins/madde/qt4maemodeployconfiguration.h b/src/plugins/madde/qt4maemodeployconfiguration.h index 56b56fe35b..989536e392 100644 --- a/src/plugins/madde/qt4maemodeployconfiguration.h +++ b/src/plugins/madde/qt4maemodeployconfiguration.h @@ -30,15 +30,9 @@ #ifndef QT4PROJECTMANAGER_QT4DEPLOYCONFIGURATION_H #define QT4PROJECTMANAGER_QT4DEPLOYCONFIGURATION_H -#include <remotelinux/deploymentsettingsassistant.h> #include <remotelinux/remotelinuxdeployconfiguration.h> #include <utils/fileutils.h> -namespace RemoteLinux { -class DeployableFilesPerProFile; -class DeploymentSettingsAssistant; -} // namespace RemoteLinux - namespace Madde { namespace Internal { @@ -68,19 +62,12 @@ class Qt4MaemoDeployConfiguration : public RemoteLinux::RemoteLinuxDeployConfigu public: ~Qt4MaemoDeployConfiguration(); - ProjectExplorer::DeployConfigurationWidget *configurationWidget() const; - - QString localDesktopFilePath(const RemoteLinux::DeployableFilesPerProFile *proFileInfo) const; + ProjectExplorer::NamedWidget *createConfigWidget(); static Core::Id fremantleWithPackagingId(); static Core::Id fremantleWithoutPackagingId(); static Core::Id harmattanId(); - RemoteLinux::DeploymentSettingsAssistant *deploymentSettingsAssistant(); - - QString qmakeScope() const; - QString installPrefix() const; - private slots: void debianDirChanged(const Utils::FileName &dir); void setupPackaging(); diff --git a/src/plugins/mercurial/mercurial.qbs b/src/plugins/mercurial/mercurial.qbs index 3875ddd979..fcf9752e5f 100644 --- a/src/plugins/mercurial/mercurial.qbs +++ b/src/plugins/mercurial/mercurial.qbs @@ -12,46 +12,38 @@ QtcPlugin { Depends { name: "VcsBase" } Depends { name: "Locator" } - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ - "mercurialplugin.cpp", - "optionspage.cpp", - "mercurialcontrol.cpp", - "mercurialclient.cpp", "annotationhighlighter.cpp", - "mercurialeditor.cpp", - "revertdialog.cpp", - "srcdestdialog.cpp", - "mercurialcommitwidget.cpp", - "commiteditor.cpp", - "clonewizardpage.cpp", + "annotationhighlighter.h", "clonewizard.cpp", - "mercurialsettings.cpp", - "mercurialplugin.h", + "clonewizard.h", + "clonewizardpage.cpp", + "clonewizardpage.h", + "commiteditor.cpp", + "commiteditor.h", "constants.h", - "optionspage.h", - "mercurialcontrol.h", + "mercurial.qrc", + "mercurialclient.cpp", "mercurialclient.h", - "annotationhighlighter.h", - "mercurialeditor.h", - "revertdialog.h", - "srcdestdialog.h", + "mercurialcommitpanel.ui", + "mercurialcommitwidget.cpp", "mercurialcommitwidget.h", - "commiteditor.h", - "clonewizardpage.h", - "clonewizard.h", + "mercurialcontrol.cpp", + "mercurialcontrol.h", + "mercurialeditor.cpp", + "mercurialeditor.h", + "mercurialplugin.cpp", + "mercurialplugin.h", + "mercurialsettings.cpp", "mercurialsettings.h", + "optionspage.cpp", + "optionspage.h", "optionspage.ui", + "revertdialog.cpp", + "revertdialog.h", "revertdialog.ui", + "srcdestdialog.cpp", + "srcdestdialog.h", "srcdestdialog.ui", - "mercurialcommitpanel.ui", - "mercurial.qrc" ] } - diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp index 2c53982323..cc6bf5ee59 100644 --- a/src/plugins/mercurial/mercurialcontrol.cpp +++ b/src/plugins/mercurial/mercurialcontrol.cpp @@ -52,7 +52,7 @@ QString MercurialControl::displayName() const Core::Id MercurialControl::id() const { - return VcsBase::Constants::VCS_ID_MERCURIAL; + return Core::Id(VcsBase::Constants::VCS_ID_MERCURIAL); } bool MercurialControl::managesDirectory(const QString &directory, QString *topLevel) const diff --git a/src/plugins/perforce/perforce.qbs b/src/plugins/perforce/perforce.qbs index 9c4c3d881b..ee31c90959 100644 --- a/src/plugins/perforce/perforce.qbs +++ b/src/plugins/perforce/perforce.qbs @@ -12,42 +12,34 @@ QtcPlugin { Depends { name: "VcsBase" } Depends { name: "Locator" } - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ - "perforceplugin.h", - "perforcechecker.h", - "settingspage.h", - "perforceeditor.h", + "annotationhighlighter.cpp", + "annotationhighlighter.h", + "changenumberdialog.cpp", "changenumberdialog.h", - "perforcesubmiteditor.h", + "changenumberdialog.ui", + "pendingchangesdialog.cpp", "pendingchangesdialog.h", - "perforceconstants.h", - "perforceversioncontrol.h", - "perforcesettings.h", - "annotationhighlighter.h", - "perforcesubmiteditorwidget.h", - "perforceplugin.cpp", + "pendingchangesdialog.ui", + "perforce.qrc", "perforcechecker.cpp", - "settingspage.cpp", + "perforcechecker.h", + "perforceconstants.h", "perforceeditor.cpp", - "changenumberdialog.cpp", - "perforcesubmiteditor.cpp", - "pendingchangesdialog.cpp", - "perforceversioncontrol.cpp", + "perforceeditor.h", + "perforceplugin.cpp", + "perforceplugin.h", "perforcesettings.cpp", - "annotationhighlighter.cpp", + "perforcesettings.h", + "perforcesubmiteditor.cpp", + "perforcesubmiteditor.h", "perforcesubmiteditorwidget.cpp", + "perforcesubmiteditorwidget.h", + "perforceversioncontrol.cpp", + "perforceversioncontrol.h", + "settingspage.cpp", + "settingspage.h", "settingspage.ui", - "changenumberdialog.ui", - "pendingchangesdialog.ui", "submitpanel.ui", - "perforce.qrc" ] } - diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 3d7ca3d410..ae2b178140 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -108,7 +108,7 @@ static inline const VcsBase::VcsBaseEditorParameters *findType(int ie) static inline QString debugCodec(const QTextCodec *c) { - return c ? QString::fromAscii(c->name()) : QString::fromAscii("Null codec"); + return c ? QString::fromLatin1(c->name()) : QString::fromLatin1("Null codec"); } // Ensure adding "..." to relative paths which is p4's convention @@ -623,7 +623,7 @@ void PerforcePlugin::startSubmitProject() Utils::TempFileSaver saver; saver.setAutoRemove(false); - saver.write(result.stdOut.toAscii()); + saver.write(result.stdOut.toLatin1()); if (!saver.finalize()) { VcsBase::VcsBaseOutputWindow::instance()->appendError(saver.errorString()); cleanCommitMessageFile(); @@ -1172,7 +1172,7 @@ Core::IEditor *PerforcePlugin::showOutputInEditor(const QString &title, const QS { const VcsBase::VcsBaseEditorParameters *params = findType(editorType); QTC_ASSERT(params, return 0); - const Core::Id id(params->id); + const Core::Id id = Core::Id(QByteArray(params->id)); if (Perforce::Constants::debug) qDebug() << "PerforcePlugin::showOutputInEditor" << title << id.name() << "Size= " << output.size() << " Type=" << editorType << debugCodec(codec); diff --git a/src/plugins/perforce/perforcesettings.cpp b/src/plugins/perforce/perforcesettings.cpp index afe00cec9a..acb5438e45 100644 --- a/src/plugins/perforce/perforcesettings.cpp +++ b/src/plugins/perforce/perforcesettings.cpp @@ -33,6 +33,7 @@ #include <utils/qtcassert.h> #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <QDebug> #include <QSettings> @@ -56,12 +57,7 @@ enum { defaultTimeOutS = 30, defaultLogCount = 1000 }; static QString defaultCommand() { - QString rc; - rc = QLatin1String("p4"); -#if defined(Q_OS_WIN32) - rc.append(QLatin1String(".exe")); -#endif - return rc; + return QLatin1String("p4" QTC_HOST_EXE_SUFFIX); } namespace Perforce { diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp index 9de9032701..a88ea30475 100644 --- a/src/plugins/perforce/perforceversioncontrol.cpp +++ b/src/plugins/perforce/perforceversioncontrol.cpp @@ -52,7 +52,7 @@ QString PerforceVersionControl::displayName() const Core::Id PerforceVersionControl::id() const { - return VcsBase::Constants::VCS_ID_PERFORCE; + return Core::Id(VcsBase::Constants::VCS_ID_PERFORCE); } bool PerforceVersionControl::isConfigured() const diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 7e6268b708..db3e70459d 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -163,7 +163,7 @@ plugin_remotelinux.subdir = remotelinux plugin_remotelinux.depends += plugin_coreplugin plugin_remotelinux.depends += plugin_debugger plugin_remotelinux.depends += plugin_projectexplorer -plugin_remotelinux.depends += plugin_qt4projectmanager +plugin_remotelinux.depends += plugin_qtsupport plugin_android.subdir = android plugin_android.depends = plugin_coreplugin @@ -173,6 +173,7 @@ plugin_android.depends += plugin_qt4projectmanager plugin_madde.subdir = madde plugin_madde.depends += plugin_remotelinux +plugin_madde.depends += plugin_qt4projectmanager plugin_locator.subdir = locator plugin_locator.depends = plugin_coreplugin diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp index 223f211034..af2d77c949 100644 --- a/src/plugins/projectexplorer/abi.cpp +++ b/src/plugins/projectexplorer/abi.cpp @@ -697,7 +697,7 @@ QList<Abi> Abi::abisOfBinary(const Utils::FileName &path) quint64 fileNameOffset = 0; if (fileName.startsWith(QLatin1String("#1/"))) fileNameOffset = fileName.mid(3).toInt(); - const QString fileLength = QString::fromAscii(data.mid(48, 10)); + const QString fileLength = QString::fromLatin1(data.mid(48, 10)); int toSkip = 60 + fileNameOffset; offset += fileLength.toInt() + 60 /* header */; diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp index bd23cb8fe4..7e38bae943 100644 --- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp +++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp @@ -105,8 +105,9 @@ ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList } } -QList<HeaderPath> AbstractMsvcToolChain::systemHeaderPaths(const Utils::FileName &sysRoot) const +QList<HeaderPath> AbstractMsvcToolChain::systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const { + Q_UNUSED(cxxflags); Q_UNUSED(sysRoot); if (m_headerPaths.isEmpty()) { Utils::Environment env(m_lastEnvironment); @@ -212,9 +213,8 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env, call += ' '; call += batchArgs.toLocal8Bit(); } - call += "\r\n"; + saver.write(call + "\r\n"); - saver.write(call); const QByteArray redirect = "set > " + Utils::QtcProcess::quoteArg( QDir::toNativeSeparators(tempOutFile)).toLocal8Bit() + "\r\n"; saver.write(redirect); @@ -250,6 +250,10 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env, Utils::SynchronousProcess::stopProcess(run); return false; } + // The SDK/MSVC scripts do not return exit codes != 0. Check on stdout. + const QByteArray stdOut = run.readAllStandardOutput(); + if (!stdOut.isEmpty() && (stdOut.contains("Unknown") || stdOut.contains("Error"))) + qWarning("%s: '%s' reports:\n%s", Q_FUNC_INFO, call.constData(), stdOut.constData()); // // Now parse the file to get the environment settings diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h index 44ee1b4af1..4c36422734 100644 --- a/src/plugins/projectexplorer/abstractmsvctoolchain.h +++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h @@ -50,7 +50,7 @@ public: QByteArray predefinedMacros(const QStringList &cxxflags) const; CompilerFlags compilerFlags(const QStringList &cxxflags) const; - QList<HeaderPath> systemHeaderPaths(const Utils::FileName &sysRoot) const; + QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const; void addToEnvironment(Utils::Environment &env) const; QString makeCommand(const Utils::Environment &environment) const; diff --git a/src/plugins/projectexplorer/applicationlauncher.cpp b/src/plugins/projectexplorer/applicationlauncher.cpp index ddeca1614e..849c16c592 100644 --- a/src/plugins/projectexplorer/applicationlauncher.cpp +++ b/src/plugins/projectexplorer/applicationlauncher.cpp @@ -28,13 +28,13 @@ ****************************************************************************/ #include "applicationlauncher.h" -#include "consoleprocess.h" #ifdef Q_OS_WIN #include "windebuginterface.h" #endif #include <coreplugin/icore.h> +#include <utils/consoleprocess.h> #include <utils/qtcprocess.h> #ifdef Q_OS_WIN #include <utils/winutils.h> diff --git a/src/plugins/projectexplorer/applicationrunconfiguration.cpp b/src/plugins/projectexplorer/applicationrunconfiguration.cpp index f0c336fe66..d67358ce66 100644 --- a/src/plugins/projectexplorer/applicationrunconfiguration.cpp +++ b/src/plugins/projectexplorer/applicationrunconfiguration.cpp @@ -52,26 +52,11 @@ LocalApplicationRunConfiguration::~LocalApplicationRunConfiguration() { } -namespace Internal { - -class VarManMacroExpander : public Utils::AbstractQtcMacroExpander { -public: - virtual bool resolveMacro(const QString &name, QString *ret) - { - *ret = Core::VariableManager::instance()->value(name.toUtf8()); - return !ret->isEmpty(); - } -}; - -} // namespace Internal - Utils::AbstractMacroExpander *LocalApplicationRunConfiguration::macroExpander() const { if (BuildConfiguration *bc = activeBuildConfiguration()) return bc->macroExpander(); - - static Internal::VarManMacroExpander mx; - return &mx; + return Core::VariableManager::instance()->macroExpander(); } } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index cc628233bd..660d9ad9fc 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -39,6 +39,7 @@ #include "kit.h" #include <coreplugin/variablemanager.h> +#include <projectexplorer/buildenvironmentwidget.h> #include <extensionsystem/pluginmanager.h> #include <utils/qtcassert.h> @@ -92,8 +93,8 @@ BuildConfiguration::BuildConfiguration(Target *target, const Core::Id id) : bsl->setDefaultDisplayName(tr("Clean")); m_stepLists.append(bsl); - connect(KitManager::instance(), SIGNAL(kitUpdated(ProjectExplorer::Kit*)), - this, SLOT(handleKitUpdate(ProjectExplorer::Kit*))); + connect(target, SIGNAL(kitChanged()), + this, SLOT(handleKitUpdate())); } BuildConfiguration::BuildConfiguration(Target *target, BuildConfiguration *source) : @@ -107,8 +108,8 @@ BuildConfiguration::BuildConfiguration(Target *target, BuildConfiguration *sourc // otherwise BuildStepFactories might reject to set up a BuildStep for us // since we are not yet the derived class! - connect(KitManager::instance(), SIGNAL(kitUpdated(ProjectExplorer::Kit*)), - this, SLOT(handleKitUpdate(ProjectExplorer::Kit*))); + connect(target, SIGNAL(kitChanged()), + this, SLOT(handleKitUpdate())); } BuildConfiguration::~BuildConfiguration() @@ -116,6 +117,11 @@ BuildConfiguration::~BuildConfiguration() delete m_macroExpander; } +QList<NamedWidget *> BuildConfiguration::createSubConfigWidgets() +{ + return QList<NamedWidget *>() << new ProjectExplorer::BuildEnvironmentWidget(this); +} + Utils::AbstractMacroExpander *BuildConfiguration::macroExpander() { if (!m_macroExpander) @@ -157,6 +163,8 @@ bool BuildConfiguration::fromMap(const QVariantMap &map) m_clearSystemEnvironment = map.value(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY)).toBool(); m_userEnvironmentChanges = Utils::EnvironmentItem::fromStringList(map.value(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY)).toStringList()); + m_lastEnvironment = environment(); + qDeleteAll(m_stepLists); m_stepLists.clear(); @@ -187,11 +195,18 @@ bool BuildConfiguration::fromMap(const QVariantMap &map) return ProjectConfiguration::fromMap(map); } -void BuildConfiguration::handleKitUpdate(ProjectExplorer::Kit *k) +void BuildConfiguration::emitEnvironmentChanged() { - if (k != target()->kit()) - return; - emit environmentChanged(); + Utils::Environment env = environment(); + if (env == m_lastEnvironment) + return; + m_lastEnvironment = env; + emit environmentChanged(); +} + +void BuildConfiguration::handleKitUpdate() +{ + emitEnvironmentChanged(); } Target *BuildConfiguration::target() const @@ -228,7 +243,7 @@ void BuildConfiguration::setUseSystemEnvironment(bool b) if (useSystemEnvironment() == b) return; m_clearSystemEnvironment = !b; - emit environmentChanged(); + emitEnvironmentChanged(); } bool BuildConfiguration::useSystemEnvironment() const @@ -246,7 +261,7 @@ void BuildConfiguration::setUserEnvironmentChanges(const QList<Utils::Environmen if (m_userEnvironmentChanges == diff) return; m_userEnvironmentChanges = diff; - emit environmentChanged(); + emitEnvironmentChanged(); } void BuildConfiguration::cloneSteps(BuildConfiguration *source) @@ -283,6 +298,7 @@ IBuildConfigurationFactory::IBuildConfigurationFactory(QObject *parent) : IBuildConfigurationFactory::~IBuildConfigurationFactory() { } +// restore IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, const QVariantMap &map) { QList<IBuildConfigurationFactory *> factories @@ -294,6 +310,7 @@ IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, con return 0; } +// create IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent) { QList<IBuildConfigurationFactory *> factories @@ -305,4 +322,15 @@ IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent) return 0; } +// clone +IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, BuildConfiguration *bc) +{ + QList<IBuildConfigurationFactory *> factories + = ExtensionSystem::PluginManager::instance()->getObjects<IBuildConfigurationFactory>(); + foreach (IBuildConfigurationFactory *factory, factories) { + if (factory->canClone(parent, bc)) + return factory; + } + return 0; +} } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index 981d72b13c..50f6f5baaa 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -44,7 +44,7 @@ class AbstractMacroExpander; namespace ProjectExplorer { class BuildConfiguration; -class BuildConfigWidget; +class NamedWidget; class BuildStepList; class Kit; class Target; @@ -60,10 +60,11 @@ public: virtual QString buildDirectory() const = 0; - virtual BuildConfigWidget *createConfigWidget() = 0; + virtual ProjectExplorer::NamedWidget *createConfigWidget() = 0; + virtual QList<NamedWidget *> createSubConfigWidgets(); // Maybe the BuildConfiguration is not the best place for the environment - virtual Utils::Environment baseEnvironment() const; + Utils::Environment baseEnvironment() const; QString baseEnvironmentText() const; Utils::Environment environment() const; void setUserEnvironmentChanges(const QList<Utils::EnvironmentItem> &diff); @@ -76,13 +77,6 @@ public: virtual QVariantMap toMap() const; - // Creates a suitable outputparser for custom build steps - // (based on the tool chain) - // this is not great API - // it's mainly so that custom build systems are better integrated - // with the generic project manager - virtual IOutputParser *createOutputParser() const = 0; - Target *target() const; virtual bool isEnabled() const; @@ -111,13 +105,16 @@ protected: virtual bool fromMap(const QVariantMap &map); private slots: - void handleKitUpdate(ProjectExplorer::Kit *k); + void handleKitUpdate(); private: + void emitEnvironmentChanged(); + bool m_clearSystemEnvironment; QList<Utils::EnvironmentItem> m_userEnvironmentChanges; QList<BuildStepList *> m_stepLists; Utils::AbstractMacroExpander *m_macroExpander; + Utils::Environment m_lastEnvironment; }; class PROJECTEXPLORER_EXPORT IBuildConfigurationFactory : @@ -144,6 +141,7 @@ public: static IBuildConfigurationFactory *find(Target *parent, const QVariantMap &map); static IBuildConfigurationFactory *find(Target *parent); + static IBuildConfigurationFactory *find(Target *parent, BuildConfiguration *bc); signals: void availableCreationIdsChanged(); diff --git a/src/plugins/projectexplorer/buildenvironmentwidget.cpp b/src/plugins/projectexplorer/buildenvironmentwidget.cpp index 002a9ea294..ee3ce72bd2 100644 --- a/src/plugins/projectexplorer/buildenvironmentwidget.cpp +++ b/src/plugins/projectexplorer/buildenvironmentwidget.cpp @@ -40,7 +40,7 @@ using namespace ProjectExplorer; -BuildEnvironmentWidget::BuildEnvironmentWidget() +BuildEnvironmentWidget::BuildEnvironmentWidget(BuildConfiguration *bc) : m_buildConfiguration(0) { QVBoxLayout *vbox = new QVBoxLayout(this); @@ -55,21 +55,6 @@ BuildEnvironmentWidget::BuildEnvironmentWidget() this, SLOT(environmentModelUserChangesChanged())); connect(m_clearSystemEnvironmentCheckBox, SIGNAL(toggled(bool)), this, SLOT(clearSystemEnvironmentCheckBoxClicked(bool))); -} - -QString BuildEnvironmentWidget::displayName() const -{ - return tr("Build Environment"); -} - -void BuildEnvironmentWidget::init(BuildConfiguration *bc) -{ - Q_ASSERT(bc); - - if (m_buildConfiguration) { - disconnect(m_buildConfiguration->target(), SIGNAL(environmentChanged()), - this, SLOT(environmentChanged())); - } m_buildConfiguration = bc; @@ -80,6 +65,8 @@ void BuildEnvironmentWidget::init(BuildConfiguration *bc) m_buildEnvironmentWidget->setBaseEnvironment(m_buildConfiguration->baseEnvironment()); m_buildEnvironmentWidget->setBaseEnvironmentText(m_buildConfiguration->baseEnvironmentText()); m_buildEnvironmentWidget->setUserChanges(m_buildConfiguration->userEnvironmentChanges()); + + setDisplayName(tr("Build Environment")); } void BuildEnvironmentWidget::environmentModelUserChangesChanged() diff --git a/src/plugins/projectexplorer/buildenvironmentwidget.h b/src/plugins/projectexplorer/buildenvironmentwidget.h index a8dd0162d3..3853920c3f 100644 --- a/src/plugins/projectexplorer/buildenvironmentwidget.h +++ b/src/plugins/projectexplorer/buildenvironmentwidget.h @@ -31,6 +31,7 @@ #define BUILDENVIRONMENTWIDGET_H #include <projectexplorer/buildstep.h> +#include <projectexplorer/namedwidget.h> QT_BEGIN_NAMESPACE class QCheckBox; @@ -41,15 +42,12 @@ namespace ProjectExplorer { class EnvironmentWidget; class BuildConfiguration; -class PROJECTEXPLORER_EXPORT BuildEnvironmentWidget : public BuildConfigWidget +class PROJECTEXPLORER_EXPORT BuildEnvironmentWidget : public NamedWidget { Q_OBJECT public: - BuildEnvironmentWidget(); - - QString displayName() const; - void init(BuildConfiguration *bc); + BuildEnvironmentWidget(BuildConfiguration *bc); private slots: void environmentModelUserChangesChanged(); diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index 890ca2d74f..8ada865914 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -48,6 +48,7 @@ #include <utils/qtcassert.h> #include <QDir> +#include <QPointer> #include <QTime> #include <QTimer> #include <QMetaType> @@ -75,7 +76,6 @@ struct BuildManagerPrivate { QList<BuildStep *> m_buildQueue; QList<bool> m_enabledState; QStringList m_stepNames; - ProjectExplorerPlugin *m_projectExplorerPlugin; bool m_running; QFutureWatcher<bool> m_watcher; QFutureInterface<bool> m_futureInterfaceForAysnc; @@ -97,7 +97,7 @@ struct BuildManagerPrivate { int m_maxProgress; QFutureInterface<void> *m_progressFutureInterface; QFutureWatcher<void> m_progressWatcher; - QWeakPointer<Core::FutureProgress> m_futureProgress; + QPointer<Core::FutureProgress> m_futureProgress; }; BuildManagerPrivate::BuildManagerPrivate() : @@ -115,8 +115,6 @@ BuildManagerPrivate::BuildManagerPrivate() : BuildManager::BuildManager(ProjectExplorerPlugin *parent, QAction *cancelBuildAction) : QObject(parent), d(new BuildManagerPrivate) { - d->m_projectExplorerPlugin = parent; - connect(&d->m_watcher, SIGNAL(finished()), this, SLOT(nextBuildQueue())); @@ -274,7 +272,7 @@ void BuildManager::clearBuildQueue() d->m_progressWatcher.setFuture(QFuture<void>()); delete d->m_progressFutureInterface; d->m_progressFutureInterface = 0; - d->m_futureProgress.clear(); + d->m_futureProgress = 0; d->m_maxProgress = 0; emit buildQueueFinished(false); @@ -321,10 +319,10 @@ void BuildManager::startBuildQueue(const QStringList &preambleMessage) d->m_taskHub->clearTasks(Core::Id(Constants::TASK_CATEGORY_COMPILE)); d->m_taskHub->clearTasks(Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)); progressManager->setApplicationLabel(QString()); - d->m_futureProgress = QWeakPointer<Core::FutureProgress>(progressManager->addTask(d->m_progressFutureInterface->future(), + d->m_futureProgress = progressManager->addTask(d->m_progressFutureInterface->future(), QString(), QLatin1String(Constants::TASK_BUILD), - Core::ProgressManager::KeepOnFinish | Core::ProgressManager::ShowInApplicationIcon)); + Core::ProgressManager::KeepOnFinish | Core::ProgressManager::ShowInApplicationIcon); connect(d->m_futureProgress.data(), SIGNAL(clicked()), this, SLOT(showBuildResults())); d->m_futureProgress.data()->setWidget(new Internal::BuildProgress(d->m_taskWindow)); d->m_progress = 0; diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp index f0ff0844f7..c3e3548b5e 100644 --- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp @@ -175,7 +175,7 @@ BuildSettingsWidget::BuildSettingsWidget(Target *target) : connect(m_target, SIGNAL(kitChanged()), this, SLOT(updateAddButtonMenu())); } -void BuildSettingsWidget::addSubWidget(BuildConfigWidget *widget) +void BuildSettingsWidget::addSubWidget(NamedWidget *widget) { widget->setContentsMargins(0, 10, 0, 0); @@ -205,7 +205,7 @@ void BuildSettingsWidget::clear() m_labels.clear(); } -QList<BuildConfigWidget *> BuildSettingsWidget::subWidgets() const +QList<NamedWidget *> BuildSettingsWidget::subWidgets() const { return m_subWidgets; } @@ -235,19 +235,19 @@ void BuildSettingsWidget::updateBuildSettings() // update buttons m_removeButton->setEnabled(m_target->buildConfigurations().size() > 1); + if (!m_buildConfiguration) + return; + // Add pages - BuildConfigWidget *generalConfigWidget = m_buildConfiguration->createConfigWidget(); + NamedWidget *generalConfigWidget = m_buildConfiguration->createConfigWidget(); addSubWidget(generalConfigWidget); - addSubWidget(new BuildStepsPage(m_target, Core::Id(Constants::BUILDSTEPS_BUILD))); - addSubWidget(new BuildStepsPage(m_target, Core::Id(Constants::BUILDSTEPS_CLEAN))); + addSubWidget(new BuildStepsPage(m_buildConfiguration, Core::Id(Constants::BUILDSTEPS_BUILD))); + addSubWidget(new BuildStepsPage(m_buildConfiguration, Core::Id(Constants::BUILDSTEPS_CLEAN))); - QList<BuildConfigWidget *> subConfigWidgets = m_target->project()->subConfigWidgets(); - foreach (BuildConfigWidget *subConfigWidget, subConfigWidgets) + QList<NamedWidget *> subConfigWidgets = m_buildConfiguration->createSubConfigWidgets(); + foreach (NamedWidget *subConfigWidget, subConfigWidgets) addSubWidget(subConfigWidget); - - foreach (BuildConfigWidget *widget, subWidgets()) - widget->init(m_buildConfiguration); } void BuildSettingsWidget::currentIndexChanged(int index) @@ -267,11 +267,7 @@ void BuildSettingsWidget::updateActiveConfiguration() BuildConfigurationModel *model = static_cast<BuildConfigurationModel *>(m_buildConfigurationComboBox->model()); m_buildConfigurationComboBox->setCurrentIndex(model->indexFor(m_buildConfiguration).row()); - foreach (QWidget *widget, subWidgets()) { - if (BuildConfigWidget *buildStepWidget = qobject_cast<BuildConfigWidget*>(widget)) { - buildStepWidget->init(m_buildConfiguration); - } - } + updateBuildSettings(); } void BuildSettingsWidget::createConfiguration() @@ -291,7 +287,6 @@ void BuildSettingsWidget::createConfiguration() QTC_CHECK(bc->id() == id); m_target->setActiveBuildConfiguration(bc); - updateBuildSettings(); } void BuildSettingsWidget::cloneConfiguration() @@ -357,8 +352,6 @@ void BuildSettingsWidget::cloneConfiguration(BuildConfiguration *sourceConfigura bc->setDisplayName(name); m_target->addBuildConfiguration(bc); - updateBuildSettings(); - m_target->setActiveBuildConfiguration(bc); } @@ -392,6 +385,4 @@ void BuildSettingsWidget::deleteConfiguration(BuildConfiguration *deleteConfigur } m_target->removeBuildConfiguration(deleteConfiguration); - - updateBuildSettings(); } diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.h b/src/plugins/projectexplorer/buildsettingspropertiespage.h index 019cde728b..d2c3286cc9 100644 --- a/src/plugins/projectexplorer/buildsettingspropertiespage.h +++ b/src/plugins/projectexplorer/buildsettingspropertiespage.h @@ -45,8 +45,8 @@ QT_END_NAMESPACE namespace ProjectExplorer { class BuildConfiguration; -class BuildConfigWidget; class IBuildStepFactory; +class NamedWidget; namespace Internal { @@ -73,8 +73,8 @@ public: ~BuildSettingsWidget(); void clear(); - void addSubWidget(BuildConfigWidget *widget); - QList<BuildConfigWidget *> subWidgets() const; + void addSubWidget(ProjectExplorer::NamedWidget *widget); + QList<ProjectExplorer::NamedWidget *> subWidgets() const; private slots: void updateBuildSettings(); @@ -103,7 +103,7 @@ private: QComboBox *m_buildConfigurationComboBox; QMenu *m_addButtonMenu; - QList<BuildConfigWidget *> m_subWidgets; + QList<NamedWidget *> m_subWidgets; QList<QLabel *> m_labels; }; diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h index af89e1d065..f3f9c495c1 100644 --- a/src/plugins/projectexplorer/buildstep.h +++ b/src/plugins/projectexplorer/buildstep.h @@ -118,24 +118,6 @@ public: virtual BuildStep *clone(BuildStepList *parent, BuildStep *product) = 0; }; -class PROJECTEXPLORER_EXPORT BuildConfigWidget - : public QWidget -{ - Q_OBJECT -public: - BuildConfigWidget() - :QWidget(0) - {} - - virtual QString displayName() const = 0; - - // This is called to set up the config widget before showing it - virtual void init(BuildConfiguration *bc) = 0; - -signals: - void displayNameChanged(const QString &); -}; - class PROJECTEXPLORER_EXPORT BuildStepConfigWidget : public QWidget { diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp index f48e16dd68..bcbdea0f38 100644 --- a/src/plugins/projectexplorer/buildstepspage.cpp +++ b/src/plugins/projectexplorer/buildstepspage.cpp @@ -38,6 +38,7 @@ #include <extensionsystem/pluginmanager.h> #include <utils/qtcassert.h> #include <utils/detailswidget.h> +#include <utils/hostosinfo.h> #include <QSignalMapper> @@ -53,6 +54,7 @@ using namespace ProjectExplorer; using namespace ProjectExplorer::Internal; +using namespace Utils; ToolWidget::ToolWidget(QWidget *parent) : Utils::FadingPanel(parent), m_buildStepEnabled(true) @@ -67,11 +69,7 @@ ToolWidget::ToolWidget(QWidget *parent) hbox->setContentsMargins(0, 0, 0, 0); hbox->setSpacing(0); m_firstWidget->setLayout(hbox); -#ifdef Q_OS_MAC - QSize buttonSize(20, 20); -#else - QSize buttonSize(20, 26); -#endif + QSize buttonSize(20, HostOsInfo::isMacHost() ? 20 : 26); m_disableButton = new QToolButton(m_firstWidget); m_disableButton->setAutoRaise(true); @@ -138,17 +136,15 @@ void ToolWidget::setBuildStepEnabled(bool b) { m_buildStepEnabled = b; if (m_buildStepEnabled) { -#ifdef Q_OS_MAC - m_firstWidget->setOpacity(m_targetOpacity); -#else - m_firstWidget->fadeTo(m_targetOpacity); -#endif + if (HostOsInfo::isMacHost()) + m_firstWidget->setOpacity(m_targetOpacity); + else + m_firstWidget->fadeTo(m_targetOpacity); } else { -#ifdef Q_OS_MAC - m_firstWidget->setOpacity(1.0); -#else - m_firstWidget->fadeTo(1.0); -#endif + if (HostOsInfo::isMacHost()) + m_firstWidget->setOpacity(1.0); + else + m_firstWidget->fadeTo(1.0); } m_disableButton->setChecked(!b); } @@ -461,9 +457,8 @@ void BuildStepListWidget::setupUi() hboxLayout->addStretch(10); -#ifdef Q_OS_MAC - m_addButton->setAttribute(Qt::WA_MacSmallSize); -#endif + if (HostOsInfo::isMacHost()) + m_addButton->setAttribute(Qt::WA_MacSmallSize); m_vbox->addLayout(hboxLayout); @@ -483,7 +478,7 @@ void BuildStepListWidget::updateBuildStepButtonsState() s->toolWidget->setUpEnabled((i > 0) && !(m_buildStepList->at(i)->immutable() - && m_buildStepList->at(i - 1))); + && m_buildStepList->at(i - 1)->immutable())); m_upMapper->setMapping(s->toolWidget, i); s->toolWidget->setDownEnabled((i + 1 < m_buildStepList->count()) && !(m_buildStepList->at(i)->immutable() @@ -496,31 +491,23 @@ void BuildStepListWidget::updateBuildStepButtonsState() } } -BuildStepsPage::BuildStepsPage(Target *target, Core::Id id) : - BuildConfigWidget(), +BuildStepsPage::BuildStepsPage(BuildConfiguration *bc, Core::Id id) : + NamedWidget(), m_id(id), m_widget(new BuildStepListWidget(this)) { - Q_UNUSED(target); QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); layout->setSpacing(0); layout->addWidget(m_widget); -} -BuildStepsPage::~BuildStepsPage() -{ } + m_widget->init(bc->stepList(m_id)); -QString BuildStepsPage::displayName() const -{ if (m_id == Constants::BUILDSTEPS_BUILD) - return tr("Build Steps"); + setDisplayName(tr("Build Steps")); if (m_id == Constants::BUILDSTEPS_CLEAN) - return tr("Clean Steps"); - return QString(); + setDisplayName(tr("Clean Steps")); } -void BuildStepsPage::init(BuildConfiguration *bc) -{ - m_widget->init(bc->stepList(m_id)); -} +BuildStepsPage::~BuildStepsPage() +{ } diff --git a/src/plugins/projectexplorer/buildstepspage.h b/src/plugins/projectexplorer/buildstepspage.h index 4719708c69..8da94d0201 100644 --- a/src/plugins/projectexplorer/buildstepspage.h +++ b/src/plugins/projectexplorer/buildstepspage.h @@ -151,17 +151,14 @@ namespace Ui { class BuildStepsPage; } -class BuildStepsPage : public BuildConfigWidget +class BuildStepsPage : public NamedWidget { Q_OBJECT public: - BuildStepsPage(Target *target, Core::Id id); + BuildStepsPage(BuildConfiguration *bc, Core::Id id); virtual ~BuildStepsPage(); - QString displayName() const; - void init(BuildConfiguration *bc); - private: Core::Id m_id; BuildStepListWidget *m_widget; diff --git a/src/plugins/projectexplorer/buildtargetinfo.h b/src/plugins/projectexplorer/buildtargetinfo.h index d368d2d371..9151cb4b61 100644 --- a/src/plugins/projectexplorer/buildtargetinfo.h +++ b/src/plugins/projectexplorer/buildtargetinfo.h @@ -34,6 +34,7 @@ #include <utils/fileutils.h> #include <QList> +#include <QSet> namespace ProjectExplorer { @@ -58,6 +59,22 @@ public: bool isValid() const { return !targetFilePath.isEmpty(); } }; +inline bool operator==(const BuildTargetInfo &ti1, const BuildTargetInfo &ti2) +{ + return ti1.targetFilePath == ti2.targetFilePath; +} + +inline bool operator!=(const BuildTargetInfo &ti1, const BuildTargetInfo &ti2) +{ + return !(ti1 == ti2); +} + +inline uint qHash(const BuildTargetInfo &ti) +{ + return qHash(ti.targetFilePath); +} + + class PROJECTEXPLORER_EXPORT BuildTargetInfoList { public: @@ -78,6 +95,16 @@ public: QList<BuildTargetInfo> list; }; +inline bool operator==(const BuildTargetInfoList &til1, const BuildTargetInfoList &til2) +{ + return til1.list.toSet() == til2.list.toSet(); +} + +inline bool operator!=(const BuildTargetInfoList &til1, const BuildTargetInfoList &til2) +{ + return !(til1 == til2); +} + } // namespace ProjectExplorer #endif // BUILDTARGETINFO_H diff --git a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp index bcb16f1f88..9af139bbce 100644 --- a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp @@ -76,13 +76,13 @@ CodeStyleSettingsWidget::CodeStyleSettingsWidget(Project *project) : QWidget(), const EditorConfiguration *config = m_project->editorConfiguration(); - QMap<QString, ICodeStylePreferencesFactory *> factories + QMap<Core::Id, ICodeStylePreferencesFactory *> factories = TextEditor::TextEditorSettings::instance()->codeStyleFactories(); - QMapIterator<QString, ICodeStylePreferencesFactory *> it(factories); + QMapIterator<Core::Id, ICodeStylePreferencesFactory *> it(factories); while (it.hasNext()) { it.next(); ICodeStylePreferencesFactory *factory = it.value(); - const QString languageId = factory->languageId(); + Core::Id languageId = factory->languageId(); ICodeStylePreferences *codeStylePreferences = config->codeStyle(languageId); CodeStyleEditor *preview = new CodeStyleEditor(factory, codeStylePreferences, m_ui.stackedWidget); diff --git a/src/plugins/projectexplorer/compileoutputwindow.cpp b/src/plugins/projectexplorer/compileoutputwindow.cpp index af94992f8a..0d8d1766bd 100644 --- a/src/plugins/projectexplorer/compileoutputwindow.cpp +++ b/src/plugins/projectexplorer/compileoutputwindow.cpp @@ -57,7 +57,7 @@ using namespace ProjectExplorer; using namespace ProjectExplorer::Internal; namespace { -const int MAX_LINECOUNT = 50000; +const int MAX_LINECOUNT = 100000; } namespace ProjectExplorer { diff --git a/src/plugins/projectexplorer/copytaskhandler.cpp b/src/plugins/projectexplorer/copytaskhandler.cpp index 3d098aa2be..c2f1dee2b5 100644 --- a/src/plugins/projectexplorer/copytaskhandler.cpp +++ b/src/plugins/projectexplorer/copytaskhandler.cpp @@ -30,8 +30,10 @@ #include "copytaskhandler.h" #include "task.h" +#include "taskwindow.h" #include <coreplugin/coreconstants.h> +#include <coreplugin/actionmanager/actionmanager.h> #include <QDir> #include <QAction> @@ -61,9 +63,13 @@ void CopyTaskHandler::handle(const ProjectExplorer::Task &task) + type + task.description); } +Core::Id CopyTaskHandler::actionManagerId() const +{ + return Core::Id(Core::Constants::COPY); +} + QAction *CopyTaskHandler::createAction(QObject *parent) const { - QAction *copyAction = new QAction(tr("&Copy", "Name of the action triggering the copytaskhandler"), parent); - copyAction->setToolTip(tr("Copy task to clipboard")); + QAction *copyAction = new QAction(parent); return copyAction; } diff --git a/src/plugins/projectexplorer/copytaskhandler.h b/src/plugins/projectexplorer/copytaskhandler.h index 77fbc63385..4629db5681 100644 --- a/src/plugins/projectexplorer/copytaskhandler.h +++ b/src/plugins/projectexplorer/copytaskhandler.h @@ -44,6 +44,7 @@ public: bool canHandle(const Task &) const { return true; } void handle(const Task &task); + Core::Id actionManagerId() const; QAction *createAction(QObject *parent) const; }; diff --git a/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp b/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp index acc599e996..5aeaa6fac4 100644 --- a/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp +++ b/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp @@ -31,6 +31,7 @@ #include "customwizard.h" #include "customwizardparameters.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QProcess> @@ -65,15 +66,16 @@ QStringList fixGeneratorScript(const QString &configFile, QString binary) } } // not absolute QStringList rc(binary); -#ifdef Q_OS_WIN // Windows: Cannot run scripts by QProcess, do 'cmd /c' - const QString extension = binaryInfo.suffix(); - if (!extension.isEmpty() && extension.compare(QLatin1String("exe"), Qt::CaseInsensitive) != 0) { - rc.push_front(QLatin1String("/C")); - rc.push_front(QString::fromLocal8Bit(qgetenv("COMSPEC"))); - if (rc.front().isEmpty()) - rc.front() = QLatin1String("cmd.exe"); + if (Utils::HostOsInfo::isWindowsHost()) { // Windows: Cannot run scripts by QProcess, do 'cmd /c' + const QString extension = binaryInfo.suffix(); + if (!extension.isEmpty() && extension.compare(QLatin1String("exe"), + Qt::CaseInsensitive) != 0) { + rc.push_front(QLatin1String("/C")); + rc.push_front(QString::fromLocal8Bit(qgetenv("COMSPEC"))); + if (rc.front().isEmpty()) + rc.front() = QLatin1String("cmd.exe"); + } } -#endif return rc; } diff --git a/src/plugins/projectexplorer/dependenciespanel.cpp b/src/plugins/projectexplorer/dependenciespanel.cpp index b7dbd2ee5d..5f85e0bf37 100644 --- a/src/plugins/projectexplorer/dependenciespanel.cpp +++ b/src/plugins/projectexplorer/dependenciespanel.cpp @@ -81,9 +81,10 @@ DependenciesModel::~DependenciesModel() void DependenciesModel::resetModel() { + beginResetModel(); m_projects = m_session->projects(); m_projects.removeAll(m_project); - reset(); + endResetModel(); } int DependenciesModel::rowCount(const QModelIndex &index) const diff --git a/src/plugins/projectexplorer/deployconfiguration.cpp b/src/plugins/projectexplorer/deployconfiguration.cpp index b4b5c9e97e..67af8c9aaa 100644 --- a/src/plugins/projectexplorer/deployconfiguration.cpp +++ b/src/plugins/projectexplorer/deployconfiguration.cpp @@ -64,7 +64,8 @@ DeployConfiguration::DeployConfiguration(Target *target, const Core::Id id) : } DeployConfiguration::DeployConfiguration(Target *target, DeployConfiguration *source) : - ProjectConfiguration(target, source) + ProjectConfiguration(target, source), + m_stepList(0) { Q_ASSERT(target); // Do not clone stepLists here, do that in the derived constructor instead @@ -90,7 +91,7 @@ QVariantMap DeployConfiguration::toMap() const return map; } -DeployConfigurationWidget *DeployConfiguration::configurationWidget() const +NamedWidget *DeployConfiguration::createConfigWidget() { return 0; } @@ -150,6 +151,21 @@ void DeployConfiguration::cloneSteps(DeployConfiguration *source) } /// +// DefaultDeployConfiguration +/// +DefaultDeployConfiguration::DefaultDeployConfiguration(Target *target, const Core::Id id) + : DeployConfiguration(target, id) +{ + +} + +DefaultDeployConfiguration::DefaultDeployConfiguration(Target *target, DeployConfiguration *source) + : DeployConfiguration(target, source) +{ + cloneSteps(source); +} + +/// // DeployConfigurationFactory /// @@ -186,7 +202,7 @@ DeployConfiguration *DeployConfigurationFactory::create(Target *parent, const Co { if (!canCreate(parent, id)) return 0; - return new DeployConfiguration(parent, id); + return new DefaultDeployConfiguration(parent, id); } bool DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const @@ -198,7 +214,7 @@ DeployConfiguration *DeployConfigurationFactory::restore(Target *parent, const Q { if (!canRestore(parent, map)) return 0; - DeployConfiguration *dc = new DeployConfiguration(parent, idFromMap(map)); + DefaultDeployConfiguration *dc = new DefaultDeployConfiguration(parent, idFromMap(map)); if (!dc->fromMap(map)) { delete dc; return 0; @@ -215,7 +231,7 @@ DeployConfiguration *DeployConfigurationFactory::clone(Target *parent, DeployCon { if (!canClone(parent, product)) return 0; - return new DeployConfiguration(parent, product); + return new DefaultDeployConfiguration(parent, product); } DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, const QVariantMap &map) @@ -240,16 +256,20 @@ DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent) return 0; } +DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, DeployConfiguration *dc) +{ + QList<DeployConfigurationFactory *> factories + = ExtensionSystem::PluginManager::instance()->getObjects<DeployConfigurationFactory>(); + foreach (DeployConfigurationFactory *factory, factories) { + if (factory->canClone(parent, dc)) + return factory; + } + return 0; +} + bool DeployConfigurationFactory::canHandle(Target *parent) const { if (!parent->project()->supportsKit(parent->kit())) return false; return DeviceTypeKitInformation::deviceTypeId(parent->kit()) == Constants::DESKTOP_DEVICE_TYPE; } - -/// -// DeployConfigurationWidget -/// - -DeployConfigurationWidget::DeployConfigurationWidget(QWidget *parent) : NamedWidget(parent) -{ } diff --git a/src/plugins/projectexplorer/deployconfiguration.h b/src/plugins/projectexplorer/deployconfiguration.h index 015ec40129..cccbab0866 100644 --- a/src/plugins/projectexplorer/deployconfiguration.h +++ b/src/plugins/projectexplorer/deployconfiguration.h @@ -44,7 +44,7 @@ namespace ProjectExplorer { class BuildStepList; class Target; class DeployConfigurationFactory; -class DeployConfigurationWidget; +class NamedWidget; class PROJECTEXPLORER_EXPORT DeployConfiguration : public ProjectConfiguration { @@ -58,7 +58,7 @@ public: virtual QVariantMap toMap() const; - virtual DeployConfigurationWidget *configurationWidget() const; + virtual NamedWidget *createConfigWidget(); virtual bool isEnabled() const; virtual QString disabledReason() const; @@ -77,11 +77,18 @@ protected: bool fromMap(const QVariantMap &map); private: - friend class DeployConfigurationFactory; - BuildStepList *m_stepList; }; +class PROJECTEXPLORER_EXPORT DefaultDeployConfiguration : public DeployConfiguration +{ + Q_OBJECT + friend class DeployConfigurationFactory; // for the ctors +protected: + DefaultDeployConfiguration(Target *target, const Core::Id id); + DefaultDeployConfiguration(Target *target, DeployConfiguration *source); +}; + class PROJECTEXPLORER_EXPORT DeployConfigurationFactory : public QObject { @@ -106,6 +113,7 @@ public: static DeployConfigurationFactory *find(Target *parent, const QVariantMap &map); static DeployConfigurationFactory *find(Target *parent); + static DeployConfigurationFactory *find(Target *parent, DeployConfiguration *dc); signals: void availableCreationIdsChanged(); @@ -116,17 +124,6 @@ protected: private: }; -class PROJECTEXPLORER_EXPORT DeployConfigurationWidget : public NamedWidget -{ - Q_OBJECT - -public: - explicit DeployConfigurationWidget(QWidget *parent = 0); - - // This is called to set up the config widget before showing it - virtual void init(DeployConfiguration *dc) = 0; -}; - } // namespace ProjectExplorer Q_DECLARE_METATYPE(ProjectExplorer::DeployConfiguration *) diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index bd4c4cf6bc..71b868c8d5 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -228,7 +228,6 @@ Utils::FileName DeviceManager::settingsFilePath(const QString &extension) void DeviceManager::addDevice(const IDevice::Ptr &_device) { const IDevice::Ptr device = _device->clone(); - QTC_ASSERT(this != instance() || device->isAutoDetected(), return); QString name = device->displayName(); const int pos = d->indexForId(device->id()); diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index db0cf7790a..f522afd23c 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -300,7 +300,7 @@ void IDevice::fromMap(const QVariantMap &map) { d->type = typeFromMap(map); d->displayName = map.value(QLatin1String(DisplayNameKey)).toString(); - d->id = Core::Id(map.value(QLatin1String(IdKey), newId().name()).toByteArray().constData()); + d->id = Core::Id(map.value(QLatin1String(IdKey), newId().name()).toByteArray()); d->origin = static_cast<Origin>(map.value(QLatin1String(OriginKey), ManuallyAdded).toInt()); d->sshParameters.host = map.value(HostKey).toString(); diff --git a/src/plugins/projectexplorer/editorconfiguration.cpp b/src/plugins/projectexplorer/editorconfiguration.cpp index ea4191f03c..027e21cb35 100644 --- a/src/plugins/projectexplorer/editorconfiguration.cpp +++ b/src/plugins/projectexplorer/editorconfiguration.cpp @@ -82,23 +82,23 @@ struct EditorConfigurationPrivate ExtraEncodingSettings m_extraEncodingSettings; QTextCodec *m_textCodec; - QMap<QString, ICodeStylePreferences *> m_languageCodeStylePreferences; + QMap<Core::Id, ICodeStylePreferences *> m_languageCodeStylePreferences; }; EditorConfiguration::EditorConfiguration() : d(new EditorConfigurationPrivate) { TextEditorSettings *textEditorSettings = TextEditorSettings::instance(); - const QMap<QString, ICodeStylePreferences *> languageCodeStylePreferences = textEditorSettings->codeStyles(); - QMapIterator<QString, ICodeStylePreferences *> itCodeStyle(languageCodeStylePreferences); + const QMap<Core::Id, ICodeStylePreferences *> languageCodeStylePreferences = textEditorSettings->codeStyles(); + QMapIterator<Core::Id, ICodeStylePreferences *> itCodeStyle(languageCodeStylePreferences); while (itCodeStyle.hasNext()) { itCodeStyle.next(); - const QString languageId = itCodeStyle.key(); + Core::Id languageId = itCodeStyle.key(); ICodeStylePreferences *originalPreferences = itCodeStyle.value(); ICodeStylePreferencesFactory *factory = textEditorSettings->codeStyleFactory(languageId); ICodeStylePreferences *preferences = factory->createCodeStyle(); preferences->setDelegatingPool(textEditorSettings->codeStylePool(languageId)); - preferences->setId(languageId + QLatin1String("Project")); + preferences->setId(languageId.toString() + QLatin1String("Project")); preferences->setDisplayName(tr("Project %1", "Settings, %1 is a language (C++ or QML)").arg(factory->displayName())); preferences->setCurrentDelegate(originalPreferences); d->m_languageCodeStylePreferences.insert(languageId, preferences); @@ -165,12 +165,12 @@ ICodeStylePreferences *EditorConfiguration::codeStyle() const return d->m_defaultCodeStyle; } -ICodeStylePreferences *EditorConfiguration::codeStyle(const QString &languageId) const +ICodeStylePreferences *EditorConfiguration::codeStyle(Core::Id languageId) const { return d->m_languageCodeStylePreferences.value(languageId, codeStyle()); } -QMap<QString, ICodeStylePreferences *> EditorConfiguration::codeStyles() const +QMap<Core::Id, ICodeStylePreferences *> EditorConfiguration::codeStyles() const { return d->m_languageCodeStylePreferences; } @@ -182,12 +182,12 @@ QVariantMap EditorConfiguration::toMap() const map.insert(kCodec, d->m_textCodec->name()); map.insert(kCodeStyleCount, d->m_languageCodeStylePreferences.count()); - QMapIterator<QString, ICodeStylePreferences *> itCodeStyle(d->m_languageCodeStylePreferences); + QMapIterator<Core::Id, ICodeStylePreferences *> itCodeStyle(d->m_languageCodeStylePreferences); int i = 0; while (itCodeStyle.hasNext()) { itCodeStyle.next(); QVariantMap settingsIdMap; - settingsIdMap.insert(QLatin1String("language"), itCodeStyle.key()); + settingsIdMap.insert(QLatin1String("language"), itCodeStyle.key().name()); QVariantMap value; itCodeStyle.value()->toMap(QString(), &value); settingsIdMap.insert(QLatin1String("value"), value); @@ -220,7 +220,7 @@ void EditorConfiguration::fromMap(const QVariantMap &map) qWarning() << "No data for code style settings list" << i << "found!"; continue; } - QString languageId = settingsIdMap.value(QLatin1String("language")).toString(); + Core::Id languageId(settingsIdMap.value(QLatin1String("language")).toByteArray()); QVariantMap value = settingsIdMap.value(QLatin1String("value")).toMap(); ICodeStylePreferences *preferences = d->m_languageCodeStylePreferences.value(languageId); if (preferences) { diff --git a/src/plugins/projectexplorer/editorconfiguration.h b/src/plugins/projectexplorer/editorconfiguration.h index 273020e891..dc5d46e0da 100644 --- a/src/plugins/projectexplorer/editorconfiguration.h +++ b/src/plugins/projectexplorer/editorconfiguration.h @@ -32,6 +32,8 @@ #include "projectexplorer_export.h" +#include <coreplugin/id.h> + #include <QObject> #include <QVariantMap> @@ -71,8 +73,8 @@ public: const TextEditor::ExtraEncodingSettings &extraEncodingSettings() const; TextEditor::ICodeStylePreferences *codeStyle() const; - TextEditor::ICodeStylePreferences *codeStyle(const QString &languageId) const; - QMap<QString, TextEditor::ICodeStylePreferences *> codeStyles() const; + TextEditor::ICodeStylePreferences *codeStyle(Core::Id languageId) const; + QMap<Core::Id, TextEditor::ICodeStylePreferences *> codeStyles() const; void configureEditor(TextEditor::ITextEditor *textEditor) const; diff --git a/src/plugins/projectexplorer/environmentitemswidget.cpp b/src/plugins/projectexplorer/environmentitemswidget.cpp index a9eb3d60de..d1b6f38888 100644 --- a/src/plugins/projectexplorer/environmentitemswidget.cpp +++ b/src/plugins/projectexplorer/environmentitemswidget.cpp @@ -30,6 +30,7 @@ #include "environmentitemswidget.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <texteditor/snippets/snippeteditor.h> #include <texteditor/texteditorsettings.h> @@ -53,9 +54,8 @@ QList<Utils::EnvironmentItem> EnvironmentItemsWidgetPrivate::cleanUp( QSet<QString> uniqueSet; for (int i = items.count() - 1; i >= 0; i--) { Utils::EnvironmentItem item = items.at(i); -#if defined(Q_OS_WIN) - item.name = item.name.toUpper(); -#endif + if (Utils::HostOsInfo::isWindowsHost()) + item.name = item.name.toUpper(); const QString &itemName = item.name; QString emptyName = itemName; emptyName.remove(QLatin1Char(' ')); diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index 88c22c18e7..a540a4647e 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -401,7 +401,7 @@ int FolderNavigationWidgetFactory::priority() const Core::Id FolderNavigationWidgetFactory::id() const { - return "File System"; + return Core::Id("File System"); } QKeySequence FolderNavigationWidgetFactory::activationSequence() const diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index ad1c22cfa2..ceabb4ba17 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -37,6 +37,7 @@ #include <utils/detailswidget.h> #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <utils/synchronousprocess.h> #include <utils/qtcassert.h> #include <utils/pathchooser.h> @@ -121,7 +122,8 @@ static QByteArray gccPredefinedMacros(const FileName &gcc, const QStringList &ar || a == QLatin1String("-O2") || a == QLatin1String("-O3") || a == QLatin1String("-ffinite-math-only") || a == QLatin1String("-fshort-double") || a == QLatin1String("-fshort-wchar") || a == QLatin1String("-fsignaling-nans") - || a.startsWith(QLatin1String("-std=")) || a.startsWith(QLatin1String("-specs=")) + || a.startsWith(QLatin1String("-std=")) || a.startsWith(QLatin1String("-stdlib=")) + || a.startsWith(QLatin1String("-specs=")) || a == QLatin1String("-ansi") || a.startsWith(QLatin1String("-D")) || a.startsWith(QLatin1String("-U")) || a == QLatin1String("-undef")) @@ -131,28 +133,34 @@ static QByteArray gccPredefinedMacros(const FileName &gcc, const QStringList &ar arguments << QLatin1String("-"); QByteArray predefinedMacros = runGcc(gcc, arguments, env); -#ifdef Q_OS_MAC - // Turn off flag indicating Apple's blocks support - const QByteArray blocksDefine("#define __BLOCKS__ 1"); - const QByteArray blocksUndefine("#undef __BLOCKS__"); - const int idx = predefinedMacros.indexOf(blocksDefine); - if (idx != -1) { - predefinedMacros.replace(idx, blocksDefine.length(), blocksUndefine); - } + if (Utils::HostOsInfo::isMacHost()) { + // Turn off flag indicating Apple's blocks support + const QByteArray blocksDefine("#define __BLOCKS__ 1"); + const QByteArray blocksUndefine("#undef __BLOCKS__"); + const int idx = predefinedMacros.indexOf(blocksDefine); + if (idx != -1) { + predefinedMacros.replace(idx, blocksDefine.length(), blocksUndefine); + } - // Define __strong and __weak (used for Apple's GC extension of C) to be empty - predefinedMacros.append("#define __strong\n"); - predefinedMacros.append("#define __weak\n"); -#endif // Q_OS_MAC + // Define __strong and __weak (used for Apple's GC extension of C) to be empty + predefinedMacros.append("#define __strong\n"); + predefinedMacros.append("#define __weak\n"); + } return predefinedMacros; } -QList<HeaderPath> GccToolChain::gccHeaderPaths(const FileName &gcc, const QStringList &env, const FileName &sysrootPath) +QList<HeaderPath> GccToolChain::gccHeaderPaths(const FileName &gcc, const QStringList &args, + const QStringList &env, const FileName &sysrootPath) { QList<HeaderPath> systemHeaderPaths; QStringList arguments; if (!sysrootPath.isEmpty()) arguments.append(QString::fromLatin1("--sysroot=%1").arg(sysrootPath.toString())); + foreach (const QString &a, args) { + if (a.startsWith(QLatin1String("-stdlib="))) + arguments << a; + } + arguments << QLatin1String("-xc++") << QLatin1String("-E") << QLatin1String("-v") @@ -392,13 +400,13 @@ ToolChain::CompilerFlags GccToolChain::compilerFlags(const QStringList &cxxflags return NO_FLAGS; } -QList<HeaderPath> GccToolChain::systemHeaderPaths(const Utils::FileName &sysRoot) const +QList<HeaderPath> GccToolChain::systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const { if (m_headerPaths.isEmpty()) { // Using a clean environment breaks ccache/distcc/etc. Environment env = Environment::systemEnvironment(); addToEnvironment(env); - m_headerPaths = gccHeaderPaths(m_compilerCommand, env.toStringList(), sysRoot); + m_headerPaths = gccHeaderPaths(m_compilerCommand, cxxflags, env.toStringList(), sysRoot); } return m_headerPaths; } @@ -589,11 +597,11 @@ ToolChain *Internal::GccToolChainFactory::create() QList<ToolChain *> Internal::GccToolChainFactory::autoDetect() { QList<ToolChain *> tcs; -#ifdef Q_OS_MAC - // Old mac compilers needed to support macx-gccXY mkspecs: - tcs.append(autoDetectToolchains(QLatin1String("g++-4.0"), Abi::hostAbi())); - tcs.append(autoDetectToolchains(QLatin1String("g++-4.2"), Abi::hostAbi())); -#endif + if (Utils::HostOsInfo::isMacHost()) { + // Old mac compilers needed to support macx-gccXY mkspecs: + tcs.append(autoDetectToolchains(QLatin1String("g++-4.0"), Abi::hostAbi())); + tcs.append(autoDetectToolchains(QLatin1String("g++-4.2"), Abi::hostAbi())); + } tcs.append(autoDetectToolchains(QLatin1String("g++"), Abi::hostAbi())); return tcs; @@ -767,12 +775,12 @@ QString ClangToolChain::typeDisplayName() const QString ClangToolChain::makeCommand(const Utils::Environment &environment) const { QStringList makes; -#if defined(Q_OS_WIN) - makes << QLatin1String("mingw32-make.exe"); - makes << QLatin1String("make.exe"); -#else - makes << QLatin1String("make"); -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + makes << QLatin1String("mingw32-make.exe"); + makes << QLatin1String("make.exe"); + } else { + makes << QLatin1String("make"); + } QString tmp; foreach (const QString &make, makes) { @@ -877,31 +885,30 @@ QString MingwToolChain::typeDisplayName() const QList<FileName> MingwToolChain::suggestedMkspecList() const { -#if defined(Q_OS_WIN) - return QList<FileName>() << FileName::fromString(QLatin1String("win32-g++")); -#elif defined(Q_OS_LINUX) - if (version().startsWith("4.6.")) - return QList<FileName>() - << FileName::fromString(QLatin1String("win32-g++-4.6-cross")) - << FileName::fromString(QLatin1String("unsupported/win32-g++-4.6-cross")); - else - return QList<FileName>() - << FileName::fromString(QLatin1String("win32-g++-cross")) - << FileName::fromString(QLatin1String("unsupported/win32-g++-cross")); -#else + if (Utils::HostOsInfo::isWindowsHost()) + return QList<FileName>() << FileName::fromString(QLatin1String("win32-g++")); + if (Utils::HostOsInfo::isLinuxHost()) { + if (version().startsWith("4.6.")) + return QList<FileName>() + << FileName::fromString(QLatin1String("win32-g++-4.6-cross")) + << FileName::fromString(QLatin1String("unsupported/win32-g++-4.6-cross")); + else + return QList<FileName>() + << FileName::fromString(QLatin1String("win32-g++-cross")) + << FileName::fromString(QLatin1String("unsupported/win32-g++-cross")); + } return QList<FileName>(); -#endif } QString MingwToolChain::makeCommand(const Utils::Environment &environment) const { QStringList makes; -#ifdef Q_OS_WIN + if (Utils::HostOsInfo::isWindowsHost()) { makes << QLatin1String("mingw32-make.exe"); makes << QLatin1String("make.exe"); -#else + } else { makes << QLatin1String("make"); -#endif + } QString tmp; foreach (const QString &make, makes) { diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index eca1aa3375..273f042ee4 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -63,7 +63,7 @@ public: QByteArray predefinedMacros(const QStringList &cxxflags) const; CompilerFlags compilerFlags(const QStringList &cxxflags) const; - QList<HeaderPath> systemHeaderPaths(const Utils::FileName &sysRoot) const; + QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const; void addToEnvironment(Utils::Environment &env) const; QString makeCommand(const Utils::Environment &environment) const; QList<Utils::FileName> suggestedMkspecList() const; @@ -90,7 +90,7 @@ protected: virtual QList<Abi> detectSupportedAbis() const; virtual QString detectVersion() const; - static QList<HeaderPath> gccHeaderPaths(const Utils::FileName &gcc, const QStringList &env, const Utils::FileName &sysrootPath); + static QList<HeaderPath> gccHeaderPaths(const Utils::FileName &gcc, const QStringList &args, const QStringList &env, const Utils::FileName &sysrootPath); mutable QByteArray m_predefinedMacros; diff --git a/src/plugins/projectexplorer/images/targetchangebutton.png b/src/plugins/projectexplorer/images/targetchangebutton.png Binary files differnew file mode 100644 index 0000000000..1311d38ef8 --- /dev/null +++ b/src/plugins/projectexplorer/images/targetchangebutton.png diff --git a/src/plugins/projectexplorer/images/targetchangebutton2.png b/src/plugins/projectexplorer/images/targetchangebutton2.png Binary files differnew file mode 100644 index 0000000000..d5d5cfefd9 --- /dev/null +++ b/src/plugins/projectexplorer/images/targetchangebutton2.png diff --git a/src/plugins/projectexplorer/images/targetremovebutton.png b/src/plugins/projectexplorer/images/targetremovebutton.png Binary files differdeleted file mode 100644 index 15e8502ccf..0000000000 --- a/src/plugins/projectexplorer/images/targetremovebutton.png +++ /dev/null diff --git a/src/plugins/projectexplorer/images/targetremovebuttondark.png b/src/plugins/projectexplorer/images/targetremovebuttondark.png Binary files differdeleted file mode 100644 index c1ec33f910..0000000000 --- a/src/plugins/projectexplorer/images/targetremovebuttondark.png +++ /dev/null diff --git a/src/plugins/projectexplorer/itaskhandler.h b/src/plugins/projectexplorer/itaskhandler.h index cfebdb83f7..90f2ac8fab 100644 --- a/src/plugins/projectexplorer/itaskhandler.h +++ b/src/plugins/projectexplorer/itaskhandler.h @@ -32,6 +32,8 @@ #include "projectexplorer_export.h" +#include <coreplugin/id.h> + #include <QObject> #include <QString> @@ -52,6 +54,7 @@ public: virtual bool isDefaultHandler() const { return false; } virtual bool canHandle(const Task &) const = 0; virtual void handle(const Task &) = 0; + virtual Core::Id actionManagerId() const { return Core::Id(); } virtual QAction *createAction(QObject *parent) const = 0; }; diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp index 5ce108f1d0..0fc7d93a11 100644 --- a/src/plugins/projectexplorer/kit.cpp +++ b/src/plugins/projectexplorer/kit.cpp @@ -34,6 +34,7 @@ #include "kitmanager.h" #include "project.h" #include "toolchainmanager.h" +#include "ioutputparser.h" #include <utils/qtcassert.h> @@ -88,7 +89,7 @@ public: m_mustNotify(false) { if (!id.isValid()) - m_id = Core::Id(QUuid::createUuid().toString().toLatin1().constData()); + m_id = Core::Id(QUuid::createUuid().toString().toLatin1()); } QString m_displayName; @@ -363,6 +364,23 @@ void Kit::addToEnvironment(Utils::Environment &env) const ki->addToEnvironment(this, env); } +IOutputParser *Kit::createOutputParser() const +{ + IOutputParser *last = 0; + IOutputParser *first = 0; + QList<KitInformation *> infoList = KitManager::instance()->kitInformation(); + foreach (KitInformation *ki, infoList) { + IOutputParser *next = ki->createOutputParser(this); + if (!first) + first = next; + if (last && next) + last->appendOutputParser(next); + if (next) + last = next; + } + return first; +} + QString Kit::toHtml() { QString rc; diff --git a/src/plugins/projectexplorer/kit.h b/src/plugins/projectexplorer/kit.h index 475b1d9601..01e4948609 100644 --- a/src/plugins/projectexplorer/kit.h +++ b/src/plugins/projectexplorer/kit.h @@ -40,6 +40,7 @@ namespace Utils { class Environment; } namespace ProjectExplorer { +class IOutputParser; namespace Internal { class KitManagerPrivate; @@ -89,6 +90,7 @@ public: bool isEqual(const Kit *other) const; void addToEnvironment(Utils::Environment &env) const; + IOutputParser *createOutputParser() const; QString toHtml(); Kit *clone(bool keepName = false) const; diff --git a/src/plugins/projectexplorer/kitconfigwidget.h b/src/plugins/projectexplorer/kitconfigwidget.h index c9239f3312..b1d518900e 100644 --- a/src/plugins/projectexplorer/kitconfigwidget.h +++ b/src/plugins/projectexplorer/kitconfigwidget.h @@ -34,30 +34,34 @@ #include <QWidget> -QT_FORWARD_DECLARE_CLASS(QGridLayout) - namespace ProjectExplorer { +class Kit; + // -------------------------------------------------------------------------- // KitConfigWidget // -------------------------------------------------------------------------- -class PROJECTEXPLORER_EXPORT KitConfigWidget : public QWidget +class PROJECTEXPLORER_EXPORT KitConfigWidget : public QObject { Q_OBJECT public: - KitConfigWidget(QWidget *parent = 0) : QWidget(parent) - { } + KitConfigWidget(Kit *kit) : m_kit(kit) { } virtual QString displayName() const = 0; + virtual QString toolTip() const { return QString(); } virtual void makeReadOnly() = 0; virtual void refresh() = 0; + virtual QWidget *mainWidget() const = 0; virtual QWidget *buttonWidget() const { return 0; } signals: void dirty(); + +protected: + ProjectExplorer::Kit *m_kit; }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index 81c068c43f..99cfacb9a3 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -205,6 +205,14 @@ void ToolChainKitInformation::addToEnvironment(const Kit *k, Utils::Environment tc->addToEnvironment(env); } +IOutputParser *ToolChainKitInformation::createOutputParser(const Kit *k) const +{ + ToolChain *tc = toolChain(k); + if (tc) + return tc->outputParser(); + return 0; +} + ToolChain *ToolChainKitInformation::toolChain(const Kit *k) { if (!k) @@ -302,7 +310,7 @@ const Core::Id DeviceTypeKitInformation::deviceTypeId(const Kit *k) { if (!k) return Core::Id(); - return Core::Id(k->value(Core::Id(DEVICETYPE_INFORMATION)).toByteArray().constData()); + return Core::Id(k->value(Core::Id(DEVICETYPE_INFORMATION)).toByteArray()); } void DeviceTypeKitInformation::setDeviceTypeId(Kit *k, Core::Id type) diff --git a/src/plugins/projectexplorer/kitinformation.h b/src/plugins/projectexplorer/kitinformation.h index 3abb091eab..d6c785a5e4 100644 --- a/src/plugins/projectexplorer/kitinformation.h +++ b/src/plugins/projectexplorer/kitinformation.h @@ -112,6 +112,7 @@ public: ItemList toUserOutput(Kit *k) const; void addToEnvironment(const Kit *k, Utils::Environment &env) const; + IOutputParser *createOutputParser(const Kit *k) const; static ToolChain *toolChain(const Kit *k); static void setToolChain(Kit *k, ToolChain *tc); diff --git a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp index 78e3927689..03ca32538a 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp @@ -43,7 +43,6 @@ #include <utils/pathchooser.h> #include <QComboBox> -#include <QHBoxLayout> #include <QLabel> #include <QPushButton> @@ -54,21 +53,12 @@ namespace Internal { // SysRootInformationConfigWidget: // -------------------------------------------------------------------------- -SysRootInformationConfigWidget::SysRootInformationConfigWidget(Kit *k, QWidget *parent) : - KitConfigWidget(parent), - m_kit(k) +SysRootInformationConfigWidget::SysRootInformationConfigWidget(Kit *k) : + KitConfigWidget(k) { - setToolTip(tr("The root directory of the system image to use.<br>" - "Leave empty when building for the desktop.")); - QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); m_chooser = new Utils::PathChooser; - m_chooser->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_chooser); m_chooser->setExpectedKind(Utils::PathChooser::ExistingDirectory); - m_chooser->setFileName(SysRootKitInformation::sysRoot(k)); - connect(m_chooser, SIGNAL(changed(QString)), this, SLOT(pathWasChanged())); } @@ -77,6 +67,12 @@ QString SysRootInformationConfigWidget::displayName() const return tr("Sysroot:"); } +QString SysRootInformationConfigWidget::toolTip() const +{ + return tr("The root directory of the system image to use.<br>" + "Leave empty when building for the desktop."); +} + void SysRootInformationConfigWidget::refresh() { m_chooser->setFileName(SysRootKitInformation::sysRoot(m_kit)); @@ -87,6 +83,11 @@ void SysRootInformationConfigWidget::makeReadOnly() m_chooser->setEnabled(false); } +QWidget *SysRootInformationConfigWidget::mainWidget() const +{ + return m_chooser->lineEdit(); +} + QWidget *SysRootInformationConfigWidget::buttonWidget() const { return m_chooser->buttonAtIndex(0); @@ -101,22 +102,13 @@ void SysRootInformationConfigWidget::pathWasChanged() // ToolChainInformationConfigWidget: // -------------------------------------------------------------------------- -ToolChainInformationConfigWidget::ToolChainInformationConfigWidget(Kit *k, QWidget *parent) : - KitConfigWidget(parent), - m_isReadOnly(false), m_kit(k), - m_comboBox(new QComboBox), m_manageButton(new QPushButton(this)) +ToolChainInformationConfigWidget::ToolChainInformationConfigWidget(Kit *k) : + KitConfigWidget(k), m_isReadOnly(false) { - setToolTip(tr("The compiler to use for building.<br>" - "Make sure the compiler will produce binaries compatible with the target device, " - "Qt version and other libraries used.")); ToolChainManager *tcm = ToolChainManager::instance(); - QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); - m_comboBox->setContentsMargins(0, 0, 0, 0); + m_comboBox = new QComboBox; m_comboBox->setEnabled(false); - m_comboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - layout->addWidget(m_comboBox); foreach (ToolChain *tc, tcm->toolChains()) toolChainAdded(tc); @@ -126,8 +118,8 @@ ToolChainInformationConfigWidget::ToolChainInformationConfigWidget(Kit *k, QWidg refresh(); connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentToolChainChanged(int))); + m_manageButton = new QPushButton(tr("Manage...")); m_manageButton->setContentsMargins(0, 0, 0, 0); - m_manageButton->setText(tr("Manage...")); connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageToolChains())); connect(tcm, SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)), @@ -143,6 +135,13 @@ QString ToolChainInformationConfigWidget::displayName() const return tr("Compiler:"); } +QString ToolChainInformationConfigWidget::toolTip() const +{ + return tr("The compiler to use for building.<br>" + "Make sure the compiler will produce binaries compatible with the target device, " + "Qt version and other libraries used."); +} + void ToolChainInformationConfigWidget::refresh() { m_comboBox->setCurrentIndex(indexOf(ToolChainKitInformation::toolChain(m_kit))); @@ -153,6 +152,11 @@ void ToolChainInformationConfigWidget::makeReadOnly() m_comboBox->setEnabled(false); } +QWidget *ToolChainInformationConfigWidget::mainWidget() const +{ + return m_comboBox; +} + QWidget *ToolChainInformationConfigWidget::buttonWidget() const { return m_manageButton; @@ -222,35 +226,35 @@ int ToolChainInformationConfigWidget::indexOf(const ToolChain *tc) // DeviceTypeInformationConfigWidget: // -------------------------------------------------------------------------- -DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *workingCopy, QWidget *parent) : - KitConfigWidget(parent), - m_isReadOnly(false), m_kit(workingCopy), - m_comboBox(new QComboBox) +DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *workingCopy) : + KitConfigWidget(workingCopy), m_isReadOnly(false), m_comboBox(new QComboBox) { - setToolTip(tr("The type of device to run applications on.")); - QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); - m_comboBox->setContentsMargins(0, 0, 0, 0); - m_comboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - layout->addWidget(m_comboBox); - QList<IDeviceFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<IDeviceFactory>(); foreach (IDeviceFactory *factory, factories) { - foreach (Core::Id id, factory->availableCreationIds()) { + foreach (Core::Id id, factory->availableCreationIds()) m_comboBox->addItem(factory->displayNameForId(id), id.uniqueIdentifier()); - } } refresh(); connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentTypeChanged(int))); } +QWidget *DeviceTypeInformationConfigWidget::mainWidget() const +{ + return m_comboBox; +} + QString DeviceTypeInformationConfigWidget::displayName() const { return tr("Device type:"); } +QString DeviceTypeInformationConfigWidget::toolTip() const +{ + return tr("The type of device to run applications on."); +} + void DeviceTypeInformationConfigWidget::refresh() { Core::Id devType = DeviceTypeKitInformation::deviceTypeId(m_kit); @@ -279,39 +283,38 @@ void DeviceTypeInformationConfigWidget::currentTypeChanged(int idx) // DeviceInformationConfigWidget: // -------------------------------------------------------------------------- -DeviceInformationConfigWidget::DeviceInformationConfigWidget(Kit *workingCopy, QWidget *parent) : - KitConfigWidget(parent), - m_isReadOnly(false), m_kit(workingCopy), - m_comboBox(new QComboBox), m_manageButton(new QPushButton(this)), +DeviceInformationConfigWidget::DeviceInformationConfigWidget(Kit *workingCopy) : + KitConfigWidget(workingCopy), + m_isReadOnly(false), + m_comboBox(new QComboBox), m_model(new DeviceManagerModel(DeviceManager::instance())) { - connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToReset())); - connect(m_model, SIGNAL(modelReset()), SLOT(modelReset())); - - setToolTip(tr("The device to run the applications on.")); - - QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); - m_comboBox->setContentsMargins(0, 0, 0, 0); - m_comboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - layout->addWidget(m_comboBox); - m_comboBox->setModel(m_model); - m_manageButton->setContentsMargins(0, 0, 0, 0); - m_manageButton->setText(tr("Manage...")); + m_manageButton = new QPushButton(tr("Manage")); refresh(); + connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToReset())); + connect(m_model, SIGNAL(modelReset()), SLOT(modelReset())); connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentDeviceChanged())); - connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageDevices())); } +QWidget *DeviceInformationConfigWidget::mainWidget() const +{ + return m_comboBox; +} + QString DeviceInformationConfigWidget::displayName() const { return tr("Device:"); } +QString DeviceInformationConfigWidget::toolTip() const +{ + return tr("The device to run the applications on."); +} + void DeviceInformationConfigWidget::refresh() { m_model->setTypeFilter(DeviceTypeKitInformation::deviceTypeId(m_kit)); diff --git a/src/plugins/projectexplorer/kitinformationconfigwidget.h b/src/plugins/projectexplorer/kitinformationconfigwidget.h index 2f3aaf1dd0..4213dec819 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.h +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.h @@ -44,7 +44,6 @@ namespace Utils { class PathChooser; } namespace ProjectExplorer { class DeviceManagerModel; -class Kit; class ToolChain; namespace Internal { @@ -58,18 +57,19 @@ class SysRootInformationConfigWidget : public KitConfigWidget Q_OBJECT public: - explicit SysRootInformationConfigWidget(Kit *k, QWidget *parent = 0); + explicit SysRootInformationConfigWidget(Kit *k); QString displayName() const; void refresh(); void makeReadOnly(); QWidget *buttonWidget() const; + QWidget *mainWidget() const; + QString toolTip() const; private slots: void pathWasChanged(); private: - Kit *m_kit; Utils::PathChooser *m_chooser; }; @@ -82,12 +82,14 @@ class ToolChainInformationConfigWidget : public KitConfigWidget Q_OBJECT public: - explicit ToolChainInformationConfigWidget(Kit *k, QWidget *parent = 0); + explicit ToolChainInformationConfigWidget(Kit *k); QString displayName() const; void refresh(); void makeReadOnly(); + QWidget *mainWidget() const; QWidget *buttonWidget() const; + QString toolTip() const; private slots: void toolChainAdded(ProjectExplorer::ToolChain *tc); @@ -101,7 +103,6 @@ private: int indexOf(const ToolChain *tc); bool m_isReadOnly; - Kit *m_kit; QComboBox *m_comboBox; QPushButton *m_manageButton; }; @@ -115,9 +116,11 @@ class DeviceTypeInformationConfigWidget : public KitConfigWidget Q_OBJECT public: - explicit DeviceTypeInformationConfigWidget(Kit *workingCopy, QWidget *parent = 0); + explicit DeviceTypeInformationConfigWidget(Kit *workingCopy); + QWidget *mainWidget() const; QString displayName() const; + QString toolTip() const; void refresh(); void makeReadOnly(); @@ -126,7 +129,6 @@ private slots: private: bool m_isReadOnly; - Kit *m_kit; QComboBox *m_comboBox; }; @@ -139,12 +141,14 @@ class DeviceInformationConfigWidget : public KitConfigWidget Q_OBJECT public: - explicit DeviceInformationConfigWidget(Kit *workingCopy, QWidget *parent = 0); + explicit DeviceInformationConfigWidget(Kit *workingCopy); + QWidget *mainWidget() const; + QWidget *buttonWidget() const; QString displayName() const; + QString toolTip() const; void refresh(); void makeReadOnly(); - QWidget *buttonWidget() const; private slots: void manageDevices(); @@ -154,7 +158,6 @@ private slots: private: bool m_isReadOnly; - Kit *m_kit; QComboBox *m_comboBox; QPushButton *m_manageButton; DeviceManagerModel *m_model; diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp index e5fc49583e..5e61af1266 100644 --- a/src/plugins/projectexplorer/kitmanager.cpp +++ b/src/plugins/projectexplorer/kitmanager.cpp @@ -196,6 +196,7 @@ void KitManager::restoreKits() setDefaultKit(k); d->m_writer = new Utils::PersistentSettingsWriter(settingsFileName(), QLatin1String("QtCreatorProfiles")); + emit kitsChanged(); } KitManager::~KitManager() @@ -453,6 +454,12 @@ void KitInformation::addToEnvironment(const Kit *k, Utils::Environment &env) con Q_UNUSED(env); } +IOutputParser *KitInformation::createOutputParser(const Kit *k) const +{ + Q_UNUSED(k); + return 0; +} + QString KitInformation::displayNamePostfix(const Kit *k) const { Q_UNUSED(k); diff --git a/src/plugins/projectexplorer/kitmanager.h b/src/plugins/projectexplorer/kitmanager.h index 88bbcbd6a5..b1c4f13b65 100644 --- a/src/plugins/projectexplorer/kitmanager.h +++ b/src/plugins/projectexplorer/kitmanager.h @@ -43,6 +43,7 @@ namespace Utils { class Environment; } namespace ProjectExplorer { +class IOutputParser; class Kit; class KitConfigWidget; @@ -82,6 +83,7 @@ public: virtual KitConfigWidget *createConfigWidget(Kit *) const = 0; virtual void addToEnvironment(const Kit *k, Utils::Environment &env) const; + virtual IOutputParser *createOutputParser(const Kit *k) const; virtual QString displayNamePostfix(const Kit *k) const; diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp index 7fcfee2af0..c4f5e29133 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp @@ -35,11 +35,11 @@ #include <utils/detailswidget.h> #include <utils/qtcassert.h> -#include <QHBoxLayout> #include <QFileDialog> #include <QGridLayout> #include <QLabel> #include <QLineEdit> +#include <QPainter> #include <QToolButton> #include <QScrollArea> #include <QSizePolicy> @@ -48,11 +48,9 @@ static const char WORKING_COPY_KIT_ID[] = "modified kit"; namespace ProjectExplorer { - namespace Internal { -KitManagerConfigWidget::KitManagerConfigWidget(Kit *k, QWidget *parent) : - QWidget(parent), +KitManagerConfigWidget::KitManagerConfigWidget(Kit *k) : m_layout(new QGridLayout), m_iconButton(new QToolButton), m_nameEdit(new QLineEdit), @@ -60,30 +58,27 @@ KitManagerConfigWidget::KitManagerConfigWidget(Kit *k, QWidget *parent) : m_modifiedKit(new Kit(Core::Id(WORKING_COPY_KIT_ID))), m_fixingKit(false) { - QVBoxLayout *top = new QVBoxLayout(this); - top->setMargin(0); + m_layout->addWidget(m_nameEdit, 0, WidgetColumn); + m_layout->addWidget(m_iconButton, 0, ButtonColumn); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + QWidget *inner = new QWidget; + inner->setLayout(m_layout); QScrollArea *scroll = new QScrollArea; + scroll->setWidget(inner); scroll->setFrameShape(QFrame::NoFrame); scroll->setWidgetResizable(true); scroll->setFocusPolicy(Qt::NoFocus); - top->addWidget(scroll); - - Utils::DetailsWidget *details = new Utils::DetailsWidget; - details->setState(Utils::DetailsWidget::NoSummary); - scroll->setWidget(details); - QWidget *widget = new QWidget; + QGridLayout *mainLayout = new QGridLayout(this); + mainLayout->setMargin(1); + mainLayout->addWidget(scroll, 0, 0); - m_layout->setMargin(0); - m_layout->setSpacing(6); - m_layout->setContentsMargins(6, 0, 6, 0); - m_layout->setRowStretch(1, 1); - widget->setLayout(m_layout); + QString toolTip = tr("Kit name and icon."); + setLabel(tr("Name:"), toolTip, 0); + m_iconButton->setToolTip(toolTip); - details->setWidget(widget); - - addToLayout(tr("Name:"), tr("Kit name and icon."), m_nameEdit, m_iconButton); discard(); connect(m_iconButton, SIGNAL(clicked()), this, SLOT(setIcon())); @@ -104,7 +99,7 @@ KitManagerConfigWidget::~KitManagerConfigWidget() delete m_modifiedKit; // Make sure our workingCopy did not get registered somehow: foreach (const Kit *k, KitManager::instance()->kits()) - Q_ASSERT(k->id() != Core::Id(WORKING_COPY_KIT_ID)); + QTC_CHECK(k->id() != Core::Id(WORKING_COPY_KIT_ID)); } QString KitManagerConfigWidget::displayName() const @@ -167,7 +162,15 @@ void KitManagerConfigWidget::addConfigWidget(ProjectExplorer::KitConfigWidget *w QTC_ASSERT(widget, return); QTC_ASSERT(!m_widgets.contains(widget), return); - addToLayout(widget->displayName(), widget->toolTip(), widget, widget->buttonWidget()); + QString name = widget->displayName(); + QString toolTip = widget->toolTip(); + + int row = m_layout->rowCount(); + m_layout->addWidget(widget->mainWidget(), row, WidgetColumn); + if (QWidget *button = widget->buttonWidget()) + m_layout->addWidget(button, row, ButtonColumn); + setLabel(name, toolTip, row); + m_widgets.append(widget); } @@ -253,16 +256,7 @@ void KitManagerConfigWidget::kitWasUpdated(Kit *k) discard(); } -void KitManagerConfigWidget::addToLayout(const QString &name, const QString &toolTip, - QWidget *widget, QWidget *button) -{ - int row = m_layout->rowCount(); - addLabel(name, toolTip, row); - m_layout->addWidget(widget, row, WidgetColumn); - addButtonWidget(button, toolTip, row); -} - -void KitManagerConfigWidget::addLabel(const QString &name, const QString &toolTip, int row) +void KitManagerConfigWidget::setLabel(const QString &name, const QString &toolTip, int row) { static const Qt::Alignment alignment = static_cast<Qt::Alignment>(style()->styleHint(QStyle::SH_FormLayoutLabelAlignment)); @@ -271,13 +265,12 @@ void KitManagerConfigWidget::addLabel(const QString &name, const QString &toolTi m_layout->addWidget(label, row, LabelColumn, alignment); } -void KitManagerConfigWidget::addButtonWidget(QWidget *button, const QString &toolTip, int row) +void KitManagerConfigWidget::paintEvent(QPaintEvent *) { - if (!button) - return; - if (button->toolTip().isEmpty()) - button->setToolTip(toolTip); - m_layout->addWidget(button, row, ButtonColumn); + QPainter p(this); + if (m_background.size() != size()) + m_background = Utils::DetailsWidget::createBackground(size(), 0, this); + p.drawPixmap(rect(), m_background); } } // namespace Internal diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.h b/src/plugins/projectexplorer/kitmanagerconfigwidget.h index e10a82ea8b..8c969aa6cf 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.h +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.h @@ -32,8 +32,9 @@ #include "kitconfigwidget.h" +#include <QWidget> + QT_BEGIN_NAMESPACE -class QHBoxLayout; class QGridLayout; class QLineEdit; class QToolButton; @@ -49,7 +50,7 @@ class KitManagerConfigWidget : public QWidget Q_OBJECT public: - explicit KitManagerConfigWidget(Kit *k, QWidget *parent = 0); + explicit KitManagerConfigWidget(Kit *k); ~KitManagerConfigWidget(); QString displayName() const; @@ -68,8 +69,6 @@ public: bool isDefaultKit() const; void removeKit(); -public slots: - signals: void dirty(); @@ -86,11 +85,8 @@ private: ButtonColumn }; - void addToLayout(const QString &name, const QString &toolTip, QWidget *widget, QWidget *button = 0); - - - void addLabel(const QString &name, const QString &toolTip, int row); - void addButtonWidget(QWidget *button, const QString &toolTip, int row); + void setLabel(const QString &name, const QString &toolTip, int row); + void paintEvent(QPaintEvent *ev); QGridLayout *m_layout; QToolButton *m_iconButton; @@ -100,6 +96,7 @@ private: Kit *m_modifiedKit; bool m_isDefaultKit; bool m_fixingKit; + QPixmap m_background; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/kitmodel.cpp b/src/plugins/projectexplorer/kitmodel.cpp index de7d9ff30c..bbacfaca9b 100644 --- a/src/plugins/projectexplorer/kitmodel.cpp +++ b/src/plugins/projectexplorer/kitmodel.cpp @@ -364,8 +364,7 @@ KitNode *KitModel::findWorkingCopy(Kit *k) const KitNode *KitModel::createNode(KitNode *parent, Kit *k) { KitNode *node = new KitNode(parent, k); - node->widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_parentLayout->addWidget(node->widget, 10); + m_parentLayout->addWidget(node->widget); connect(node->widget, SIGNAL(dirty()), this, SLOT(setDirty())); return node; } diff --git a/src/plugins/projectexplorer/kitoptionspage.cpp b/src/plugins/projectexplorer/kitoptionspage.cpp index e61123c1a1..63c4ca15e1 100644 --- a/src/plugins/projectexplorer/kitoptionspage.cpp +++ b/src/plugins/projectexplorer/kitoptionspage.cpp @@ -85,7 +85,7 @@ QWidget *KitOptionsPage::createPage(QWidget *parent) buttonLayout->addWidget(m_cloneButton); buttonLayout->addWidget(m_delButton); buttonLayout->addWidget(m_makeDefaultButton); - buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + buttonLayout->addStretch(); QHBoxLayout *horizontalLayout = new QHBoxLayout(); horizontalLayout->addWidget(m_kitsView); @@ -96,6 +96,8 @@ QWidget *KitOptionsPage::createPage(QWidget *parent) m_model = new Internal::KitModel(verticalLayout); connect(m_model, SIGNAL(kitStateChanged()), this, SLOT(updateState())); + verticalLayout->setStretch(0, 1); + verticalLayout->setStretch(1, 0); m_kitsView->setModel(m_model); m_kitsView->header()->setResizeMode(0, QHeaderView::Stretch); diff --git a/src/plugins/projectexplorer/kitoptionspage.h b/src/plugins/projectexplorer/kitoptionspage.h index 0e72e8cd55..6b1a4a4c8b 100644 --- a/src/plugins/projectexplorer/kitoptionspage.h +++ b/src/plugins/projectexplorer/kitoptionspage.h @@ -47,9 +47,6 @@ namespace ProjectExplorer { namespace Internal { class KitModel; } class Kit; -class KitConfigWidget; -class KitFactory; -class KitManager; // -------------------------------------------------------------------------- // KitOptionsPage: diff --git a/src/plugins/projectexplorer/pluginfilefactory.cpp b/src/plugins/projectexplorer/pluginfilefactory.cpp index 60614b3f9e..15f9926705 100644 --- a/src/plugins/projectexplorer/pluginfilefactory.cpp +++ b/src/plugins/projectexplorer/pluginfilefactory.cpp @@ -65,7 +65,7 @@ QStringList ProjectFileFactory::mimeTypes() const Core::Id ProjectFileFactory::id() const { - return Constants::FILE_FACTORY_ID; + return Core::Id(Constants::FILE_FACTORY_ID); } QString ProjectFileFactory::displayName() const diff --git a/src/plugins/projectexplorer/processstep.cpp b/src/plugins/projectexplorer/processstep.cpp index 4549e23eb6..0b57d4d7ad 100644 --- a/src/plugins/projectexplorer/processstep.cpp +++ b/src/plugins/projectexplorer/processstep.cpp @@ -33,6 +33,7 @@ #include "buildconfiguration.h" #include "projectexplorerconstants.h" #include "target.h" +#include "kit.h" #include <coreplugin/idocument.h> #include <utils/qtcprocess.h> @@ -95,7 +96,9 @@ bool ProcessStep::init() pp->setWorkingDirectory(workingDirectory()); pp->setCommand(m_command); pp->setArguments(m_arguments); - setOutputParser(bc->createOutputParser()); + IOutputParser *parser = target()->kit()->createOutputParser(); + if (parser) + setOutputParser(parser); return AbstractProcessStep::init(); } diff --git a/src/plugins/projectexplorer/processstep.h b/src/plugins/projectexplorer/processstep.h index a9b47b6569..18d559becf 100644 --- a/src/plugins/projectexplorer/processstep.h +++ b/src/plugins/projectexplorer/processstep.h @@ -32,7 +32,8 @@ #include "ui_processstep.h" #include "abstractprocessstep.h" -#include "environment.h" + +#include <utils/environment.h> namespace ProjectExplorer { diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index a79362e6a5..261955c03b 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -32,7 +32,6 @@ #include "buildconfiguration.h" #include "deployconfiguration.h" #include "editorconfiguration.h" -#include "environment.h" #include "projectexplorer.h" #include "projectexplorerconstants.h" #include "projectnodes.h" @@ -48,6 +47,7 @@ #include <projectexplorer/kitmanager.h> #include <limits> #include <utils/qtcassert.h> +#include <utils/environment.h> /*! \class ProjectExplorer::Project @@ -306,10 +306,6 @@ bool Project::restoreSettings() return ok; } -QList<BuildConfigWidget*> Project::subConfigWidgets() -{ - return QList<BuildConfigWidget*>(); -} /*! \brief Serialize all data into a QVariantMap. @@ -425,7 +421,7 @@ QVariant Project::namedSettings(const QString &name) const return d->m_pluginSettings.value(name); } -void Project::setNamedSettings(const QString &name, QVariant &value) +void Project::setNamedSettings(const QString &name, const QVariant &value) { if (value.isNull()) d->m_pluginSettings.remove(name); diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index b67304cb80..cef039e816 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -45,11 +45,11 @@ class Context; namespace ProjectExplorer { -class BuildConfigWidget; class IProjectManager; class EditorConfiguration; class ProjectNode; class Kit; +class NamedWidget; class Target; class ProjectPrivate; @@ -97,8 +97,6 @@ public: void saveSettings(); bool restoreSettings(); - virtual QList<BuildConfigWidget*> subConfigWidgets(); - virtual ProjectNode *rootProjectNode() const = 0; enum FilesMode { AllFiles, ExcludeGeneratedFiles }; @@ -118,7 +116,7 @@ public: virtual Core::Context projectLanguage() const; QVariant namedSettings(const QString &name) const; - void setNamedSettings(const QString &name, QVariant &value); + void setNamedSettings(const QString &name, const QVariant &value); virtual bool needsConfiguration() const; virtual void configureAsExampleProject(const QStringList &platforms); diff --git a/src/plugins/projectexplorer/projectconfiguration.cpp b/src/plugins/projectexplorer/projectconfiguration.cpp index d4c01d8747..b6a6bfa716 100644 --- a/src/plugins/projectexplorer/projectconfiguration.cpp +++ b/src/plugins/projectexplorer/projectconfiguration.cpp @@ -102,7 +102,7 @@ QVariantMap ProjectConfiguration::toMap() const bool ProjectConfiguration::fromMap(const QVariantMap &map) { - m_id = Core::Id(map.value(QLatin1String(CONFIGURATION_ID_KEY), QByteArray()).toByteArray().constData()); + m_id = Core::Id(map.value(QLatin1String(CONFIGURATION_ID_KEY), QByteArray()).toByteArray()); m_displayName = map.value(QLatin1String(DISPLAY_NAME_KEY), QString()).toString(); m_defaultDisplayName = map.value(QLatin1String(DEFAULT_DISPLAY_NAME_KEY), m_defaultDisplayName.isEmpty() ? diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index c9a7aac6f4..a26be61a5d 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -35,6 +35,7 @@ #include "gcctoolchainfactories.h" #include "project.h" #include "projectexplorersettings.h" +#include "removetaskhandler.h" #include "kitmanager.h" #include "kitoptionspage.h" #include "target.h" @@ -154,10 +155,6 @@ namespace { bool debug = false; } -static const char kCurrentProjectPath[] = "CurrentProject:Path"; -static const char kCurrentProjectFilePath[] = "CurrentProject:FilePath"; -static const char kCurrentProjectBuildPath[] = "CurrentProject:BuildPath"; - namespace ProjectExplorer { struct ProjectExplorerPluginPrivate { @@ -393,6 +390,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er addAutoReleasedObject(new CopyTaskHandler); addAutoReleasedObject(new ShowInEditorTaskHandler); addAutoReleasedObject(new VcsAnnotateTaskHandler); + addAutoReleasedObject(new RemoveTaskHandler); addAutoReleasedObject(new CoreListener); d->m_outputPane = new AppOutputPane; @@ -988,12 +986,20 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er updateWelcomePage(); Core::VariableManager *vm = Core::VariableManager::instance(); - vm->registerVariable(kCurrentProjectFilePath, + vm->registerVariable(Constants::VAR_CURRENTPROJECT_FILEPATH, tr("Full path of the current project's main file, including file name.")); - vm->registerVariable(kCurrentProjectPath, + vm->registerVariable(Constants::VAR_CURRENTPROJECT_PATH, tr("Full path of the current project's main file, excluding file name.")); - vm->registerVariable(kCurrentProjectBuildPath, + vm->registerVariable(Constants::VAR_CURRENTPROJECT_BUILDPATH, tr("Full build path of the current project's active build configuration.")); + vm->registerVariable(Constants::VAR_CURRENTPROJECT_NAME, tr("The current project's name.")); + vm->registerVariable(Constants::VAR_CURRENTKIT_NAME, tr("The currently active kit's name.")); + vm->registerVariable(Constants::VAR_CURRENTKIT_FILESYSTEMNAME, + tr("The currently active kit's name in a filesystem friendly version.")); + vm->registerVariable(Constants::VAR_CURRENTKIT_ID, tr("The currently active kit's id.")); + vm->registerVariable(Constants::VAR_CURRENTBUILD_NAME, tr("The currently active build configuration's name.")); + vm->registerVariable(Constants::VAR_CURRENTBUILD_TYPE, tr("The currently active build configuration's type.")); + connect(vm, SIGNAL(variableUpdateRequested(QByteArray)), this, SLOT(updateVariable(QByteArray))); @@ -1067,7 +1073,12 @@ void ProjectExplorerPlugin::unloadProject() return; addToRecentProjects(document->fileName(), d->m_currentProject->displayName()); - d->m_session->removeProject(d->m_currentProject); + unloadProject(d->m_currentProject); +} + +void ProjectExplorerPlugin::unloadProject(Project *project) +{ + d->m_session->removeProject(project); updateActions(); } @@ -1081,6 +1092,8 @@ void ProjectExplorerPlugin::closeAllProjects() d->m_session->closeAllProjects(); updateActions(); + + Core::ModeManager::activateMode(Core::Id(Core::Constants::MODE_WELCOME)); } void ProjectExplorerPlugin::extensionsInitialized() @@ -1119,27 +1132,71 @@ void ProjectExplorerPlugin::loadCustomWizards() void ProjectExplorerPlugin::updateVariable(const QByteArray &variable) { - if (variable == kCurrentProjectFilePath) { + if (variable == Constants::VAR_CURRENTPROJECT_FILEPATH) { if (currentProject() && currentProject()->document()) { Core::VariableManager::instance()->insert(variable, currentProject()->document()->fileName()); } else { Core::VariableManager::instance()->remove(variable); } - } else if (variable == kCurrentProjectPath) { + } else if (variable == Constants::VAR_CURRENTPROJECT_PATH) { if (currentProject() && currentProject()->document()) { Core::VariableManager::instance()->insert(variable, QFileInfo(currentProject()->document()->fileName()).path()); } else { Core::VariableManager::instance()->remove(variable); } - } else if (variable == kCurrentProjectBuildPath) { + } else if (variable == Constants::VAR_CURRENTPROJECT_BUILDPATH) { if (currentProject() && currentProject()->activeTarget() && currentProject()->activeTarget()->activeBuildConfiguration()) { Core::VariableManager::instance()->insert(variable, currentProject()->activeTarget()->activeBuildConfiguration()->buildDirectory()); } else { Core::VariableManager::instance()->remove(variable); } + } else if (variable == Constants::VAR_CURRENTPROJECT_NAME) { + if (currentProject()) { + Core::VariableManager::instance()->insert(variable, currentProject()->displayName()); + } else { + Core::VariableManager::instance()->remove(variable); + } + } else if (variable == Constants::VAR_CURRENTKIT_NAME) { + if (currentProject() && currentProject()->activeTarget() && currentProject()->activeTarget()->kit()) { + Core::VariableManager::instance()->insert(variable, currentProject()->activeTarget()->kit()->displayName()); + } else { + Core::VariableManager::instance()->remove(variable); + } + } else if (variable == Constants::VAR_CURRENTKIT_FILESYSTEMNAME) { + if (currentProject() && currentProject()->activeTarget() && currentProject()->activeTarget()->kit()) { + Core::VariableManager::instance()->insert(variable, currentProject()->activeTarget()->kit()->fileSystemFriendlyName()); + } else { + Core::VariableManager::instance()->remove(variable); + } + } else if (variable == Constants::VAR_CURRENTKIT_ID) { + if (currentProject() && currentProject()->activeTarget() && currentProject()->activeTarget()->kit()) { + Core::VariableManager::instance()->insert(variable, currentProject()->activeTarget()->kit()->id().toString()); + } else { + Core::VariableManager::instance()->remove(variable); + } + } else if (variable == Constants::VAR_CURRENTBUILD_NAME) { + if (currentProject() && currentProject()->activeTarget() && currentProject()->activeTarget()->activeBuildConfiguration()) { + Core::VariableManager::instance()->insert(variable, currentProject()->activeTarget()->activeBuildConfiguration()->displayName()); + } else { + Core::VariableManager::instance()->remove(variable); + } + } else if (variable == Constants::VAR_CURRENTBUILD_TYPE) { + if (currentProject() && currentProject()->activeTarget() && currentProject()->activeTarget()->activeBuildConfiguration()) { + BuildConfiguration::BuildType type = currentProject()->activeTarget()->activeBuildConfiguration()->buildType(); + QString typeString; + if (type == BuildConfiguration::Debug) + typeString = tr("debug"); + else if (type == BuildConfiguration::Release) + typeString = tr("release"); + else + typeString = tr("unknown"); + Core::VariableManager::instance()->insert(variable, typeString); + } else { + Core::VariableManager::instance()->remove(variable); + } } } @@ -1447,6 +1504,21 @@ void ProjectExplorerPlugin::determineSessionToRestoreAtStartup() Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); } +// Return a list of glob patterns for project files ("*.pro", etc), use first, main pattern only. +static inline QStringList projectFileGlobs() +{ + QStringList result; + const Core::MimeDatabase *mimeDatabase = Core::ICore::instance()->mimeDatabase(); + foreach (const IProjectManager *ipm, ExtensionSystem::PluginManager::getObjects<IProjectManager>()) { + if (const Core::MimeType mimeType = mimeDatabase->findByType(ipm->mimeType())) { + const QList<Core::MimeGlobPattern> patterns = mimeType.globPatterns(); + if (!patterns.isEmpty()) + result.push_back(patterns.front().regExp().pattern()); + } + } + return result; +} + /*! \fn void ProjectExplorerPlugin::restoreSession() @@ -1462,8 +1534,55 @@ void ProjectExplorerPlugin::restoreSession() // We have command line arguments, try to find a session in them QStringList arguments = ExtensionSystem::PluginManager::arguments(); - arguments.removeOne(d->m_sessionToRestoreAtStartup); - + if (!d->m_sessionToRestoreAtStartup.isEmpty() && !arguments.isEmpty()) + arguments.removeOne(d->m_sessionToRestoreAtStartup); + + // Massage the argument list. + // Be smart about directories: If there is a session of that name, load it. + // Other than that, look for project files in it. The idea is to achieve + // 'Do what I mean' functionality when starting Creator in a directory with + // the single command line argument '.' and avoid editor warnings about not + // being able to open directories. + // In addition, convert "filename" "+45" or "filename" ":23" into + // "filename+45" and "filename:23". + if (!arguments.isEmpty()) { + const QStringList sessions = d->m_session->sessions(); + QStringList projectGlobs = projectFileGlobs(); + for (int a = 0; a < arguments.size(); ) { + const QString &arg = arguments.at(a); + const QFileInfo fi(arg); + if (fi.isDir()) { + const QDir dir(fi.absoluteFilePath()); + // Does the directory name match a session? + if (d->m_sessionToRestoreAtStartup.isEmpty() + && sessions.contains(dir.dirName())) { + d->m_sessionToRestoreAtStartup = dir.dirName(); + arguments.removeAt(a); + continue; + } else { + // Are there project files in that directory? + const QFileInfoList proFiles + = dir.entryInfoList(projectGlobs, QDir::Files); + if (!proFiles.isEmpty()) { + arguments[a] = proFiles.front().absoluteFilePath(); + ++a; + continue; + } + } + // Cannot handle: Avoid mime type warning for directory. + qWarning("Skipping directory '%s' passed on to command line.", + qPrintable(QDir::toNativeSeparators(arg))); + arguments.removeAt(a); + continue; + } // Done directories. + // Converts "filename" "+45" or "filename" ":23" into "filename+45" and "filename:23" + if (a && (arg.startsWith(QLatin1Char('+')) || arg.startsWith(QLatin1Char(':')))) { + arguments[a - 1].append(arguments.takeAt(a)); + continue; + } + ++a; + } // for arguments + } // !arguments.isEmpty() // Restore latest session or what was passed on the command line if (!d->m_sessionToRestoreAtStartup.isEmpty()) d->m_session->loadSession(d->m_sessionToRestoreAtStartup); @@ -1475,19 +1594,7 @@ void ProjectExplorerPlugin::restoreSession() connect(d->m_welcomePage, SIGNAL(requestSession(QString)), this, SLOT(loadSession(QString))); connect(d->m_welcomePage, SIGNAL(requestProject(QString)), this, SLOT(openProjectWelcomePage(QString))); - QStringList combinedList; - // Converts "filename" "+45" or "filename" ":23" - // into "filename+45" and "filename:23" - foreach (const QString &str, arguments) { - if (!combinedList.isEmpty() && (str.startsWith(QLatin1Char('+')) - || str.startsWith(QLatin1Char(':')))) { - combinedList.last().append(str); - } else { - combinedList << str; - } - } - - Core::ICore::openFiles(combinedList, Core::ICore::OpenFilesFlags(Core::ICore::CanContainLineNumbers | Core::ICore::SwitchMode)); + Core::ICore::openFiles(arguments, Core::ICore::OpenFilesFlags(Core::ICore::CanContainLineNumbers | Core::ICore::SwitchMode)); updateActions(); } @@ -2810,6 +2917,8 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &to) .arg(orgFilePath) .arg(newFilePath) .arg(projectNode->displayName())); + } else { + setCurrent(d->m_session->projectForFile(newFilePath), newFilePath, 0); } } } diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index 03e46fb9b2..e7105a38f3 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -81,6 +81,7 @@ public: Project *openProject(const QString &fileName, QString *error); QList<Project *> openProjects(const QStringList &fileNames, QString *error); Q_SLOT void openProjectWelcomePage(const QString &fileName); + void unloadProject(Project *project); SessionManager *session() const; diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index a4bd7003df..26185070f4 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -15,6 +15,7 @@ HEADERS += projectexplorer.h \ gcctoolchain.h \ projectexplorer_export.h \ projectwindow.h \ + removetaskhandler.h \ kit.h \ kitchooser.h \ kitconfigwidget.h \ @@ -134,6 +135,7 @@ SOURCES += projectexplorer.cpp \ clangparser.cpp \ gcctoolchain.cpp \ projectwindow.cpp \ + removetaskhandler.cpp \ kit.cpp \ kitchooser.cpp \ kitinformation.cpp \ diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 6c8b79753f..88c31b89ac 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -1,5 +1,7 @@ import qbs.base 1.0 + import "../QtcPlugin.qbs" as QtcPlugin +import "../../../qbs/defaults.js" as Defaults QtcPlugin { name: "ProjectExplorer" @@ -13,78 +15,95 @@ QtcPlugin { Depends { name: "cpp" } cpp.defines: base.concat(["QTC_CPU=X86Architecture"]) - cpp.includePaths: [ - ".", - "..", - "../../libs", - "../../libs/utils", + cpp.includePaths: base.concat([ "customwizard", - "publishing", - buildDirectory - ] + "publishing" + ]) files: [ - "doubletabwidget.ui", - "processstep.ui", - "projectexplorer.qrc", - "sessiondialog.ui", - "targetsettingswidget.ui", - "projectwizardpage.ui", + "abi.cpp", "abi.h", "abiwidget.cpp", "abiwidget.h", "abstractprocessstep.cpp", "abstractprocessstep.h", "allprojectsfilter.cpp", + "allprojectsfilter.h", "allprojectsfind.cpp", "allprojectsfind.h", "applicationlauncher.cpp", "applicationlauncher.h", + "applicationrunconfiguration.cpp", "applicationrunconfiguration.h", + "appoutputpane.cpp", "appoutputpane.h", "baseprojectwizarddialog.cpp", "baseprojectwizarddialog.h", + "buildconfiguration.cpp", "buildconfiguration.h", "buildconfigurationmodel.cpp", "buildconfigurationmodel.h", "buildenvironmentwidget.cpp", "buildenvironmentwidget.h", + "buildmanager.cpp", "buildmanager.h", + "buildprogress.cpp", "buildprogress.h", + "buildsettingspropertiespage.cpp", "buildsettingspropertiespage.h", "buildstep.cpp", + "buildstep.h", "buildsteplist.cpp", "buildsteplist.h", + "buildstepspage.cpp", "buildstepspage.h", + "buildtargetinfo.h", "cesdkhandler.cpp", "cesdkhandler.h", + "clangparser.cpp", "clangparser.h", + "codestylesettingspropertiespage.cpp", "codestylesettingspropertiespage.h", "codestylesettingspropertiespage.ui", "compileoutputwindow.cpp", "compileoutputwindow.h", + "copytaskhandler.cpp", "copytaskhandler.h", "corelistenercheckingforrunningbuild.cpp", "corelistenercheckingforrunningbuild.h", "currentprojectfilter.cpp", + "currentprojectfilter.h", "currentprojectfind.cpp", "currentprojectfind.h", + "dependenciespanel.cpp", "dependenciespanel.h", + "deployablefile.cpp", + "deployablefile.h", "deployconfiguration.cpp", "deployconfiguration.h", "deployconfigurationmodel.cpp", "deployconfigurationmodel.h", + "deploymentdata.h", + "doubletabwidget.cpp", "doubletabwidget.h", + "doubletabwidget.ui", "editorconfiguration.cpp", "editorconfiguration.h", + "editorsettingspropertiespage.cpp", "editorsettingspropertiespage.h", "editorsettingspropertiespage.ui", "environmentitemswidget.cpp", + "environmentitemswidget.h", + "environmentwidget.cpp", "environmentwidget.h", "foldernavigationwidget.cpp", "foldernavigationwidget.h", + "gccparser.cpp", "gccparser.h", + "gcctoolchain.cpp", + "gcctoolchain.h", "gcctoolchainfactories.h", + "gnumakeparser.cpp", "gnumakeparser.h", "headerpath.h", "ioutputparser.cpp", @@ -92,21 +111,6 @@ QtcPlugin { "iprojectmanager.h", "iprojectproperties.h", "itaskhandler.h", - "ldparser.h", - "linuxiccparser.h", - "metatypedeclarations.h", - "miniprojecttargetselector.h", - "namedwidget.cpp", - "namedwidget.h", - "nodesvisitor.cpp", - "nodesvisitor.h", - "outputparser_test.h", - "pluginfilefactory.cpp", - "pluginfilefactory.h", - "processparameters.cpp", - "processparameters.h", - "processstep.cpp", - "processstep.h", "kit.cpp", "kit.h", "kitchooser.cpp", @@ -124,29 +128,70 @@ QtcPlugin { "kitmodel.h", "kitoptionspage.cpp", "kitoptionspage.h", + "ldparser.cpp", + "ldparser.h", + "linuxiccparser.cpp", + "linuxiccparser.h", + "localapplicationruncontrol.cpp", + "localapplicationruncontrol.h", + "metatypedeclarations.h", + "miniprojecttargetselector.cpp", + "miniprojecttargetselector.h", + "namedwidget.cpp", + "namedwidget.h", + "nodesvisitor.cpp", + "nodesvisitor.h", + "outputparser_test.cpp", + "outputparser_test.h", + "pluginfilefactory.cpp", + "pluginfilefactory.h", + "processparameters.cpp", + "processparameters.h", + "processstep.cpp", + "processstep.h", + "processstep.ui", "project.cpp", "project.h", "projectconfiguration.cpp", "projectconfiguration.h", + "projectexplorer.cpp", + "projectexplorer.h", + "projectexplorer.qrc", "projectexplorer_export.h", + "projectexplorerconstants.h", + "projectexplorersettings.h", + "projectexplorersettingspage.cpp", "projectexplorersettingspage.h", + "projectexplorersettingspage.ui", "projectfilewizardextension.cpp", "projectfilewizardextension.h", "projectmodels.cpp", "projectmodels.h", "projectnodes.cpp", "projectnodes.h", + "projecttreewidget.cpp", "projecttreewidget.h", + "projectwelcomepage.cpp", "projectwelcomepage.h", "projectwindow.cpp", "projectwindow.h", + "projectwizardpage.cpp", "projectwizardpage.h", + "projectwizardpage.ui", + "removetaskhandler.cpp", + "removetaskhandler.h", + "runconfiguration.cpp", + "runconfiguration.h", "runconfigurationmodel.cpp", "runconfigurationmodel.h", "runsettingspropertiespage.cpp", "runsettingspropertiespage.h", + "session.cpp", "session.h", + "sessiondialog.cpp", "sessiondialog.h", + "sessiondialog.ui", + "settingsaccessor.cpp", "settingsaccessor.h", "showineditortaskhandler.cpp", "showineditortaskhandler.h", @@ -160,87 +205,74 @@ QtcPlugin { "targetsettingspanel.h", "targetsettingswidget.cpp", "targetsettingswidget.h", + "targetsettingswidget.ui", "task.cpp", "task.h", "taskhub.cpp", "taskhub.h", + "taskmodel.cpp", "taskmodel.h", + "taskwindow.cpp", "taskwindow.h", "toolchain.cpp", "toolchain.h", "toolchainconfigwidget.cpp", "toolchainconfigwidget.h", - "toolchainmanager.h", - "toolchainoptionspage.h", - "vcsannotatetaskhandler.h", - "environmentitemswidget.h", - "abi.cpp", - "allprojectsfilter.h", - "applicationrunconfiguration.cpp", - "appoutputpane.cpp", - "buildconfiguration.cpp", - "buildmanager.cpp", - "buildprogress.cpp", - "buildsettingspropertiespage.cpp", - "buildstep.h", - "buildstepspage.cpp", - "clangparser.cpp", - "codestylesettingspropertiespage.cpp", - "copytaskhandler.cpp", - "currentprojectfilter.h", - "dependenciespanel.cpp", - "doubletabwidget.cpp", - "editorsettingspropertiespage.cpp", - "environmentwidget.cpp", - "gccparser.cpp", - "gcctoolchain.cpp", - "gcctoolchain.h", - "gnumakeparser.cpp", - "ldparser.cpp", - "linuxiccparser.cpp", - "localapplicationruncontrol.cpp", - "localapplicationruncontrol.h", - "miniprojecttargetselector.cpp", - "outputparser_test.cpp", - "projectexplorer.cpp", - "projectexplorer.h", - "projectexplorerconstants.h", - "projectexplorersettings.h", - "projectexplorersettingspage.cpp", - "projectexplorersettingspage.ui", - "projecttreewidget.cpp", - "projectwelcomepage.cpp", - "projectwizardpage.cpp", - "runconfiguration.cpp", - "runconfiguration.h", - "session.cpp", - "sessiondialog.cpp", - "settingsaccessor.cpp", - "taskmodel.cpp", - "taskwindow.cpp", "toolchainmanager.cpp", + "toolchainmanager.h", "toolchainoptionspage.cpp", + "toolchainoptionspage.h", "vcsannotatetaskhandler.cpp", + "vcsannotatetaskhandler.h", + "customwizard/customwizard.cpp", "customwizard/customwizard.h", "customwizard/customwizardpage.cpp", "customwizard/customwizardpage.h", + "customwizard/customwizardparameters.cpp", "customwizard/customwizardparameters.h", "customwizard/customwizardpreprocessor.cpp", "customwizard/customwizardpreprocessor.h", "customwizard/customwizardscriptgenerator.cpp", "customwizard/customwizardscriptgenerator.h", - "customwizard/customwizard.cpp", - "customwizard/customwizardparameters.cpp", - "deployablefile.h", - "deployablefile.cpp", - "deploymentdata.h", - "buildtargetinfo.h", + "devicesupport/desktopdevice.cpp", + "devicesupport/desktopdevice.h", + "devicesupport/desktopdevicefactory.cpp", + "devicesupport/desktopdevicefactory.h", + "devicesupport/deviceapplicationrunner.cpp", + "devicesupport/deviceapplicationrunner.h", + "devicesupport/devicefactoryselectiondialog.cpp", + "devicesupport/devicefactoryselectiondialog.h", + "devicesupport/devicefactoryselectiondialog.ui", + "devicesupport/devicemanager.cpp", + "devicesupport/devicemanager.h", + "devicesupport/devicemanagermodel.cpp", + "devicesupport/devicemanagermodel.h", + "devicesupport/deviceprocessesdialog.cpp", + "devicesupport/deviceprocessesdialog.h", + "devicesupport/deviceprocesslist.cpp", + "devicesupport/deviceprocesslist.h", + "devicesupport/devicesettingspage.cpp", + "devicesupport/devicesettingspage.h", + "devicesupport/devicesettingswidget.cpp", + "devicesupport/devicesettingswidget.h", + "devicesupport/devicesettingswidget.ui", + "devicesupport/deviceusedportsgatherer.cpp", + "devicesupport/deviceusedportsgatherer.h", + "devicesupport/idevice.cpp", + "devicesupport/idevice.h", + "devicesupport/idevicefactory.cpp", + "devicesupport/idevicefactory.h", + "devicesupport/idevicewidget.h", + "devicesupport/localprocesslist.cpp", + "devicesupport/localprocesslist.h", + "devicesupport/sshdeviceprocesslist.cpp", + "devicesupport/sshdeviceprocesslist.h", "images/BuildSettings.png", "images/CodeStyleSettings.png", + "images/Desktop.png", "images/DeviceConnected.png", "images/DeviceDisconnected.png", "images/DeviceReadyToUse.png", - "images/Desktop.png", "images/EditorSettings.png", "images/MaemoDevice.png", "images/ProjectDependencies.png", @@ -269,75 +301,45 @@ QtcPlugin { "images/session.png", "images/stop.png", "images/stop_small.png", - "images/targetleftbutton.png", - "images/targetrightbutton.png", "images/targetbuildselected.png", + "images/targetleftbutton.png", "images/targetpanel_bottom.png", "images/targetpanel_gradient.png", "images/targetremovebutton.png", "images/targetremovebuttondark.png", + "images/targetrightbutton.png", "images/targetrunselected.png", "images/targetseparatorbackground.png", "images/targetunselected.png", "images/window.png", - "publishing/publishingwizardselectiondialog.ui", "publishing/ipublishingwizardfactory.h", "publishing/publishingwizardselectiondialog.cpp", "publishing/publishingwizardselectiondialog.h", - "devicesupport/idevice.h", - "devicesupport/idevice.cpp", - "devicesupport/desktopdevice.cpp", - "devicesupport/desktopdevice.h", - "devicesupport/desktopdevicefactory.cpp", - "devicesupport/desktopdevicefactory.h", - "devicesupport/devicemanager.h", - "devicesupport/devicemanager.cpp", - "devicesupport/devicemanagermodel.h", - "devicesupport/devicemanagermodel.cpp", - "devicesupport/devicesettingspage.h", - "devicesupport/devicesettingspage.cpp", - "devicesupport/devicefactoryselectiondialog.cpp", - "devicesupport/devicefactoryselectiondialog.h", - "devicesupport/devicefactoryselectiondialog.ui", - "devicesupport/deviceprocesslist.cpp", - "devicesupport/deviceprocesslist.h", - "devicesupport/sshdeviceprocesslist.cpp", - "devicesupport/sshdeviceprocesslist.h", - "devicesupport/deviceprocessesdialog.cpp", - "devicesupport/deviceprocessesdialog.h", - "devicesupport/devicesettingswidget.cpp", - "devicesupport/devicesettingswidget.h", - "devicesupport/devicesettingswidget.ui", - "devicesupport/deviceusedportsgatherer.cpp", - "devicesupport/deviceusedportsgatherer.h", - "devicesupport/idevicewidget.h", - "devicesupport/idevicefactory.cpp", - "devicesupport/idevicefactory.h", - "devicesupport/deviceapplicationrunner.cpp", - "devicesupport/deviceapplicationrunner.h", - "devicesupport/localprocesslist.h", - "devicesupport/localprocesslist.cpp" + "publishing/publishingwizardselectiondialog.ui", ] Group { - condition: qbs.targetOS == "windows" + condition: qbs.targetOS == "windows" || Defaults.testsEnabled(qbs) files: [ - "wincetoolchain.cpp", - "wincetoolchain.h", - "windebuginterface.cpp", - "windebuginterface.h", + "abstractmsvctoolchain.cpp", + "abstractmsvctoolchain.h", "msvcparser.cpp", "msvcparser.h", "msvctoolchain.cpp", "msvctoolchain.h", - "abstractmsvctoolchain.cpp", - "abstractmsvctoolchain.h" + "wincetoolchain.cpp", + "wincetoolchain.h", + "windebuginterface.cpp", + "windebuginterface.h", ] } + Group { + condition: Defaults.testsEnabled(qbs) + files: ["outputparser_test.h", "outputparser_test.cpp"] + } + ProductModule { - Depends { name: "cpp" } - Depends { name: "Qt"; submodules: ["network"] } - cpp.includePaths: [".."] + Depends { name: "Qt.network" } } } diff --git a/src/plugins/projectexplorer/projectexplorer.qrc b/src/plugins/projectexplorer/projectexplorer.qrc index b36371d106..85ea369bbe 100644 --- a/src/plugins/projectexplorer/projectexplorer.qrc +++ b/src/plugins/projectexplorer/projectexplorer.qrc @@ -40,7 +40,7 @@ <file>images/unconfigured.png</file> <file>images/targetleftbutton.png</file> <file>images/targetrightbutton.png</file> - <file>images/targetremovebutton.png</file> - <file>images/targetremovebuttondark.png</file> + <file>images/targetchangebutton.png</file> + <file>images/targetchangebutton2.png</file> </qresource> </RCC> diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 4359e7cae1..cdf2408e75 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -235,6 +235,17 @@ const char DEFAULT_WORKING_DIR[] = "%{buildDir}"; const char DESKTOP_DEVICE_ID[] = "Desktop Device"; const char DESKTOP_DEVICE_TYPE[] = "Desktop"; +// Variable Names: +const char VAR_CURRENTPROJECT_PATH[] = "CurrentProject:Path"; +const char VAR_CURRENTPROJECT_FILEPATH[] = "CurrentProject:FilePath"; +const char VAR_CURRENTPROJECT_BUILDPATH[] = "CurrentProject:BuildPath"; +const char VAR_CURRENTPROJECT_NAME[] = "CurrentProject:Name"; +const char VAR_CURRENTKIT_NAME[] = "CurrentKit:Name"; +const char VAR_CURRENTKIT_FILESYSTEMNAME[] = "CurrentKit:FileSystemName"; +const char VAR_CURRENTKIT_ID[] = "CurrentKit:Id"; +const char VAR_CURRENTBUILD_NAME[] = "CurrentBuild:Name"; +const char VAR_CURRENTBUILD_TYPE[] = "CurrentBuild:Type"; + } // namespace Constants // Run modes diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.cpp b/src/plugins/projectexplorer/projectexplorersettingspage.cpp index b840ab16b4..ce6125e714 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.cpp +++ b/src/plugins/projectexplorer/projectexplorersettingspage.cpp @@ -32,8 +32,10 @@ #include "projectexplorerconstants.h" #include "projectexplorer.h" -#include <coreplugin/icore.h> +#include <coreplugin/coreconstants.h> #include <coreplugin/documentmanager.h> +#include <coreplugin/icore.h> +#include <utils/hostosinfo.h> #include <QLabel> #include <QCoreApplication> @@ -47,13 +49,15 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget(QWidget *parent) : QWidget(parent) { m_ui.setupUi(this); -#ifndef Q_OS_WIN - setJomVisible(false); -#endif + setJomVisible(Utils::HostOsInfo::isWindowsHost()); m_ui.directoryButtonGroup->setId(m_ui.currentDirectoryRadioButton, UseCurrentDirectory); m_ui.directoryButtonGroup->setId(m_ui.directoryRadioButton, UseProjectDirectory); + m_ui.buildDirectoryEdit->setProperty(Core::Constants::VARIABLE_SUPPORT_PROPERTY, true); + connect(m_ui.directoryButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotDirectoryButtonGroupChanged())); + connect(m_ui.resetButton, SIGNAL(clicked()), this, SLOT(resetDefaultBuildDirectory())); + connect(m_ui.buildDirectoryEdit, SIGNAL(textChanged(QString)), this, SLOT(updateResetButton())); } void ProjectExplorerSettingsWidget::setJomVisible(bool v) @@ -119,9 +123,30 @@ void ProjectExplorerSettingsWidget::setUseProjectsDirectory(bool b) } } +QString ProjectExplorerSettingsWidget::buildDirectory() const +{ + return m_ui.buildDirectoryEdit->text(); +} + +void ProjectExplorerSettingsWidget::setBuildDirectory(const QString &bd) +{ + m_ui.buildDirectoryEdit->setText(bd); +} + void ProjectExplorerSettingsWidget::slotDirectoryButtonGroupChanged() { - m_ui.projectsDirectoryPathChooser->setEnabled(useProjectsDirectory()); + bool enable = useProjectsDirectory(); + m_ui.projectsDirectoryPathChooser->setEnabled(enable); +} + +void ProjectExplorerSettingsWidget::resetDefaultBuildDirectory() +{ + setBuildDirectory(QLatin1String(Core::Constants::DEFAULT_BUILD_DIRECTORY)); +} + +void ProjectExplorerSettingsWidget::updateResetButton() +{ + m_ui.resetButton->setEnabled(buildDirectory() != QLatin1String(Core::Constants::DEFAULT_BUILD_DIRECTORY)); } QString ProjectExplorerSettingsWidget::searchKeywords() const @@ -168,6 +193,7 @@ QWidget *ProjectExplorerSettingsPage::createPage(QWidget *parent) m_widget->setSettings(ProjectExplorerPlugin::instance()->projectExplorerSettings()); m_widget->setProjectsDirectory(Core::DocumentManager::projectsDirectory()); m_widget->setUseProjectsDirectory(Core::DocumentManager::useProjectsDirectory()); + m_widget->setBuildDirectory(Core::DocumentManager::buildDirectory()); if (m_searchKeywords.isEmpty()) m_searchKeywords = m_widget->searchKeywords(); return m_widget; @@ -179,6 +205,7 @@ void ProjectExplorerSettingsPage::apply() ProjectExplorerPlugin::instance()->setProjectExplorerSettings(m_widget->settings()); Core::DocumentManager::setProjectsDirectory(m_widget->projectsDirectory()); Core::DocumentManager::setUseProjectsDirectory(m_widget->useProjectsDirectory()); + Core::DocumentManager::setBuildDirectory(m_widget->buildDirectory()); } } diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.h b/src/plugins/projectexplorer/projectexplorersettingspage.h index ad6e928db5..3e0a606ed2 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.h +++ b/src/plugins/projectexplorer/projectexplorersettingspage.h @@ -55,10 +55,15 @@ public: bool useProjectsDirectory(); void setUseProjectsDirectory(bool v); + QString buildDirectory() const; + void setBuildDirectory(const QString &bd); + QString searchKeywords() const; private slots: void slotDirectoryButtonGroupChanged(); + void resetDefaultBuildDirectory(); + void updateResetButton(); private: void setJomVisible(bool); diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.ui b/src/plugins/projectexplorer/projectexplorersettingspage.ui index 6f13f17fd7..7963fd4bc7 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.ui +++ b/src/plugins/projectexplorer/projectexplorersettingspage.ui @@ -20,6 +20,9 @@ <property name="fieldGrowthPolicy"> <enum>QFormLayout::ExpandingFieldsGrow</enum> </property> + <property name="labelAlignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> <item row="0" column="0" colspan="2"> <widget class="QRadioButton" name="currentDirectoryRadioButton"> <property name="text"> @@ -44,7 +47,7 @@ </widget> </item> <item row="1" column="1"> - <widget class="Utils::PathChooser" name="projectsDirectoryPathChooser" native="true"/> + <widget class="Utils::PathChooser" name="projectsDirectoryPathChooser"/> </item> </layout> </widget> @@ -107,7 +110,7 @@ </property> </widget> </item> - <item row="3" column="1" rowspan="2"> + <item row="3" column="1"> <widget class="QWidget" name="widget" native="true"> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="margin"> @@ -146,7 +149,21 @@ </layout> </widget> </item> - <item row="7" column="0"> + <item row="4" column="0"> + <widget class="QCheckBox" name="showRunOutputCheckBox"> + <property name="text"> + <string>Open application output pane when running</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QCheckBox" name="showDebugOutputCheckBox"> + <property name="text"> + <string>Open application output pane when debugging</string> + </property> + </widget> + </item> + <item row="6" column="0"> <widget class="QCheckBox" name="promptToStopRunControlCheckBox"> <property name="toolTip"> <string>Ask before terminating the running application in response to clicking the stop button in Application Output.</string> @@ -156,7 +173,7 @@ </property> </widget> </item> - <item row="8" column="0" colspan="2"> + <item row="7" column="0" colspan="2"> <layout class="QVBoxLayout" name="verticalLayout"> <property name="spacing"> <number>0</number> @@ -189,19 +206,29 @@ </item> </layout> </item> - <item row="5" column="0"> - <widget class="QCheckBox" name="showRunOutputCheckBox"> - <property name="text"> - <string>Open application output pane when running</string> - </property> - </widget> - </item> - <item row="6" column="0"> - <widget class="QCheckBox" name="showDebugOutputCheckBox"> - <property name="text"> - <string>Open application output pane when debugging</string> + <item row="8" column="0" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>12</number> </property> - </widget> + <item> + <widget class="QLabel" name="buildDirLabel"> + <property name="text"> + <string>Default Build Directory:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="buildDirectoryEdit"/> + </item> + <item> + <widget class="QPushButton" name="resetButton"> + <property name="text"> + <string>Reset</string> + </property> + </widget> + </item> + </layout> </item> </layout> <zorder>saveAllFilesCheckBox</zorder> @@ -235,8 +262,9 @@ <customwidgets> <customwidget> <class>Utils::PathChooser</class> - <extends>QWidget</extends> - <header location="global">utils/pathchooser.h</header> + <extends>QLineEdit</extends> + <header>utils/pathchooser.h</header> + <container>1</container> </customwidget> </customwidgets> <resources/> diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp index bf30a98c86..6900eac0f3 100644 --- a/src/plugins/projectexplorer/projectfilewizardextension.cpp +++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp @@ -524,9 +524,9 @@ bool ProjectFileWizardExtension::processVersionControl(const QList<Core::Generat return true; } -static TextEditor::ICodeStylePreferences *codeStylePreferences(ProjectExplorer::Project *project, const QString &languageId) +static TextEditor::ICodeStylePreferences *codeStylePreferences(ProjectExplorer::Project *project, Core::Id languageId) { - if (languageId.isEmpty()) + if (!languageId.isValid()) return 0; if (project) @@ -542,9 +542,9 @@ void ProjectFileWizardExtension::applyCodeStyle(Core::GeneratedFile *file) const const Core::MimeDatabase *mdb = Core::ICore::mimeDatabase(); Core::MimeType mt = mdb->findByFile(QFileInfo(file->path())); - const QString languageId = TextEditor::TextEditorSettings::instance()->languageId(mt.type()); + Core::Id languageId = TextEditor::TextEditorSettings::instance()->languageId(mt.type()); - if (languageId.isEmpty()) + if (!languageId.isValid()) return; // don't modify files like *.ui *.pro ProjectNode *project = 0; diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index 444023641c..38c6afe261 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -258,7 +258,20 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const if (Node *node = nodeForIndex(index)) { FolderNode *folderNode = qobject_cast<FolderNode*>(node); switch (role) { - case Qt::DisplayRole: + case Qt::DisplayRole: { + QString name = node->displayName(); + + if (node->parentFolderNode() + && node->parentFolderNode()->nodeType() == SessionNodeType) { + const QString vcsTopic = node->vcsTopic(); + + if (!vcsTopic.isEmpty()) + name += " (" + vcsTopic + ")"; + } + + result = name; + break; + } case Qt::EditRole: { result = node->displayName(); break; @@ -451,8 +464,9 @@ void FlatModel::setStartupProject(ProjectNode *projectNode) void FlatModel::reset() { + beginResetModel(); m_childNodes.clear(); - QAbstractItemModel::reset(); + endResetModel(); } QModelIndex FlatModel::indexForNode(const Node *node_) diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 586be2d5f7..4444996627 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -34,6 +34,9 @@ #include <coreplugin/mimedatabase.h> #include <coreplugin/fileiconprovider.h> +#include <coreplugin/icore.h> +#include <coreplugin/iversioncontrol.h> +#include <coreplugin/vcsmanager.h> #include <utils/qtcassert.h> #include <QFileInfo> @@ -104,6 +107,11 @@ QString Node::displayName() const return QFileInfo(path()).fileName(); } +QString Node::vcsTopic() const +{ + return QString(); +} + QString Node::tooltip() const { return QDir::toNativeSeparators(path()); @@ -269,6 +277,16 @@ ProjectNode::ProjectNode(const QString &projectFilePath) setDisplayName(QFileInfo(projectFilePath).fileName()); } +QString ProjectNode::vcsTopic() const { + const QString dir = QFileInfo(path()).absolutePath(); + + if (Core::IVersionControl *const vc = + Core::ICore::vcsManager()->findVersionControlForDirectory(dir)) + return vc->vcsTopic(dir); + + return QString(); +} + QList<ProjectNode*> ProjectNode::subProjectNodes() const { return m_subProjectNodes; diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index d57765ada5..5cbdee4a9a 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -86,6 +86,7 @@ public: FolderNode *parentFolderNode() const; // parent folder or project QString path() const; // file system path virtual QString displayName() const; + virtual QString vcsTopic() const; virtual QString tooltip() const; protected: @@ -183,6 +184,8 @@ public: HasSubProjectRunConfigurations }; + QString vcsTopic() const; + // all subFolders that are projects QList<ProjectNode*> subProjectNodes() const; diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index a23efe5289..f1c4ab9f65 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -110,7 +110,8 @@ bool SessionModel::isDefaultVirgin() const void SessionModel::resetSessions() { - reset(); + beginResetModel(); + endResetModel(); } void SessionModel::cloneSession(const QString &session) @@ -123,8 +124,9 @@ void SessionModel::cloneSession(const QString &session) QString newSession = newSessionInputDialog.value(); if (newSession.isEmpty() || m_manager->sessions().contains(newSession)) return; + beginResetModel(); m_manager->cloneSession(session, newSession); - reset(); + endResetModel(); if (newSessionInputDialog.isSwitchToRequested()) { m_manager->loadSession(newSession); @@ -134,8 +136,9 @@ void SessionModel::cloneSession(const QString &session) void SessionModel::deleteSession(const QString &session) { + beginResetModel(); m_manager->deleteSession(session); - reset(); + endResetModel(); } void SessionModel::renameSession(const QString &session) @@ -148,8 +151,9 @@ void SessionModel::renameSession(const QString &session) QString newSession = newSessionInputDialog.value(); if (newSession.isEmpty() || m_manager->sessions().contains(newSession)) return; + beginResetModel(); m_manager->renameSession(session, newSession); - reset(); + endResetModel(); if (newSessionInputDialog.isSwitchToRequested()) { m_manager->loadSession(newSession); @@ -193,7 +197,8 @@ QVariant ProjectModel::data(const QModelIndex &index, int role) const void ProjectModel::resetProjects() { - reset(); + beginResetModel(); + endResetModel(); } /////////////////// diff --git a/src/plugins/projectexplorer/removetaskhandler.cpp b/src/plugins/projectexplorer/removetaskhandler.cpp new file mode 100644 index 0000000000..fa75bf791d --- /dev/null +++ b/src/plugins/projectexplorer/removetaskhandler.cpp @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: http://www.qt-project.org/ +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +**************************************************************************/ + +#include "removetaskhandler.h" + +#include "projectexplorer.h" +#include "task.h" +#include "taskhub.h" + +#include <coreplugin/coreconstants.h> + +#include <QDir> +#include <QAction> +#include <QApplication> +#include <QClipboard> + +using namespace ProjectExplorer::Internal; + +void RemoveTaskHandler::handle(const ProjectExplorer::Task &task) +{ + ProjectExplorerPlugin::instance()->taskHub()->removeTask(task); +} + +QAction *RemoveTaskHandler::createAction(QObject *parent) const +{ + QAction *removeAction = new QAction(tr("Remove", "Name of the action triggering the removetaskhandler"), parent); + removeAction->setToolTip(tr("Remove task from the task list")); + removeAction->setShortcut(QKeySequence(QKeySequence::Delete)); + removeAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); + return removeAction; +} diff --git a/src/plugins/projectexplorer/removetaskhandler.h b/src/plugins/projectexplorer/removetaskhandler.h new file mode 100644 index 0000000000..e13258e9bf --- /dev/null +++ b/src/plugins/projectexplorer/removetaskhandler.h @@ -0,0 +1,54 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: http://www.qt-project.org/ +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +**************************************************************************/ + +#ifndef PROJECTEXPLORER_REMOVETASKHANDLER_H +#define PROJECTEXPLORER_REMOVETASKHANDLER_H + +#include "itaskhandler.h" + +namespace ProjectExplorer { +namespace Internal { + +class RemoveTaskHandler : public ITaskHandler +{ + Q_OBJECT + +public: + RemoveTaskHandler() {} + + bool canHandle(const Task &) const { return true; } + void handle(const Task &task); + QAction *createAction(QObject *parent) const; +}; + +} // namespace Internal +} // namespace ProjectExplorer + +#endif // PROJECTEXPLORER_REMOVETASKHANDLER_H diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 64c7059787..29e5e53a3d 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -122,16 +122,17 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(RunConfiguration m_suppressQmlDebuggingSpinbox(false) {} -DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(DebuggerRunConfigurationAspect *other) : - m_runConfiguration(other->m_runConfiguration), - m_useCppDebugger(other->m_useCppDebugger), - m_useQmlDebugger(other->m_useQmlDebugger), - m_qmlDebugServerPort(other->m_qmlDebugServerPort), - m_useMultiProcess(other->m_useMultiProcess), - m_suppressDisplay(other->m_suppressDisplay), - m_suppressQmlDebuggingOptions(other->m_suppressQmlDebuggingOptions), - m_suppressCppDebuggingOptions(other->m_suppressCppDebuggingOptions), - m_suppressQmlDebuggingSpinbox(other->m_suppressQmlDebuggingSpinbox) +DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration, + DebuggerRunConfigurationAspect *other) + : m_runConfiguration(runConfiguration), + m_useCppDebugger(other->m_useCppDebugger), + m_useQmlDebugger(other->m_useQmlDebugger), + m_qmlDebugServerPort(other->m_qmlDebugServerPort), + m_useMultiProcess(other->m_useMultiProcess), + m_suppressDisplay(other->m_suppressDisplay), + m_suppressQmlDebuggingOptions(other->m_suppressQmlDebuggingOptions), + m_suppressCppDebuggingOptions(other->m_suppressCppDebuggingOptions), + m_suppressQmlDebuggingSpinbox(other->m_suppressQmlDebuggingSpinbox) {} RunConfiguration *DebuggerRunConfigurationAspect::runConfiguration() @@ -289,10 +290,18 @@ RunConfiguration::RunConfiguration(Target *target, const Core::Id id) : RunConfiguration::RunConfiguration(Target *target, RunConfiguration *source) : ProjectConfiguration(target, source), - m_debuggerAspect(new DebuggerRunConfigurationAspect(source->debuggerAspect())) + m_debuggerAspect(new DebuggerRunConfigurationAspect(this, source->debuggerAspect())) { Q_ASSERT(target); - addExtraAspects(); + QList<IRunControlFactory *> factories = ExtensionSystem::PluginManager::getObjects<IRunControlFactory>(); + foreach (IRunConfigurationAspect *aspect, source->m_aspects) { + foreach (IRunControlFactory *factory, factories) { + if (IRunConfigurationAspect *clone = factory->cloneRunConfigurationAspect(aspect)) { + m_aspects.append(clone); + break; + } + } + } } RunConfiguration::~RunConfiguration() @@ -460,6 +469,17 @@ IRunConfigurationFactory *IRunConfigurationFactory::find(Target *parent, const Q return 0; } +IRunConfigurationFactory *IRunConfigurationFactory::find(Target *parent, RunConfiguration *rc) +{ + QList<IRunConfigurationFactory *> factories + = ExtensionSystem::PluginManager::instance()->getObjects<IRunConfigurationFactory>(); + foreach (IRunConfigurationFactory *factory, factories) { + if (factory->canClone(parent, rc)) + return factory; + } + return 0; +} + QList<IRunConfigurationFactory *> IRunConfigurationFactory::find(Target *parent) { QList<IRunConfigurationFactory *> factories @@ -510,6 +530,12 @@ IRunConfigurationAspect *IRunControlFactory::createRunConfigurationAspect() return 0; } +IRunConfigurationAspect *IRunControlFactory::cloneRunConfigurationAspect(IRunConfigurationAspect *source) +{ + Q_UNUSED(source); + return 0; +} + RunConfigWidget *IRunControlFactory::createConfigurationWidget(RunConfiguration *) { return 0; diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index a4274553d2..c846606d31 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -37,7 +37,7 @@ #include <utils/outputformat.h> #include <QMetaType> -#include <QWeakPointer> +#include <QPointer> #include <QWidget> QT_FORWARD_DECLARE_CLASS(QIcon) @@ -90,7 +90,7 @@ class PROJECTEXPLORER_EXPORT DebuggerRunConfigurationAspect public: DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration); - DebuggerRunConfigurationAspect(DebuggerRunConfigurationAspect *other); + DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration, DebuggerRunConfigurationAspect *other); enum QmlDebuggerStatus { DisableQmlDebugger = 0, @@ -213,6 +213,7 @@ public: virtual RunConfiguration *clone(Target *parent, RunConfiguration *product) = 0; static IRunConfigurationFactory *find(Target *parent, const QVariantMap &map); + static IRunConfigurationFactory *find(Target *parent, RunConfiguration *rc); static QList<IRunConfigurationFactory *> find(Target *parent); signals: @@ -234,6 +235,7 @@ public: virtual QString displayName() const = 0; virtual IRunConfigurationAspect *createRunConfigurationAspect(); + virtual IRunConfigurationAspect *cloneRunConfigurationAspect(IRunConfigurationAspect *); virtual RunConfigWidget *createConfigurationWidget(RunConfiguration *runConfiguration); }; @@ -304,7 +306,7 @@ protected: private: QString m_displayName; RunMode m_runMode; - const QWeakPointer<RunConfiguration> m_runConfiguration; + const QPointer<RunConfiguration> m_runConfiguration; Utils::OutputFormatter *m_outputFormatter; // A handle to the actual application process. diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp index d00f19f21b..bf19e13c59 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp @@ -496,11 +496,9 @@ void RunSettingsWidget::updateDeployConfiguration(DeployConfiguration *dc) m_deployConfigurationCombo->setCurrentIndex(actDc.row()); m_ignoreChange = false; - m_deployConfigurationWidget = dc->configurationWidget(); - if (m_deployConfigurationWidget) { - m_deployConfigurationWidget->init(dc); + m_deployConfigurationWidget = dc->createConfigWidget(); + if (m_deployConfigurationWidget) m_deployLayout->addWidget(m_deployConfigurationWidget); - } m_deploySteps = new BuildStepListWidget; m_deploySteps->init(dc->stepList()); diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.h b/src/plugins/projectexplorer/runsettingspropertiespage.h index d16b98fad9..ada616eea8 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.h +++ b/src/plugins/projectexplorer/runsettingspropertiespage.h @@ -47,8 +47,8 @@ QT_END_NAMESPACE namespace ProjectExplorer { class DeployConfiguration; -class DeployConfigurationWidget; class DeployConfigurationModel; +class NamedWidget; class RunConfiguration; class RunConfigurationModel; class RunConfigWidget; @@ -107,7 +107,7 @@ private: DeployConfigurationModel *m_deployConfigurationModel; QWidget *m_runConfigurationWidget; QVBoxLayout *m_runLayout; - DeployConfigurationWidget *m_deployConfigurationWidget; + NamedWidget *m_deployConfigurationWidget; QVBoxLayout *m_deployLayout; BuildStepListWidget *m_deploySteps; QMenu *m_addRunMenu; diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index e3901a94fc..afc48940eb 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -49,6 +49,7 @@ #include <utils/listutils.h> #include <utils/qtcassert.h> +#include <utils/stylehelper.h> #include <QDebug> #include <QDir> @@ -316,6 +317,15 @@ bool SessionManager::save() if (m_startupProject) data.insert(QLatin1String("StartupProject"), m_startupProject->document()->fileName()); + QColor c = Utils::StyleHelper::requestedBaseColor(); + if (c.isValid()) { + QString tmp = QString::fromLatin1("#%1%2%3") + .arg(c.red(), 2, 16, QLatin1Char('0')) + .arg(c.green(), 2, 16, QLatin1Char('0')) + .arg(c.blue(), 2, 16, QLatin1Char('0')); + data.insert(QLatin1String("Color"), tmp); + } + QStringList projectFiles; foreach (Project *pro, m_projects) projectFiles << pro->document()->fileName(); @@ -861,6 +871,10 @@ bool SessionManager::loadSession(const QString &session) restoreValues(reader); emit aboutToLoadSession(session); + QColor c = QColor(reader.restoreValue(QLatin1String("Color")).toString()); + if (c.isValid()) + Utils::StyleHelper::setBaseColor(c); + QStringList fileList = reader.restoreValue(QLatin1String("ProjectList")).toStringList(); int openEditorsCount = reader.restoreValue(QLatin1String("OpenEditors")).toInt(); @@ -901,8 +915,7 @@ bool SessionManager::loadSession(const QString &session) QString SessionManager::lastSession() const { - QString fileName = ICore::settings()->value(QLatin1String("ProjectExplorer/StartupSession")).toString(); - return QFileInfo(fileName).completeBaseName(); + return ICore::settings()->value(QLatin1String("ProjectExplorer/StartupSession")).toString(); } SessionNode *SessionManager::sessionNode() const diff --git a/src/plugins/projectexplorer/settingsaccessor.cpp b/src/plugins/projectexplorer/settingsaccessor.cpp index 696445ddbe..9b29282755 100644 --- a/src/plugins/projectexplorer/settingsaccessor.cpp +++ b/src/plugins/projectexplorer/settingsaccessor.cpp @@ -45,6 +45,7 @@ #include <coreplugin/icore.h> #include <coreplugin/idocument.h> #include <extensionsystem/pluginmanager.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/qtcprocess.h> #include <utils/persistentsettings.h> @@ -1893,7 +1894,6 @@ static const char * const lameArgListKeys[] = { 0 }; -#ifdef Q_OS_UNIX inline static bool isSpecialChar(ushort c) { // Chars that should be quoted (TM). This includes: @@ -1912,27 +1912,26 @@ inline static bool hasSpecialChars(const QString &arg) return true; return false; } -#endif // These were split according to sane (even if a bit arcane) rules static QVariant version8ArgNodeHandler(const QVariant &var) { QString ret; foreach (const QVariant &svar, var.toList()) { -#ifdef Q_OS_UNIX - // We don't just addArg, so we don't disarm existing env expansions. - // This is a bit fuzzy logic ... - QString s = svar.toString(); - s.replace(QLatin1Char('\\'), QLatin1String("\\\\")); - s.replace(QLatin1Char('"'), QLatin1String("\\\"")); - s.replace(QLatin1Char('`'), QLatin1String("\\`")); - if (s != svar.toString() || hasSpecialChars(s)) - s.prepend(QLatin1Char('"')).append(QLatin1Char('"')); - Utils::QtcProcess::addArgs(&ret, s); -#else - // Under windows, env expansions cannot be quoted anyway. - Utils::QtcProcess::addArg(&ret, svar.toString()); -#endif + if (Utils::HostOsInfo::isAnyUnixHost()) { + // We don't just addArg, so we don't disarm existing env expansions. + // This is a bit fuzzy logic ... + QString s = svar.toString(); + s.replace(QLatin1Char('\\'), QLatin1String("\\\\")); + s.replace(QLatin1Char('"'), QLatin1String("\\\"")); + s.replace(QLatin1Char('`'), QLatin1String("\\`")); + if (s != svar.toString() || hasSpecialChars(s)) + s.prepend(QLatin1Char('"')).append(QLatin1Char('"')); + Utils::QtcProcess::addArgs(&ret, s); + } else { + // Under windows, env expansions cannot be quoted anyway. + Utils::QtcProcess::addArg(&ret, svar.toString()); + } } return QVariant(ret); } @@ -1987,13 +1986,13 @@ static const char * const envExpandedKeys[] = { static QString version8NewVar(const QString &old) { QString ret = old; -#ifdef Q_OS_UNIX - ret.prepend(QLatin1String("${")); - ret.append(QLatin1Char('}')); -#else - ret.prepend(QLatin1Char('%')); - ret.append(QLatin1Char('%')); -#endif + if (Utils::HostOsInfo::isAnyUnixHost()) { + ret.prepend(QLatin1String("${")); + ret.append(QLatin1Char('}')); + } else { + ret.prepend(QLatin1Char('%')); + ret.append(QLatin1Char('%')); + } return ret; } @@ -2007,65 +2006,65 @@ static QVariant version8EnvNodeTransform(const QVariant &var) QLatin1String("%{sourceDir}")); result.replace(QRegExp(QLatin1String("%BUILDDIR%|\\$(BUILDDIR\\b|\\{BUILDDIR\\})")), QLatin1String("%{buildDir}")); -#ifdef Q_OS_UNIX - for (int vStart = -1, i = 0; i < result.length(); ) { - QChar c = result.at(i++); - if (c == QLatin1Char('%')) { - if (vStart > 0 && vStart < i - 1) { - QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart)); - result.replace(vStart - 1, i - vStart + 1, nv); - i = vStart - 1 + nv.length(); - vStart = -1; - } else { - vStart = i; + if (Utils::HostOsInfo::isAnyUnixHost()) { + for (int vStart = -1, i = 0; i < result.length(); ) { + QChar c = result.at(i++); + if (c == QLatin1Char('%')) { + if (vStart > 0 && vStart < i - 1) { + QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart)); + result.replace(vStart - 1, i - vStart + 1, nv); + i = vStart - 1 + nv.length(); + vStart = -1; + } else { + vStart = i; + } + } else if (vStart > 0) { + // Sanity check so we don't catch too much garbage + if (!c.isLetterOrNumber() && c != QLatin1Char('_')) + vStart = -1; } - } else if (vStart > 0) { - // Sanity check so we don't catch too much garbage - if (!c.isLetterOrNumber() && c != QLatin1Char('_')) - vStart = -1; } - } -#else - enum { BASE, OPTIONALVARIABLEBRACE, VARIABLE, BRACEDVARIABLE } state = BASE; - int vStart = -1; - - for (int i = 0; i < result.length();) { - QChar c = result.at(i++); - if (state == BASE) { - if (c == QLatin1Char('$')) - state = OPTIONALVARIABLEBRACE; - } else if (state == OPTIONALVARIABLEBRACE) { - if (c == QLatin1Char('{')) { - state = BRACEDVARIABLE; - vStart = i; - } else if (c.isLetterOrNumber() || c == QLatin1Char('_')) { - state = VARIABLE; - vStart = i - 1; - } else { - state = BASE; - } - } else if (state == BRACEDVARIABLE) { - if (c == QLatin1Char('}')) { - QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart)); - result.replace(vStart - 2, i - vStart + 2, nv); - i = vStart + nv.length(); - state = BASE; - } - } else if (state == VARIABLE) { - if (!c.isLetterOrNumber() && c != QLatin1Char('_')) { - QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart)); - result.replace(vStart - 1, i - vStart, nv); - i = vStart - 1 + nv.length(); // On the same char - could be next expansion. - state = BASE; + } else { + enum { BASE, OPTIONALVARIABLEBRACE, VARIABLE, BRACEDVARIABLE } state = BASE; + int vStart = -1; + + for (int i = 0; i < result.length();) { + QChar c = result.at(i++); + if (state == BASE) { + if (c == QLatin1Char('$')) + state = OPTIONALVARIABLEBRACE; + } else if (state == OPTIONALVARIABLEBRACE) { + if (c == QLatin1Char('{')) { + state = BRACEDVARIABLE; + vStart = i; + } else if (c.isLetterOrNumber() || c == QLatin1Char('_')) { + state = VARIABLE; + vStart = i - 1; + } else { + state = BASE; + } + } else if (state == BRACEDVARIABLE) { + if (c == QLatin1Char('}')) { + QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart)); + result.replace(vStart - 2, i - vStart + 2, nv); + i = vStart + nv.length(); + state = BASE; + } + } else if (state == VARIABLE) { + if (!c.isLetterOrNumber() && c != QLatin1Char('_')) { + QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart)); + result.replace(vStart - 1, i - vStart, nv); + i = vStart - 1 + nv.length(); // On the same char - could be next expansion. + state = BASE; + } } } + if (state == VARIABLE) { + QString nv = version8NewVar(result.mid(vStart)); + result.truncate(vStart - 1); + result += nv; + } } - if (state == VARIABLE) { - QString nv = version8NewVar(result.mid(vStart)); - result.truncate(vStart - 1); - result += nv; - } -#endif return QVariant(result); } @@ -2574,14 +2573,8 @@ void Version11Handler::addRunConfigurations(Kit *k, static QString targetRoot(const QString &qmakePath) { -#ifdef Q_OS_WIN - Qt::CaseSensitivity cs = Qt::CaseInsensitive; - const QString binQmake = "/bin/qmake.exe"; -#else - Qt::CaseSensitivity cs = Qt::CaseSensitive; - const QString binQmake = "/bin/qmake"; -#endif - return QDir::cleanPath(qmakePath).remove(binQmake, cs); + return QDir::cleanPath(qmakePath).remove(QLatin1String("/bin/qmake" QTC_HOST_EXE_SUFFIX), + Utils::HostOsInfo::fileNameCaseSensitivity()); } static QString maddeRoot(const QString &qmakePath) diff --git a/src/plugins/projectexplorer/showineditortaskhandler.cpp b/src/plugins/projectexplorer/showineditortaskhandler.cpp index 7f34850ec9..f1758b2b86 100644 --- a/src/plugins/projectexplorer/showineditortaskhandler.cpp +++ b/src/plugins/projectexplorer/showineditortaskhandler.cpp @@ -55,7 +55,9 @@ void ShowInEditorTaskHandler::handle(const ProjectExplorer::Task &task) QAction *ShowInEditorTaskHandler::createAction(QObject *parent) const { - QAction *showAction = new QAction(tr("&Show in Editor"), parent); + QAction *showAction = new QAction(tr("Show in Editor"), parent); showAction->setToolTip(tr("Show task location in an editor.")); + showAction->setShortcut(QKeySequence(Qt::Key_Return)); + showAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); return showAction; } diff --git a/src/plugins/projectexplorer/showoutputtaskhandler.cpp b/src/plugins/projectexplorer/showoutputtaskhandler.cpp index 01d6c814e4..47d580f47a 100644 --- a/src/plugins/projectexplorer/showoutputtaskhandler.cpp +++ b/src/plugins/projectexplorer/showoutputtaskhandler.cpp @@ -61,5 +61,7 @@ QAction *ShowOutputTaskHandler::createAction(QObject *parent) const { QAction *outputAction = new QAction(tr("Show &Output"), parent); outputAction->setToolTip(tr("Show output generating this issue.")); + outputAction->setShortcut(QKeySequence(tr("O"))); + outputAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); return outputAction; } diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp index 13a522d504..953b4059db 100644 --- a/src/plugins/projectexplorer/target.cpp +++ b/src/plugins/projectexplorer/target.cpp @@ -368,7 +368,10 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc) void Target::setDeploymentData(const DeploymentData &deploymentData) { - d->m_deploymentData = deploymentData; + if (d->m_deploymentData != deploymentData) { + d->m_deploymentData = deploymentData; + emit deploymentDataChanged(); + } } DeploymentData Target::deploymentData() const @@ -378,7 +381,10 @@ DeploymentData Target::deploymentData() const void Target::setApplicationTargets(const BuildTargetInfoList &appTargets) { - d->m_appTargets = appTargets; + if (d->m_appTargets != appTargets) { + d->m_appTargets = appTargets; + emit applicationTargetsChanged(); + } } BuildTargetInfoList Target::applicationTargets() const diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h index 57be3ff413..03d8d8d81b 100644 --- a/src/plugins/projectexplorer/target.h +++ b/src/plugins/projectexplorer/target.h @@ -49,7 +49,7 @@ class DeployConfigurationFactory; class IRunConfigurationFactory; class Kit; class Project; -class BuildConfigWidget; +class NamedWidget; class TargetPrivate; @@ -148,6 +148,9 @@ signals: void deployConfigurationEnabledChanged(); void runConfigurationEnabledChanged(); + void deploymentDataChanged(); + void applicationTargetsChanged(); + // Remove all the signals below, they are stupid /// Emitted whenever the current build configuartion changed or the build directory of the current /// build configuration was changed. diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp index 686042ab3b..cd58c4ca0b 100644 --- a/src/plugins/projectexplorer/targetselector.cpp +++ b/src/plugins/projectexplorer/targetselector.cpp @@ -36,10 +36,41 @@ #include <QMenu> #include <QMouseEvent> #include <QFontMetrics> +#include <QPushButton> static const int TARGET_HEIGHT = 43; static const int NAVBUTTON_WIDTH = 27; +namespace ProjectExplorer { +namespace Internal { +class QPixmapButton : public QPushButton +{ +public: + QPixmapButton(QWidget *parent, const QPixmap &first, const QPixmap &second) + : QPushButton(parent), m_showFirst(true), m_first(first), m_second(second) + { + setFixedSize(m_first.size()); + } + + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.drawPixmap(0, 0, m_showFirst ? m_first : m_second); + } + + void setFirst(bool f) + { + m_showFirst = f; + } + +private: + bool m_showFirst; + const QPixmap m_first; + const QPixmap m_second; +}; +} +} + using namespace ProjectExplorer::Internal; TargetSelector::TargetSelector(QWidget *parent) : @@ -49,11 +80,12 @@ TargetSelector::TargetSelector(QWidget *parent) : m_buildselected(QLatin1String(":/projectexplorer/images/targetbuildselected.png")), m_targetRightButton(QLatin1String(":/projectexplorer/images/targetrightbutton.png")), m_targetLeftButton(QLatin1String(":/projectexplorer/images/targetleftbutton.png")), - m_targetRemoveButton(QLatin1String(":/projectexplorer/images/targetremovebutton.png")), - m_targetRemoveDarkButton(QLatin1String(":/projectexplorer/images/targetremovebuttondark.png")), + m_targetChangePixmap(QLatin1String(":/projectexplorer/images/targetchangebutton.png")), + m_targetChangePixmap2(QLatin1String(":/projectexplorer/images/targetchangebutton2.png")), m_currentTargetIndex(-1), m_currentHoveredTargetIndex(-1), - m_startIndex(0) + m_startIndex(0), + m_menuShown(false) { QFont f = font(); f.setPixelSize(10); @@ -61,6 +93,27 @@ TargetSelector::TargetSelector(QWidget *parent) : setFont(f); setMouseTracking(true); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + m_targetChangeButton = new QPixmapButton(this, m_targetChangePixmap2, m_targetChangePixmap); + m_targetChangeButton->hide(); + connect(m_targetChangeButton, SIGNAL(pressed()), this, SLOT(changeButtonPressed())); +} + +void TargetSelector::changeButtonPressed() +{ + emit menuShown(m_currentHoveredTargetIndex); +} + +void TargetSelector::menuAboutToShow() +{ + m_menuShown = true; + updateButtons(); +} + +void TargetSelector::menuAboutToHide() +{ + m_menuShown = false; + updateButtons(); } void TargetSelector::insertTarget(int index, const QString &name) @@ -136,6 +189,25 @@ TargetSelector::Target TargetSelector::targetAt(int index) const return m_targets.at(index); } +void TargetSelector::setTargetMenu(QMenu *menu) +{ + if (m_targetChangeButton->menu()) { + disconnect(m_targetChangeButton->menu(), SIGNAL(aboutToShow()), + this, SLOT(menuAboutToShow())); + disconnect(m_targetChangeButton->menu(), SIGNAL(aboutToHide()), + this, SLOT(menuAboutToHide())); + } + + m_targetChangeButton->setMenu(menu); + + if (menu) { + connect(m_targetChangeButton->menu(), SIGNAL(aboutToShow()), + this, SLOT(menuAboutToShow())); + connect(m_targetChangeButton->menu(), SIGNAL(aboutToHide()), + this, SLOT(menuAboutToHide())); + } +} + int TargetSelector::targetWidth() const { static int width = -1; @@ -157,7 +229,7 @@ int TargetSelector::maxVisibleTargets() const return (width() - ((NAVBUTTON_WIDTH + 1) * 2 + 3))/(targetWidth() + 1); } -void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex, bool *removeButton) +void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex) { if (buttonIndex) *buttonIndex = -1; @@ -165,8 +237,6 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd *targetIndex = -1; if (targetSubIndex) *targetSubIndex = -1; - if (removeButton) - *removeButton = false; // left button? if (m_startIndex > 0 /* button visible */ && x >= 0 && x < NAVBUTTON_WIDTH + 2) { @@ -196,6 +266,7 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd } --index; tx -= targetWidth() + 1; + if (index >= 0 && index < m_targets.size()) { if (targetIndex) *targetIndex = index; @@ -209,10 +280,6 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd if (targetSubIndex) *targetSubIndex = 0; } - } else if (y < m_targetRemoveButton.height() + 3 - && x >= tx + targetWidth() - m_targetRemoveButton.width() - 1) { - if (removeButton) - *removeButton = true; } } } @@ -222,8 +289,7 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) int buttonIndex; int targetIndex; int targetSubIndex; - bool removeButton; - getControlAt(event->x(), event->y(), &buttonIndex, &targetIndex, &targetSubIndex, &removeButton); + getControlAt(event->x(), event->y(), &buttonIndex, &targetIndex, &targetSubIndex); if (buttonIndex == 0) { event->accept(); --m_startIndex; @@ -235,7 +301,7 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) } else if (targetIndex != -1) { event->accept(); bool updateNeeded = false; - if (targetIndex != m_currentTargetIndex && !removeButton) { + if (targetIndex != m_currentTargetIndex) { m_currentTargetIndex = targetIndex; updateNeeded = true; } @@ -244,8 +310,6 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) m_targets[m_currentTargetIndex].currentSubIndex = targetSubIndex; updateNeeded = true; } - } else if (removeButton) { - emit removeButtonClicked(targetIndex); } if (updateNeeded) { update(); @@ -259,11 +323,12 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) void TargetSelector::mouseMoveEvent(QMouseEvent *event) { int targetIndex; - getControlAt(event->x(), event->y(), 0, &targetIndex, 0, 0); + getControlAt(event->x(), event->y(), 0, &targetIndex, 0); if (m_currentHoveredTargetIndex != targetIndex) { m_currentHoveredTargetIndex = targetIndex; if (targetIndex != -1) event->accept(); + updateButtons(); update(); } } @@ -272,18 +337,34 @@ void TargetSelector::leaveEvent(QEvent *event) { Q_UNUSED(event) m_currentHoveredTargetIndex = -1; + updateButtons(); update(); } +void TargetSelector::updateButtons() +{ + if (m_menuShown) { + // Do nothing while the menu is show + } else if (m_currentHoveredTargetIndex == -1) { + m_targetChangeButton->hide(); + } else { + int tx = NAVBUTTON_WIDTH + 3 + (m_currentHoveredTargetIndex - m_startIndex) * (targetWidth() + 1); + + QPoint buttonTopLeft(tx + targetWidth() - m_targetChangePixmap.width() - 1, 3); + m_targetChangeButton->move(buttonTopLeft); + m_targetChangeButton->setVisible(true); + m_targetChangeButton->setFirst(m_currentHoveredTargetIndex == m_currentTargetIndex); + } +} + bool TargetSelector::event(QEvent *e) { if (e->type() == QEvent::ToolTip) { const QHelpEvent *helpEvent = static_cast<const QHelpEvent *>(e); int targetIndex; int subTargetIndex; - bool removeButton; - getControlAt(helpEvent->x(), helpEvent->y(), 0, &targetIndex, &subTargetIndex, &removeButton); - if (targetIndex >= 0 && subTargetIndex < 0 && !removeButton) { + getControlAt(helpEvent->x(), helpEvent->y(), 0, &targetIndex, &subTargetIndex); + if (targetIndex >= 0 && subTargetIndex < 0) { emit toolTipRequested(helpEvent->globalPos(), targetIndex); e->accept(); return true; @@ -340,12 +421,6 @@ void TargetSelector::paintEvent(QPaintEvent *event) p.drawText(x + (targetWidth()- fm.width(nameText))/2 + 1, 7 + fm.ascent(), nameText); - // remove button - if (m_currentHoveredTargetIndex == index) { - p.drawPixmap(x + targetWidth() - m_targetRemoveButton.width() - 2, 3, - index == m_currentTargetIndex ? m_targetRemoveDarkButton : m_targetRemoveButton); - } - // Build int margin = 2; // position centered within the rounded buttons QFontMetrics fm = fontMetrics(); diff --git a/src/plugins/projectexplorer/targetselector.h b/src/plugins/projectexplorer/targetselector.h index 097a7d3363..2f97269a69 100644 --- a/src/plugins/projectexplorer/targetselector.h +++ b/src/plugins/projectexplorer/targetselector.h @@ -35,10 +35,12 @@ QT_BEGIN_NAMESPACE class QMenu; +class QPushButton; QT_END_NAMESPACE namespace ProjectExplorer { namespace Internal { +class QPixmapButton; class TargetSelector : public QWidget { @@ -62,6 +64,8 @@ public: int currentIndex() const { return m_currentTargetIndex; } int currentSubIndex() const { return m_targets.at(m_currentTargetIndex).currentSubIndex; } + void setTargetMenu(QMenu *menu); + public: void insertTarget(int index, const QString &name); void renameTarget(int index, const QString &name); @@ -70,11 +74,11 @@ public: void setCurrentSubIndex(int subindex); signals: - void removeButtonClicked(int targetIndex); // This signal is emitted whenever the target pointed to by the indices // has changed. void currentChanged(int targetIndex, int subIndex); void toolTipRequested(const QPoint &globalPosition, int targetIndex); + void menuShown(int targetIndex); protected: void paintEvent(QPaintEvent *event); @@ -83,8 +87,13 @@ protected: void leaveEvent(QEvent *event); bool event(QEvent *e); +private slots: + void changeButtonPressed(); + void updateButtons(); + void menuAboutToShow(); + void menuAboutToHide(); private: - void getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex, bool *removeButton); + void getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex); int maxVisibleTargets() const; const QImage m_unselected; @@ -92,14 +101,17 @@ private: const QImage m_buildselected; const QPixmap m_targetRightButton; const QPixmap m_targetLeftButton; - const QPixmap m_targetRemoveButton; - const QPixmap m_targetRemoveDarkButton; + const QPixmap m_targetChangePixmap; + const QPixmap m_targetChangePixmap2; + + QPixmapButton *m_targetChangeButton; QList<Target> m_targets; int m_currentTargetIndex; int m_currentHoveredTargetIndex; int m_startIndex; + bool m_menuShown; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index e57a20751a..b38371e237 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -44,6 +44,9 @@ #include <projectexplorer/kitmanager.h> #include <projectexplorer/buildmanager.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/deployconfiguration.h> +#include <projectexplorer/runconfiguration.h> #include <utils/qtcassert.h> #include <QCoreApplication> @@ -69,6 +72,8 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : m_project(project), m_selector(0), m_centralWidget(0), + m_changeMenu(0), + m_duplicateMenu(0), m_lastAction(0) { Q_ASSERT(m_project); @@ -77,6 +82,7 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : m_panelWidgets[1] = 0; m_addMenu = new QMenu(this); + m_targetMenu = new QMenu(this); setFocusPolicy(Qt::NoFocus); @@ -91,7 +97,7 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : this, SLOT(activeTargetChanged(ProjectExplorer::Target*))); connect(KitManager::instance(), SIGNAL(kitsChanged()), - this, SLOT(updateTargetAddAndRemoveButtons())); + this, SLOT(updateTargetButtons())); } TargetSettingsPanelWidget::~TargetSettingsPanelWidget() @@ -101,21 +107,35 @@ TargetSettingsPanelWidget::~TargetSettingsPanelWidget() bool TargetSettingsPanelWidget::event(QEvent *event) { if (event->type() == QEvent::StatusTip) { + QAction *act = 0; + QMenu *menu = 0; + if (m_addMenu->activeAction()) { + menu = m_addMenu; + act = m_addMenu->activeAction(); + } else if (m_changeMenu && m_changeMenu->activeAction()) { + menu = m_changeMenu; + act = m_changeMenu->activeAction(); + } else if (m_duplicateMenu && m_duplicateMenu->activeAction()) { + menu = m_duplicateMenu; + act = m_duplicateMenu->activeAction(); + } else { + return QWidget::event(event); + } + QStatusTipEvent *ev = static_cast<QStatusTipEvent *>(event); ev->accept(); - QAction *act = m_addMenu->activeAction(); if (act != m_lastAction) QToolTip::showText(QPoint(), QString()); m_lastAction = act; if (act) { - QRect actionRect = m_addMenu->actionGeometry(act); - actionRect.translate(m_addMenu->pos()); + QRect actionRect = menu->actionGeometry(act); + actionRect.translate(menu->pos()); QPoint p = QCursor::pos(); if (!actionRect.contains(p)) p = actionRect.center(); p.setY(actionRect.center().y()); - QToolTip::showText(p, ev->tip(), m_addMenu, m_addMenu->actionGeometry(act)); + QToolTip::showText(p, ev->tip(), menu, menu->actionGeometry(act)); } else { QToolTip::showText(QPoint(), QString()); } @@ -168,18 +188,20 @@ void TargetSettingsPanelWidget::setupUi() connect(m_selector, SIGNAL(currentChanged(int,int)), this, SLOT(currentTargetChanged(int,int))); - connect(m_selector, SIGNAL(removeButtonClicked(int)), - this, SLOT(removeTarget(int))); connect(m_selector, SIGNAL(manageButtonClicked()), this, SLOT(openTargetPreferences())); connect(m_selector, SIGNAL(toolTipRequested(QPoint,int)), this, SLOT(showTargetToolTip(QPoint,int))); + connect(m_selector, SIGNAL(menuShown(int)), + this, SLOT(menuShown(int))); - m_selector->setAddButtonMenu(m_addMenu); connect(m_addMenu, SIGNAL(triggered(QAction*)), - this, SLOT(addTarget(QAction*))); + this, SLOT(addActionTriggered(QAction*))); - updateTargetAddAndRemoveButtons(); + m_selector->setAddButtonMenu(m_addMenu); + m_selector->setTargetMenu(m_targetMenu); + + updateTargetButtons(); } void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subIndex) @@ -242,7 +264,36 @@ void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subInd m_project->setActiveTarget(target); } -void TargetSettingsPanelWidget::addTarget(QAction *action) +void TargetSettingsPanelWidget::menuShown(int targetIndex) +{ + m_menuTargetIndex = targetIndex; +} + +void TargetSettingsPanelWidget::changeActionTriggered(QAction *action) +{ + Kit *k = KitManager::instance()->find(action->data().value<Core::Id>()); + Target *sourceTarget = m_targets.at(m_menuTargetIndex); + Target *newTarget = cloneTarget(sourceTarget, k); + + if (newTarget) { + m_project->addTarget(newTarget); + m_project->setActiveTarget(newTarget); + m_project->removeTarget(sourceTarget); + } +} + +void TargetSettingsPanelWidget::duplicateActionTriggered(QAction *action) +{ + Kit *k = KitManager::instance()->find(action->data().value<Core::Id>()); + Target *newTarget = cloneTarget(m_targets.at(m_menuTargetIndex), k); + + if (newTarget) { + m_project->addTarget(newTarget); + m_project->setActiveTarget(newTarget); + } +} + +void TargetSettingsPanelWidget::addActionTriggered(QAction *action) { Kit *k = KitManager::instance()->find(action->data().value<Core::Id>()); QTC_ASSERT(!m_project->target(k), return); @@ -253,10 +304,146 @@ void TargetSettingsPanelWidget::addTarget(QAction *action) m_project->addTarget(target); } -void TargetSettingsPanelWidget::removeTarget(int targetIndex) +Target *TargetSettingsPanelWidget::cloneTarget(Target *sourceTarget, Kit *k) +{ + Target *newTarget = new Target(m_project, k); + + QStringList buildconfigurationError; + QStringList deployconfigurationError; + QStringList runconfigurationError; + + foreach (BuildConfiguration *sourceBc, sourceTarget->buildConfigurations()) { + IBuildConfigurationFactory *factory = IBuildConfigurationFactory::find(newTarget, sourceBc); + if (!factory) { + buildconfigurationError << sourceBc->displayName(); + continue; + } + BuildConfiguration *newBc = factory->clone(newTarget, sourceBc); + if (!newBc) { + buildconfigurationError << sourceBc->displayName(); + continue; + } + newBc->setDisplayName(sourceBc->displayName()); + newTarget->addBuildConfiguration(newBc); + if (sourceTarget->activeBuildConfiguration() == sourceBc) + newTarget->setActiveBuildConfiguration(newBc); + } + if (!newTarget->activeBuildConfiguration()) { + QList<BuildConfiguration *> bcs = newTarget->buildConfigurations(); + if (!bcs.isEmpty()) + newTarget->setActiveBuildConfiguration(bcs.first()); + } + + foreach (DeployConfiguration *sourceDc, sourceTarget->deployConfigurations()) { + DeployConfigurationFactory *factory = DeployConfigurationFactory::find(newTarget, sourceDc); + if (!factory) { + deployconfigurationError << sourceDc->displayName(); + continue; + } + DeployConfiguration *newDc = factory->clone(newTarget, sourceDc); + if (!newDc) { + deployconfigurationError << sourceDc->displayName(); + continue; + } + newDc->setDisplayName(sourceDc->displayName()); + newTarget->addDeployConfiguration(newDc); + if (sourceTarget->activeDeployConfiguration() == sourceDc) + newTarget->setActiveDeployConfiguration(newDc); + } + if (!newTarget->activeBuildConfiguration()) { + QList<DeployConfiguration *> dcs = newTarget->deployConfigurations(); + if (!dcs.isEmpty()) + newTarget->setActiveDeployConfiguration(dcs.first()); + } + + foreach (RunConfiguration *sourceRc, sourceTarget->runConfigurations()) { + IRunConfigurationFactory *factory = IRunConfigurationFactory::find(newTarget, sourceRc); + if (!factory) { + runconfigurationError << sourceRc->displayName(); + continue; + } + RunConfiguration *newRc = factory->clone(newTarget, sourceRc); + if (!newRc) { + runconfigurationError << sourceRc->displayName(); + continue; + } + newRc->setDisplayName(sourceRc->displayName()); + newTarget->addRunConfiguration(newRc); + if (sourceTarget->activeRunConfiguration() == sourceRc) + newTarget->setActiveRunConfiguration(newRc); + } + if (!newTarget->activeRunConfiguration()) { + QList<RunConfiguration *> rcs = newTarget->runConfigurations(); + if (!rcs.isEmpty()) + newTarget->setActiveRunConfiguration(rcs.first()); + } + + bool fatalError = false; + if (buildconfigurationError.count() == sourceTarget->buildConfigurations().count()) + fatalError = true; + + if (deployconfigurationError.count() == sourceTarget->deployConfigurations().count()) + fatalError = true; + + if (runconfigurationError.count() == sourceTarget->runConfigurations().count()) + fatalError = true; + + if (fatalError) { + // That could be a more granular error message + QMessageBox::critical(Core::ICore::mainWindow(), + tr("Incompatible Kit"), + tr("The Kit %1 is incompatible with Kit %2.") + .arg(sourceTarget->kit()->displayName()) + .arg(k->displayName())); + + delete newTarget; + newTarget = 0; + } else if (!buildconfigurationError.isEmpty() + || !deployconfigurationError.isEmpty() + || ! runconfigurationError.isEmpty()) { + + QString error; + if (!buildconfigurationError.isEmpty()) + error += tr("Build configurations:\n") + + buildconfigurationError.join(QLatin1String("\n")); + + if (!deployconfigurationError.isEmpty()) { + if (!error.isEmpty()) + error.append(QLatin1Char('\n')); + error += tr("Deploy configurations:\n") + + deployconfigurationError.join(QLatin1String("\n")); + } + + if (!runconfigurationError.isEmpty()) { + if (!error.isEmpty()) + error.append(QLatin1Char('\n')); + error += tr("Run configurations ") + + runconfigurationError.join(QLatin1String("\n")); + } + + QMessageBox msgBox(Core::ICore::mainWindow()); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle(tr("Partial Incompatible Kit")); + msgBox.setText(tr("Some configurations could not be copied.")); + msgBox.setDetailedText(error); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + if (msgBox.exec() != QDialog::Accepted) { + delete newTarget; + newTarget = 0; + } + } + + return newTarget; +} + +void TargetSettingsPanelWidget::removeTarget() { - Target *t = m_targets.at(targetIndex); + Target *t = m_targets.at(m_menuTargetIndex); + removeTarget(t); +} +void TargetSettingsPanelWidget::removeTarget(Target *t) +{ ProjectExplorer::BuildManager *bm = ProjectExplorerPlugin::instance()->buildManager(); if (bm->isBuilding(t)) { QMessageBox box; @@ -307,7 +494,7 @@ void TargetSettingsPanelWidget::targetAdded(ProjectExplorer::Target *target) } connect(target, SIGNAL(displayNameChanged()), this, SLOT(renameTarget())); - updateTargetAddAndRemoveButtons(); + updateTargetButtons(); } void TargetSettingsPanelWidget::removedTarget(ProjectExplorer::Target *target) @@ -322,7 +509,7 @@ void TargetSettingsPanelWidget::removedTarget(ProjectExplorer::Target *target) m_selector->removeTarget(index); - updateTargetAddAndRemoveButtons(); + updateTargetButtons(); } void TargetSettingsPanelWidget::activeTargetChanged(ProjectExplorer::Target *target) @@ -333,37 +520,61 @@ void TargetSettingsPanelWidget::activeTargetChanged(ProjectExplorer::Target *tar m_selector->setCurrentIndex(index); } -void TargetSettingsPanelWidget::updateTargetAddAndRemoveButtons() +namespace { +bool diplayNameSorter(Kit *a, Kit *b) +{ + return a->displayName() < b->displayName(); +} +} + +void TargetSettingsPanelWidget::createAction(Kit *k, QMenu *menu) +{ + QAction *action = new QAction(k->displayName(), menu); + action->setData(QVariant::fromValue(k->id())); + QString errorMessage; + if (!m_project->supportsKit(k, &errorMessage)) { + action->setEnabled(false); + action->setStatusTip(errorMessage); + } + menu->addAction(action); +} + +void TargetSettingsPanelWidget::updateTargetButtons() { if (!m_selector) return; m_addMenu->clear(); + m_targetMenu->clear(); - foreach (Kit *k, KitManager::instance()->kits()) { - if (m_project->target(k)) - continue; + m_changeMenu = m_targetMenu->addMenu(tr("Change Kit")); + m_duplicateMenu = m_targetMenu->addMenu(tr("Copy to Kit")); + QAction *removeAction = m_targetMenu->addAction(tr("Remove Kit")); - QAction *action = new QAction(k->displayName(), m_addMenu); - action->setData(QVariant::fromValue(k->id())); - QString errorMessage; - if (!m_project->supportsKit(k, &errorMessage)) { - action->setEnabled(false); - action->setStatusTip(errorMessage); - } + if (m_project->targets().size() < 2) + removeAction->setEnabled(false); - bool inserted = false; - foreach (QAction *existing, m_addMenu->actions()) { - if (existing->text() > action->text()) { - m_addMenu->insertAction(existing, action); - inserted = true; - break; - } - } - if (!inserted) - m_addMenu->addAction(action); + connect(m_changeMenu, SIGNAL(triggered(QAction*)), + this, SLOT(changeActionTriggered(QAction*))); + connect(m_duplicateMenu, SIGNAL(triggered(QAction*)), + this, SLOT(duplicateActionTriggered(QAction*))); + connect(removeAction, SIGNAL(triggered()), this, SLOT(removeTarget())); + + QList<Kit *> kits = KitManager::instance()->kits(); + qSort(kits.begin(), kits.end(), diplayNameSorter); + foreach (Kit *k, kits) { + if (m_project->target(k)) + continue; + createAction(k, m_addMenu); + createAction(k, m_changeMenu); + createAction(k, m_duplicateMenu); } + if (m_changeMenu->actions().isEmpty()) + m_changeMenu->setEnabled(false); + if (m_duplicateMenu->actions().isEmpty()) + m_duplicateMenu->setEnabled(false); + m_selector->setAddButtonEnabled(!m_addMenu->actions().isEmpty()); } diff --git a/src/plugins/projectexplorer/targetsettingspanel.h b/src/plugins/projectexplorer/targetsettingspanel.h index 3d9aa908e7..5749055d05 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.h +++ b/src/plugins/projectexplorer/targetsettingspanel.h @@ -42,6 +42,7 @@ namespace ProjectExplorer { class Target; class Project; +class Kit; namespace Internal { @@ -64,17 +65,24 @@ protected: bool event(QEvent *event); private slots: void currentTargetChanged(int targetIndex, int subIndex); - void removeTarget(int targetIndex); void showTargetToolTip(const QPoint &globalPos, int targetIndex); - void addTarget(QAction *); void targetAdded(ProjectExplorer::Target *target); void removedTarget(ProjectExplorer::Target *target); void activeTargetChanged(ProjectExplorer::Target *target); - void updateTargetAddAndRemoveButtons(); + void updateTargetButtons(); void renameTarget(); void openTargetPreferences(); + void removeTarget(); + void menuShown(int targetIndex); + void addActionTriggered(QAction *action); + void changeActionTriggered(QAction *action); + void duplicateActionTriggered(QAction *action); private: + Target *cloneTarget(Target *sourceTarget, Kit *k); + void removeTarget(Target *t); + void createAction(Kit *k, QMenu *menu); + Target *m_currentTarget; Project *m_project; TargetSettingsWidget *m_selector; @@ -82,8 +90,12 @@ private: QWidget *m_noTargetLabel; PanelsWidget *m_panelWidgets[2]; QList<Target *> m_targets; + QMenu *m_targetMenu; + QMenu *m_changeMenu; + QMenu *m_duplicateMenu; QMenu *m_addMenu; QAction *m_lastAction; + int m_menuTargetIndex; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/targetsettingswidget.cpp b/src/plugins/projectexplorer/targetsettingswidget.cpp index 427903bd82..f2bdbb2e2b 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.cpp +++ b/src/plugins/projectexplorer/targetsettingswidget.cpp @@ -62,12 +62,12 @@ TargetSettingsWidget::TargetSettingsWidget(QWidget *parent) : headerLayout->addWidget(m_targetSelector, 0, Qt::AlignBottom); headerLayout->addStretch(10); - connect(m_targetSelector, SIGNAL(removeButtonClicked(int)), - this, SIGNAL(removeButtonClicked(int))); connect(m_targetSelector, SIGNAL(currentChanged(int,int)), this, SIGNAL(currentChanged(int,int))); connect(m_targetSelector, SIGNAL(toolTipRequested(QPoint,int)), this, SIGNAL(toolTipRequested(QPoint,int))); + connect(m_targetSelector, SIGNAL(menuShown(int)), + this, SIGNAL(menuShown(int))); QPalette shadowPal = palette(); QLinearGradient grad(0, 0, 0, 2); @@ -118,6 +118,11 @@ void TargetSettingsWidget::setAddButtonMenu(QMenu *menu) m_addButton->setMenu(menu); } +void TargetSettingsWidget::setTargetMenu(QMenu *menu) +{ + m_targetSelector->setTargetMenu(menu); +} + QString TargetSettingsWidget::targetNameAt(int index) const { return m_targetSelector->targetAt(index).name; diff --git a/src/plugins/projectexplorer/targetsettingswidget.h b/src/plugins/projectexplorer/targetsettingswidget.h index 78eef585a4..227146d7d2 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.h +++ b/src/plugins/projectexplorer/targetsettingswidget.h @@ -38,6 +38,8 @@ class QPushButton; QT_END_NAMESPACE namespace ProjectExplorer { +class Target; +class Kit; namespace Internal { namespace Ui { @@ -66,12 +68,14 @@ public: void setCurrentSubIndex(int index); void setAddButtonEnabled(bool enabled); void setAddButtonMenu(QMenu *menu); - + void setTargetMenu(QMenu *menu); signals: - void removeButtonClicked(int targetIndex); void currentChanged(int targetIndex, int subIndex); void manageButtonClicked(); + void duplicateButtonClicked(); + void changeKitButtonClicked(); void toolTipRequested(const QPoint &globalPosition, int targetIndex); + void menuShown(int targetIndex); protected: void changeEvent(QEvent *e); diff --git a/src/plugins/projectexplorer/taskhub.cpp b/src/plugins/projectexplorer/taskhub.cpp index f7a34bc01f..99200097f1 100644 --- a/src/plugins/projectexplorer/taskhub.cpp +++ b/src/plugins/projectexplorer/taskhub.cpp @@ -45,7 +45,7 @@ public: setVisible(visible); } - bool clickable() const; + bool isClickable() const; void clicked(); void updateFileName(const QString &fileName); @@ -72,7 +72,7 @@ void TaskMark::removedFromEditor() ProjectExplorerPlugin::instance()->taskHub()->updateTaskLineNumber(m_id, -1); } -bool TaskMark::clickable() const +bool TaskMark::isClickable() const { return true; } diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index b0b5508516..465c76ef74 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -68,7 +68,6 @@ public: TaskView(QWidget *parent = 0); ~TaskView(); void resizeEvent(QResizeEvent *e); - void keyPressEvent(QKeyEvent *e); }; class TaskWindowContext : public Core::IContext @@ -189,16 +188,6 @@ void TaskView::resizeEvent(QResizeEvent *e) static_cast<TaskDelegate *>(itemDelegate())->emitSizeHintChanged(selectionModel()->currentIndex()); } -void TaskView::keyPressEvent(QKeyEvent *e) -{ - if (!e->modifiers() && e->key() == Qt::Key_Return) { - emit activated(currentIndex()); - e->accept(); - return; - } - QListView::keyPressEvent(e); -} - ///// // TaskWindow ///// @@ -211,13 +200,13 @@ public: Internal::TaskView *m_listview; Internal::TaskWindowContext *m_taskWindowContext; QMenu *m_contextMenu; - QModelIndex m_contextMenuIndex; ITaskHandler *m_defaultHandler; QToolButton *m_filterWarningsButton; QToolButton *m_categoriesButton; QMenu *m_categoriesMenu; TaskHub *m_taskHub; int m_badgeCount; + QList<QAction *> m_actions; }; static QToolButton *createFilterButton(QIcon icon, const QString &toolTip, @@ -261,17 +250,14 @@ TaskWindow::TaskWindow(TaskHub *taskhub) : d(new TaskWindowPrivate) connect(d->m_listview->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), tld, SLOT(currentChanged(QModelIndex,QModelIndex))); + connect(d->m_listview->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, SLOT(currentChanged(QModelIndex))); connect(d->m_listview, SIGNAL(activated(QModelIndex)), this, SLOT(triggerDefaultHandler(QModelIndex))); d->m_contextMenu = new QMenu(d->m_listview); - connect(d->m_contextMenu, SIGNAL(triggered(QAction*)), - this, SLOT(contextMenuEntryTriggered(QAction*))); - - d->m_listview->setContextMenuPolicy(Qt::CustomContextMenu); - connect(d->m_listview, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(showContextMenu(QPoint))); + d->m_listview->setContextMenuPolicy(Qt::ActionsContextMenu); d->m_filterWarningsButton = createFilterButton(d->m_model->taskTypeIcon(Task::Warning), tr("Show Warnings"), @@ -315,7 +301,6 @@ TaskWindow::TaskWindow(TaskHub *taskhub) : d(new TaskWindowPrivate) TaskWindow::~TaskWindow() { Core::ICore::removeContextObject(d->m_taskWindowContext); - cleanContextMenu(); delete d->m_filterWarningsButton; delete d->m_listview; delete d->m_filter; @@ -323,6 +308,43 @@ TaskWindow::~TaskWindow() delete d; } +static ITaskHandler *handler(QAction *action) +{ + return qobject_cast<ITaskHandler *>(action->data().value<QObject *>()); +} + +void TaskWindow::delayedInitialization() +{ + static bool alreadyDone = false; + if (alreadyDone) + return; + + alreadyDone = true; + + QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::getObjects<ITaskHandler>(); + foreach (ITaskHandler *h, handlers) { + if (h->isDefaultHandler() && !d->m_defaultHandler) + d->m_defaultHandler = h; + + QAction *action = h->createAction(this); + QTC_ASSERT(action, continue); + action->setData(qVariantFromValue(qobject_cast<QObject*>(h))); + connect(action, SIGNAL(triggered()), this, SLOT(actionTriggered())); + d->m_actions << action; + + Core::Id id = h->actionManagerId(); + if (id.isValid()) { + Core::Command *cmd = Core::ActionManager::instance() + ->registerAction(action, id, d->m_taskWindowContext->context(), true); + action = cmd->action(); + } + d->m_listview->addAction(action); + } + + // Disable everything for now: + currentChanged(QModelIndex()); +} + QList<QWidget*> TaskWindow::toolBarWidgets() const { return QList<QWidget*>() << d->m_filterWarningsButton << d->m_categoriesButton; @@ -382,8 +404,19 @@ void TaskWindow::setCategoryVisibility(const Core::Id &categoryId, bool visible) setBadgeNumber(d->m_badgeCount); } -void TaskWindow::visibilityChanged(bool /* b */) +void TaskWindow::currentChanged(const QModelIndex &index) +{ + const Task task = index.isValid() ? d->m_filter->task(index) : Task(); + foreach (QAction *action, d->m_actions) { + ITaskHandler *h = handler(action); + action->setEnabled((task.isNull() || !h) ? false : h->canHandle(task)); + } +} + +void TaskWindow::visibilityChanged(bool visible) { + if (visible) + delayedInitialization(); } void TaskWindow::addCategory(const Core::Id &categoryId, const QString &displayName, bool visible) @@ -470,20 +503,9 @@ void TaskWindow::openTask(unsigned int id) void TaskWindow::triggerDefaultHandler(const QModelIndex &index) { - if (!index.isValid()) + if (!index.isValid() || !d->m_defaultHandler) return; - // Find a default handler to use: - if (!d->m_defaultHandler) { - QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::getObjects<ITaskHandler>(); - foreach(ITaskHandler *handler, handlers) { - if (handler->isDefaultHandler()) { - d->m_defaultHandler = handler; - break; - } - } - } - Q_ASSERT(d->m_defaultHandler); Task task(d->m_filter->task(index)); if (task.isNull()) return; @@ -496,49 +518,21 @@ void TaskWindow::triggerDefaultHandler(const QModelIndex &index) } } -void TaskWindow::showContextMenu(const QPoint &position) +void TaskWindow::actionTriggered() { - QModelIndex index = d->m_listview->indexAt(position); - if (!index.isValid()) + QAction *action = qobject_cast<QAction *>(sender()); + if (!action || !action->isEnabled()) + return; + ITaskHandler *h = handler(action); + if (!h) return; - d->m_contextMenuIndex = index; - cleanContextMenu(); + QModelIndex index = d->m_listview->selectionModel()->currentIndex(); Task task = d->m_filter->task(index); if (task.isNull()) return; - QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::getObjects<ITaskHandler>(); - foreach(ITaskHandler *handler, handlers) { - if (handler == d->m_defaultHandler) - continue; - QAction * action = handler->createAction(d->m_contextMenu); - action->setEnabled(handler->canHandle(task)); - action->setData(qVariantFromValue(qobject_cast<QObject*>(handler))); - d->m_contextMenu->addAction(action); - } - d->m_contextMenu->popup(d->m_listview->mapToGlobal(position)); -} - -void TaskWindow::contextMenuEntryTriggered(QAction *action) -{ - if (action->isEnabled()) { - Task task = d->m_filter->task(d->m_contextMenuIndex); - if (task.isNull()) - return; - - ITaskHandler *handler = qobject_cast<ITaskHandler*>(action->data().value<QObject*>()); - if (!handler) - return; - handler->handle(task); - } -} - -void TaskWindow::cleanContextMenu() -{ - QList<QAction *> actions = d->m_contextMenu->actions(); - qDeleteAll(actions); - d->m_contextMenu->clear(); + h->handle(task); } void TaskWindow::setShowWarnings(bool show) @@ -564,14 +558,14 @@ void TaskWindow::updateCategoriesMenu() action->setCheckable(true); action->setText(displayName); action->setData(categoryId); - action->setChecked(!filteredCategories.contains(Core::Id(categoryId.constData()))); + action->setChecked(!filteredCategories.contains(Core::Id(categoryId))); d->m_categoriesMenu->addAction(action); } } void TaskWindow::filterCategoryTriggered(QAction *action) { - Core::Id categoryId(action->data().toByteArray().constData()); + Core::Id categoryId(action->data().toByteArray()); QTC_CHECK(categoryId.uniqueIdentifier() != 0); setCategoryVisibility(categoryId, action->isChecked()); diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h index 3f50aaca7b..f89fb7c60c 100644 --- a/src/plugins/projectexplorer/taskwindow.h +++ b/src/plugins/projectexplorer/taskwindow.h @@ -55,6 +55,8 @@ public: TaskWindow(ProjectExplorer::TaskHub *taskHub); virtual ~TaskWindow(); + void delayedInitialization(); + int taskCount(const Core::Id &category = Core::Id()) const; int warningTaskCount(const Core::Id &category = Core::Id()) const; int errorTaskCount(const Core::Id &category = Core::Id()) const; @@ -92,16 +94,15 @@ private slots: void openTask(unsigned int id); void clearTasks(const Core::Id &categoryId); void setCategoryVisibility(const Core::Id &categoryId, bool visible); + void currentChanged(const QModelIndex &index); void triggerDefaultHandler(const QModelIndex &index); - void showContextMenu(const QPoint &position); - void contextMenuEntryTriggered(QAction *); + void actionTriggered(); void setShowWarnings(bool); void updateCategoriesMenu(); void filterCategoryTriggered(QAction *action); private: - void cleanContextMenu(); int sizeHintForColumn(int column) const; TaskWindowPrivate *d; diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index 5109baa033..3ea55bbc46 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -87,7 +87,8 @@ public: STD_CXX11 = 1 }; virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0; - virtual QList<HeaderPath> systemHeaderPaths(const Utils::FileName &sysRoot) const = 0; + virtual QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, + const Utils::FileName &sysRoot) const = 0; virtual void addToEnvironment(Utils::Environment &env) const = 0; virtual QString makeCommand(const Utils::Environment &env) const = 0; diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index 839ecb0cdd..31c6a95120 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -73,13 +73,16 @@ public: ~ToolChainNode() { - if (parent) - parent->childNodes.removeOne(this); - - qDeleteAll(childNodes); // Do not delete tool chain, we do not own it. - Q_ASSERT(childNodes.isEmpty()); + for (int i = childNodes.size(); --i >= 0; ) { + ToolChainNode *child = childNodes.at(i); + child->parent = 0; + delete child; + } + + if (parent) + parent->childNodes.removeOne(this); } ToolChainNode *parent; diff --git a/src/plugins/projectexplorer/toolchainoptionspage.h b/src/plugins/projectexplorer/toolchainoptionspage.h index 408c5f182e..c189011711 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.h +++ b/src/plugins/projectexplorer/toolchainoptionspage.h @@ -35,11 +35,9 @@ #include <QAbstractItemModel> QT_BEGIN_NAMESPACE -class QBoxLayout; class QItemSelectionModel; class QPushButton; class QTreeView; -class QTreeWidgetItem; QT_END_NAMESPACE namespace Utils { class DetailsWidget; } @@ -49,7 +47,6 @@ namespace ProjectExplorer { class ToolChain; class ToolChainConfigWidget; class ToolChainFactory; -class ToolChainManager; namespace Internal { @@ -101,9 +98,9 @@ private: QModelIndex index(ToolChainNode *, int column = 0) const; ToolChainNode *createNode(ToolChainNode *parent, ToolChain *tc, bool changed); - ToolChainNode * m_root; - ToolChainNode * m_autoRoot; - ToolChainNode * m_manualRoot; + ToolChainNode *m_root; + ToolChainNode *m_autoRoot; + ToolChainNode *m_manualRoot; QList<ToolChainNode *> m_toAddList; QList<ToolChainNode *> m_toRemoveList; diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore.pri b/src/plugins/qmldesigner/components/componentcore/componentcore.pri new file mode 100644 index 0000000000..9035a629d7 --- /dev/null +++ b/src/plugins/qmldesigner/components/componentcore/componentcore.pri @@ -0,0 +1,5 @@ +VPATH += $$PWD +INCLUDEPATH += $$PWD +SOURCES += modelnodecontextmenu.cpp + +HEADERS += modelnodecontextmenu.h diff --git a/src/plugins/qmldesigner/designercore/model/modelnodecontextmenu.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp index 622b9bff04..92c0139683 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnodecontextmenu.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp @@ -433,6 +433,12 @@ void ModelNodeContextMenu::setScenePos(const QPoint &pos) m_scenePos = pos; } +void ModelNodeContextMenu::showContextMenu(QmlModelView *view, const QPoint &globalPosition, const QPoint &scenePosition, bool showSelection) +{ + ModelNodeContextMenu contextMenu(view); + contextMenu.setScenePos(scenePosition); + contextMenu.execute(globalPosition, showSelection); +} ModelNodeAction* ModelNodeContextMenu::createModelNodeAction(const QString &description, QMenu *menu, const QList<ModelNode> &modelNodeList, ModelNodeAction::ModelNodeActionType type, bool enabled) { diff --git a/src/plugins/qmldesigner/designercore/model/modelnodecontextmenu.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.h index 4704952480..6aa11aa750 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnodecontextmenu.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.h @@ -117,6 +117,8 @@ public: void execute(const QPoint &pos, bool selectionMenu); void setScenePos(const QPoint &pos); + static void showContextMenu(QmlModelView *view, const QPoint &globalPosition, const QPoint &scenePosition, bool showSelection); + private: ModelNodeAction* createModelNodeAction(const QString &description, QMenu *menu, const QList<ModelNode> &modelNodeList, ModelNodeAction::ModelNodeActionType type, bool enabled = true); diff --git a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp index e74b93dba4..11a31d3bec 100644 --- a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp @@ -31,6 +31,8 @@ #include "formeditorview.h" #include "formeditorview.h" +#include <modelnodecontextmenu.h> + #include <coreplugin/editormanager/editormanager.h> #include <QDebug> @@ -210,7 +212,7 @@ void AbstractFormEditorTool::mouseDoubleClickEvent(const QList<QGraphicsItem*> & void AbstractFormEditorTool::showContextMenu(QGraphicsSceneMouseEvent *event) { - view()->showContextMenu(event->screenPos(), event->scenePos().toPoint(), true); + ModelNodeContextMenu::showContextMenu(view(), event->screenPos(), event->scenePos().toPoint(), true); } void AbstractFormEditorTool::clear() diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp index 35b0aa8d6f..3178bebe72 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp @@ -322,7 +322,7 @@ void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, painter->save(); - if (qmlItemNode().instanceIsRenderPixmapNull()) { + if (qmlItemNode().instanceIsRenderPixmapNull() || !isContentVisible()) { if (scene()->showBoundingRects() && boundingRect().width() > 15 && boundingRect().height() > 15) paintPlaceHolderForInvisbleItem(painter); } else { diff --git a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp index 28e90b4d9d..0e0897ffd8 100644 --- a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp @@ -362,10 +362,10 @@ void MoveManipulator::reparentTo(FormEditorItem *newParent) if (!itemsCanReparented()) return; - if (!newParent->qmlItemNode().modelNode().metaInfo().isSubclassOf("<cpp>.QDeclarativeBasePositioner", -1, -1) + if (!newParent->qmlItemNode().modelNode().metaInfo().isPositioner() && newParent->qmlItemNode().modelNode().hasParentProperty()) { ModelNode grandParent = newParent->qmlItemNode().modelNode().parentProperty().parentModelNode(); - if (grandParent.metaInfo().isSubclassOf("<cpp>.QDeclarativeBasePositioner", -1, -1)) + if (grandParent.metaInfo().isPositioner()) newParent = m_view.data()->scene()->itemForQmlItemNode(QmlItemNode(grandParent)); } diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp index a61fdcfe80..afb145d567 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp @@ -31,30 +31,19 @@ #include "designdocumentcontrollerview.h" #include "xuifiledialog.h" #include "componentview.h" -#include "subcomponentmanager.h" -#include "model/viewlogger.h" -#include <itemlibraryview.h> #include <itemlibrarywidget.h> -#include <navigatorview.h> -#include <stateseditorview.h> -#include <formeditorview.h> -#include <propertyeditor.h> #include <formeditorwidget.h> #include <toolbox.h> -#include <basetexteditmodifier.h> -#include <componenttextmodifier.h> #include <metainfo.h> #include <invalidargumentexception.h> -#include <componentview.h> #include <componentaction.h> #include <qmlobjectnode.h> -#include <rewriterview.h> #include <rewritingexception.h> #include <nodelistproperty.h> #include <variantproperty.h> #include <rewritingexception.h> -#include <model/modelnodecontextmenu.h> +#include <modelnodecontextmenu.h> #include <designmodewidget.h> #include <projectexplorer/projectexplorer.h> @@ -95,41 +84,9 @@ enum { namespace QmlDesigner { -class DesignDocumentControllerPrivate { -public: - QWeakPointer<FormEditorView> formEditorView; - - QWeakPointer<ItemLibraryView> itemLibraryView; - QWeakPointer<NavigatorView> navigator; - QWeakPointer<PropertyEditor> propertyEditorView; - QWeakPointer<StatesEditorView> statesEditorView; - QWeakPointer<QStackedWidget> stackedWidget; - QWeakPointer<NodeInstanceView> nodeInstanceView; - QWeakPointer<ComponentView> componentView; - - QWeakPointer<QmlDesigner::Model> model; - QWeakPointer<QmlDesigner::Model> subComponentModel; - QWeakPointer<QmlDesigner::Model> masterModel; - QWeakPointer<QPlainTextEdit> textEdit; - QWeakPointer<RewriterView> rewriterView; - QmlDesigner::BaseTextEditModifier *textModifier; - QmlDesigner::ComponentTextModifier *componentTextModifier; - QWeakPointer<SubComponentManager> subComponentManager; - QWeakPointer<Internal::ViewLogger> viewLogger; - ModelNode componentNode; - - QString fileName; - QUrl searchPath; - bool documentLoaded; - bool syncBlocked; - int qt_versionId; - static bool clearCrumblePath; - static bool pushCrumblePath; -}; - -bool DesignDocumentControllerPrivate::clearCrumblePath = true; -bool DesignDocumentControllerPrivate::pushCrumblePath = true; +bool DesignDocumentController::s_clearCrumblePath = true; +bool DesignDocumentController::s_pushCrumblePath = true; /** @@ -139,11 +96,10 @@ bool DesignDocumentControllerPrivate::pushCrumblePath = true; and the different views/widgets accessing it. */ DesignDocumentController::DesignDocumentController(QObject *parent) : - QObject(parent), - d(new DesignDocumentControllerPrivate) + QObject(parent) { - d->documentLoaded = false; - d->syncBlocked = false; + m_documentLoaded = false; + m_syncBlocked = false; ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance(); connect(projectExplorer, SIGNAL(currentProjectChanged(ProjectExplorer::Project*)), this, SLOT(activeQtVersionChanged())); @@ -152,58 +108,56 @@ DesignDocumentController::DesignDocumentController(QObject *parent) : DesignDocumentController::~DesignDocumentController() { - delete d->model.data(); - delete d->subComponentModel.data(); - - delete d->rewriterView.data(); + delete m_model.data(); + delete m_subComponentModel.data(); - if (d->componentTextModifier) //componentTextModifier might not be created - delete d->componentTextModifier; + delete m_rewriterView.data(); - delete d; + if (m_componentTextModifier) //componentTextModifier might not be created + delete m_componentTextModifier; } Model *DesignDocumentController::model() const { - return d->model.data(); + return m_model.data(); } Model *DesignDocumentController::masterModel() const { - return d->masterModel.data(); + return m_masterModel.data(); } void DesignDocumentController::detachNodeInstanceView() { - if (d->nodeInstanceView) - model()->detachView(d->nodeInstanceView.data()); + if (m_nodeInstanceView) + model()->detachView(m_nodeInstanceView.data()); } void DesignDocumentController::attachNodeInstanceView() { - if (d->nodeInstanceView) { - model()->attachView(d->nodeInstanceView.data()); + if (m_nodeInstanceView) { + model()->attachView(m_nodeInstanceView.data()); } - if (d->formEditorView) { - d->formEditorView->resetView(); + if (m_formEditorView) { + m_formEditorView->resetView(); } } void DesignDocumentController::changeToMasterModel() { - d->model->detachView(d->rewriterView.data()); - d->rewriterView->setTextModifier(d->textModifier); - d->model = d->masterModel; - d->model->attachView(d->rewriterView.data()); - d->componentNode = d->rewriterView->rootModelNode(); + m_model->detachView(m_rewriterView.data()); + m_rewriterView->setTextModifier(m_textModifier); + m_model = m_masterModel; + m_model->attachView(m_rewriterView.data()); + m_componentNode = m_rewriterView->rootModelNode(); } QVariant DesignDocumentController::createCrumbleBarInfo() { CrumbleBarInfo info; info.fileName = fileName(); - info.modelNode = d->componentNode; + info.modelNode = m_componentNode; return QVariant::fromValue<CrumbleBarInfo>(info); } @@ -214,7 +168,7 @@ QWidget *DesignDocumentController::centralWidget() const QString DesignDocumentController::pathToQt() const { - QtSupport::BaseQtVersion *activeQtVersion = QtSupport::QtVersionManager::instance()->version(d->qt_versionId); + QtSupport::BaseQtVersion *activeQtVersion = QtSupport::QtVersionManager::instance()->version(m_qt_versionId); if (activeQtVersion && (activeQtVersion->qtVersion().majorVersion > 3) && (activeQtVersion->type() == QLatin1String(QtSupport::Constants::DESKTOPQT) || activeQtVersion->type() == QLatin1String(QtSupport::Constants::SIMULATORQT))) @@ -227,7 +181,7 @@ QString DesignDocumentController::pathToQt() const */ bool DesignDocumentController::isModelSyncBlocked() const { - return d->syncBlocked; + return m_syncBlocked; } /*! @@ -239,35 +193,35 @@ bool DesignDocumentController::isModelSyncBlocked() const */ void DesignDocumentController::blockModelSync(bool block) { - if (d->syncBlocked == block) + if (m_syncBlocked == block) return; - d->syncBlocked = block; + m_syncBlocked = block; - if (d->textModifier) { - if (d->syncBlocked) { + if (m_textModifier) { + if (m_syncBlocked) { detachNodeInstanceView(); - d->textModifier->deactivateChangeSignals(); + m_textModifier->deactivateChangeSignals(); } else { activeQtVersionChanged(); changeToMasterModel(); QmlModelState state; //We go back to base state (and back again) to avoid side effects from text editing. - if (d->statesEditorView && d->statesEditorView->model()) { - state = d->statesEditorView->currentState(); - d->statesEditorView->setCurrentState(d->statesEditorView->baseState()); + if (m_statesEditorView && m_statesEditorView->model()) { + state = m_statesEditorView->currentState(); + m_statesEditorView->setCurrentState(m_statesEditorView->baseState()); } - d->textModifier->reactivateChangeSignals(); + m_textModifier->reactivateChangeSignals(); - if (state.isValid() && d->statesEditorView) - d->statesEditorView->setCurrentState(state); + if (state.isValid() && m_statesEditorView) + m_statesEditorView->setCurrentState(state); attachNodeInstanceView(); - if (d->propertyEditorView) - d->propertyEditorView->resetView(); - if (d->formEditorView) - d->formEditorView->resetView(); + if (m_propertyEditorView) + m_propertyEditorView->resetView(); + if (m_formEditorView) + m_formEditorView->resetView(); } } } @@ -277,43 +231,43 @@ void DesignDocumentController::blockModelSync(bool block) */ QList<RewriterView::Error> DesignDocumentController::qmlErrors() const { - return d->rewriterView->errors(); + return m_rewriterView->errors(); } void DesignDocumentController::setItemLibraryView(ItemLibraryView* itemLibraryView) { - d->itemLibraryView = itemLibraryView; + m_itemLibraryView = itemLibraryView; } void DesignDocumentController::setNavigator(NavigatorView* navigatorView) { - d->navigator = navigatorView; + m_navigator = navigatorView; } void DesignDocumentController::setPropertyEditorView(PropertyEditor *propertyEditor) { - d->propertyEditorView = propertyEditor; + m_propertyEditorView = propertyEditor; } void DesignDocumentController::setStatesEditorView(StatesEditorView* statesEditorView) { - d->statesEditorView = statesEditorView; + m_statesEditorView = statesEditorView; } void DesignDocumentController::setFormEditorView(FormEditorView *formEditorView) { - d->formEditorView = formEditorView; + m_formEditorView = formEditorView; } void DesignDocumentController::setNodeInstanceView(NodeInstanceView *nodeInstanceView) { - d->nodeInstanceView = nodeInstanceView; + m_nodeInstanceView = nodeInstanceView; } void DesignDocumentController::setComponentView(ComponentView *componentView) { - d->componentView = componentView; - connect(d->componentView->action(), SIGNAL(currentComponentChanged(ModelNode)), SLOT(changeCurrentModelTo(ModelNode))); + m_componentView = componentView; + connect(componentView->action(), SIGNAL(currentComponentChanged(ModelNode)), SLOT(changeCurrentModelTo(ModelNode))); } static inline bool compareCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo1, const CrumbleBarInfo &crumbleBarInfo2) @@ -323,20 +277,20 @@ static inline bool compareCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo1, void DesignDocumentController::setCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo) { - DesignDocumentControllerPrivate::clearCrumblePath = false; - DesignDocumentControllerPrivate::pushCrumblePath = false; - while (!compareCrumbleBarInfo(d->formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(), crumbleBarInfo)) - d->formEditorView->crumblePath()->popElement(); + s_clearCrumblePath = false; + s_pushCrumblePath = false; + while (!compareCrumbleBarInfo(m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(), crumbleBarInfo)) + m_formEditorView->crumblePath()->popElement(); Core::EditorManager::openEditor(crumbleBarInfo.fileName); - DesignDocumentControllerPrivate::pushCrumblePath = true; + s_pushCrumblePath = true; Internal::DesignModeWidget::instance()->currentDesignDocumentController()->changeToSubComponent(crumbleBarInfo.modelNode); - DesignDocumentControllerPrivate::clearCrumblePath = true; + s_clearCrumblePath = true; } void DesignDocumentController::setBlockCrumbleBar(bool b) { - DesignDocumentControllerPrivate::clearCrumblePath = !b; - DesignDocumentControllerPrivate::pushCrumblePath = !b; + s_clearCrumblePath = !b; + s_pushCrumblePath = !b; } QString DesignDocumentController::displayName() const @@ -349,14 +303,14 @@ QString DesignDocumentController::displayName() const QString DesignDocumentController::simplfiedDisplayName() const { - if (!d->componentNode.isRootNode()) { - if (d->componentNode.id().isEmpty()) { - if (d->formEditorView->rootModelNode().id().isEmpty()) { - return d->formEditorView->rootModelNode().simplifiedTypeName(); + if (!m_componentNode.isRootNode()) { + if (m_componentNode.id().isEmpty()) { + if (m_formEditorView->rootModelNode().id().isEmpty()) { + return m_formEditorView->rootModelNode().simplifiedTypeName(); } - return d->formEditorView->rootModelNode().id(); + return m_formEditorView->rootModelNode().id(); } - return d->componentNode.id(); + return m_componentNode.id(); } QStringList list = displayName().split(QLatin1Char('/')); @@ -365,24 +319,24 @@ QString DesignDocumentController::simplfiedDisplayName() const QString DesignDocumentController::fileName() const { - return d->fileName; + return m_fileName; } void DesignDocumentController::setFileName(const QString &fileName) { - d->fileName = fileName; + m_fileName = fileName; if (QFileInfo(fileName).exists()) { - d->searchPath = QUrl::fromLocalFile(fileName); + m_searchPath = QUrl::fromLocalFile(fileName); } else { - d->searchPath = QUrl(fileName); + m_searchPath = QUrl(fileName); } - if (d->model) - d->model->setFileUrl(d->searchPath); + if (m_model) + m_model->setFileUrl(m_searchPath); - if (d->itemLibraryView) - d->itemLibraryView->widget()->setResourcePath(QFileInfo(fileName).absolutePath()); + if (m_itemLibraryView) + m_itemLibraryView->widget()->setResourcePath(QFileInfo(fileName).absolutePath()); emit displayNameChanged(displayName()); } @@ -390,7 +344,7 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit * { Q_CHECK_PTR(edit); - d->textEdit = edit; + m_textEdit = edit; connect(edit, SIGNAL(undoAvailable(bool)), this, SIGNAL(undoAvailable(bool))); @@ -399,70 +353,70 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit * connect(edit, SIGNAL(modificationChanged(bool)), this, SIGNAL(dirtyStateChanged(bool))); - d->textModifier = new BaseTextEditModifier(dynamic_cast<TextEditor::BaseTextEditorWidget*>(d->textEdit.data())); + m_textModifier = new BaseTextEditModifier(dynamic_cast<TextEditor::BaseTextEditorWidget*>(m_textEdit.data())); - d->componentTextModifier = 0; + m_componentTextModifier = 0; - //d->masterModel = Model::create(d->textModifier, d->searchPath, errors); + //masterModel = Model::create(textModifier, searchPath, errors); - d->masterModel = Model::create("QtQuick.Rectangle", 1, 0); + m_masterModel = Model::create("QtQuick.Rectangle", 1, 0); #if defined(VIEWLOGGER) - d->viewLogger = new Internal::ViewLogger(d->model.data()); - d->masterModel->attachView(d->viewLogger.data()); + m_viewLogger = new Internal::ViewLogger(m_model.data()); + m_masterModel->attachView(m_viewLogger.data()); #endif - d->masterModel->setFileUrl(d->searchPath); + m_masterModel->setFileUrl(m_searchPath); - d->subComponentModel = Model::create("QtQuick.Rectangle", 1, 0); - d->subComponentModel->setFileUrl(d->searchPath); + m_subComponentModel = Model::create("QtQuick.Rectangle", 1, 0); + m_subComponentModel->setFileUrl(m_searchPath); - d->rewriterView = new RewriterView(RewriterView::Amend, d->masterModel.data()); - d->rewriterView->setTextModifier( d->textModifier); - connect(d->rewriterView.data(), SIGNAL(errorsChanged(QList<RewriterView::Error>)), + m_rewriterView = new RewriterView(RewriterView::Amend, m_masterModel.data()); + m_rewriterView->setTextModifier( m_textModifier); + connect(m_rewriterView.data(), SIGNAL(errorsChanged(QList<RewriterView::Error>)), this, SIGNAL(qmlErrorsChanged(QList<RewriterView::Error>))); - d->masterModel->attachView(d->rewriterView.data()); - d->model = d->masterModel; - d->componentNode = d->rewriterView->rootModelNode(); + m_masterModel->attachView(m_rewriterView.data()); + m_model = m_masterModel; + m_componentNode = m_rewriterView->rootModelNode(); - d->subComponentManager = new SubComponentManager(d->masterModel.data(), this); - d->subComponentManager->update(d->searchPath, d->model->imports()); + m_subComponentManager = new SubComponentManager(m_masterModel.data(), this); + m_subComponentManager->update(m_searchPath, m_model->imports()); loadCurrentModel(); - d->masterModel->attachView(d->componentView.data()); + m_masterModel->attachView(m_componentView.data()); - return d->rewriterView->errors(); + return m_rewriterView->errors(); } void DesignDocumentController::changeCurrentModelTo(const ModelNode &node) { - if (d->componentNode == node) + if (m_componentNode == node) return; if (Internal::DesignModeWidget::instance()->currentDesignDocumentController() != this) return; - DesignDocumentControllerPrivate::clearCrumblePath = false; - while (d->formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isValid() && - !d->formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isRootNode()) - d->formEditorView->crumblePath()->popElement(); - if (node.isRootNode() && d->formEditorView->crumblePath()->dataForLastIndex().isValid()) - d->formEditorView->crumblePath()->popElement(); + s_clearCrumblePath = false; + while (m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isValid() && + !m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isRootNode()) + m_formEditorView->crumblePath()->popElement(); + if (node.isRootNode() && m_formEditorView->crumblePath()->dataForLastIndex().isValid()) + m_formEditorView->crumblePath()->popElement(); changeToSubComponent(node); - DesignDocumentControllerPrivate::clearCrumblePath = true; + s_clearCrumblePath = true; } void DesignDocumentController::changeToSubComponent(const ModelNode &componentNode) { - Q_ASSERT(d->masterModel); - QWeakPointer<Model> oldModel = d->model; + Q_ASSERT(m_masterModel); + QWeakPointer<Model> oldModel = m_model; Q_ASSERT(oldModel.data()); - if (d->model == d->subComponentModel) { + if (m_model == m_subComponentModel) { changeToMasterModel(); } - QString componentText = d->rewriterView->extractText(QList<ModelNode>() << componentNode).value(componentNode); + QString componentText = m_rewriterView->extractText(QList<ModelNode>() << componentNode).value(componentNode); if (componentText.isEmpty()) return; @@ -472,110 +426,110 @@ void DesignDocumentController::changeToSubComponent(const ModelNode &componentNo explicitComponent = true; } - d->componentNode = componentNode; + m_componentNode = componentNode; if (!componentNode.isRootNode()) { - Q_ASSERT(d->model == d->masterModel); + Q_ASSERT(m_model == m_masterModel); Q_ASSERT(componentNode.isValid()); //change to subcomponent model ModelNode rootModelNode = componentNode.view()->rootModelNode(); Q_ASSERT(rootModelNode.isValid()); - if (d->componentTextModifier) - delete d->componentTextModifier; + if (m_componentTextModifier) + delete m_componentTextModifier; int componentStartOffset; int componentEndOffset; - int rootStartOffset = d->rewriterView->nodeOffset(rootModelNode); + int rootStartOffset = m_rewriterView->nodeOffset(rootModelNode); if (explicitComponent) { //the component is explciit we have to find the first definition inside - componentStartOffset = d->rewriterView->firstDefinitionInsideOffset(componentNode); - componentEndOffset = componentStartOffset + d->rewriterView->firstDefinitionInsideLength(componentNode); + componentStartOffset = m_rewriterView->firstDefinitionInsideOffset(componentNode); + componentEndOffset = componentStartOffset + m_rewriterView->firstDefinitionInsideLength(componentNode); } else { //the component is implicit - componentStartOffset = d->rewriterView->nodeOffset(componentNode); - componentEndOffset = componentStartOffset + d->rewriterView->nodeLength(componentNode); + componentStartOffset = m_rewriterView->nodeOffset(componentNode); + componentEndOffset = componentStartOffset + m_rewriterView->nodeLength(componentNode); } - d->componentTextModifier = new ComponentTextModifier (d->textModifier, componentStartOffset, componentEndOffset, rootStartOffset); + m_componentTextModifier = new ComponentTextModifier (m_textModifier, componentStartOffset, componentEndOffset, rootStartOffset); - d->model->detachView(d->rewriterView.data()); + m_model->detachView(m_rewriterView.data()); - d->rewriterView->setTextModifier(d->componentTextModifier); + m_rewriterView->setTextModifier(m_componentTextModifier); - d->subComponentModel->attachView(d->rewriterView.data()); + m_subComponentModel->attachView(m_rewriterView.data()); - Q_ASSERT(d->rewriterView->rootModelNode().isValid()); + Q_ASSERT(m_rewriterView->rootModelNode().isValid()); - d->model = d->subComponentModel; + m_model = m_subComponentModel; } - Q_ASSERT(d->masterModel); - Q_ASSERT(d->model); + Q_ASSERT(m_masterModel); + Q_ASSERT(m_model); loadCurrentModel(); - d->componentView->setComponentNode(componentNode); + m_componentView->setComponentNode(componentNode); } void DesignDocumentController::changeToExternalSubComponent(const QString &fileName) { - DesignDocumentControllerPrivate::clearCrumblePath = false; + s_clearCrumblePath = false; Core::EditorManager::openEditor(fileName); - DesignDocumentControllerPrivate::clearCrumblePath = true; + s_clearCrumblePath = true; } void DesignDocumentController::goIntoComponent() { - if (!d->model) + if (!m_model) return; QList<ModelNode> selectedNodes; - if (d->formEditorView) - selectedNodes = d->formEditorView->selectedModelNodes(); + if (m_formEditorView) + selectedNodes = m_formEditorView->selectedModelNodes(); - DesignDocumentControllerPrivate::clearCrumblePath = false; + s_clearCrumblePath = false; if (selectedNodes.count() == 1) ModelNodeAction::goIntoComponent(selectedNodes.first()); - DesignDocumentControllerPrivate::clearCrumblePath = true; + s_clearCrumblePath = true; } void DesignDocumentController::loadCurrentModel() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - Q_ASSERT(d->masterModel); - Q_ASSERT(d->model); - d->model->setMasterModel(d->masterModel.data()); - d->masterModel->attachView(d->componentView.data()); + Q_ASSERT(m_masterModel); + Q_ASSERT(m_model); + m_model->setMasterModel(m_masterModel.data()); + m_masterModel->attachView(m_componentView.data()); - d->nodeInstanceView->setPathToQt(pathToQt()); - d->model->attachView(d->nodeInstanceView.data()); - d->model->attachView(d->navigator.data()); - d->itemLibraryView->widget()->setResourcePath(QFileInfo(d->fileName).absolutePath()); + m_nodeInstanceView->setPathToQt(pathToQt()); + m_model->attachView(m_nodeInstanceView.data()); + m_model->attachView(m_navigator.data()); + m_itemLibraryView->widget()->setResourcePath(QFileInfo(m_fileName).absolutePath()); - d->model->attachView(d->formEditorView.data()); - d->model->attachView(d->itemLibraryView.data()); + m_model->attachView(m_formEditorView.data()); + m_model->attachView(m_itemLibraryView.data()); - if (!d->textEdit->parent()) // hack to prevent changing owner of external text edit - d->stackedWidget->addWidget(d->textEdit.data()); + if (!m_textEdit->parent()) // hack to prevent changing owner of external text edit + m_stackedWidget->addWidget(m_textEdit.data()); // Will call setCurrentState (formEditorView etc has to be constructed first) - d->model->attachView(d->statesEditorView.data()); + m_model->attachView(m_statesEditorView.data()); - d->model->attachView(d->propertyEditorView.data()); + m_model->attachView(m_propertyEditorView.data()); - if (DesignDocumentControllerPrivate::clearCrumblePath) - d->formEditorView->crumblePath()->clear(); + if (s_clearCrumblePath) + m_formEditorView->crumblePath()->clear(); - if (DesignDocumentControllerPrivate::pushCrumblePath && - !compareCrumbleBarInfo(d->formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(), + if (s_pushCrumblePath && + !compareCrumbleBarInfo(m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(), createCrumbleBarInfo().value<CrumbleBarInfo>())) - d->formEditorView->crumblePath()->pushElement(simplfiedDisplayName(), createCrumbleBarInfo()); + m_formEditorView->crumblePath()->pushElement(simplfiedDisplayName(), createCrumbleBarInfo()); - d->documentLoaded = true; - d->subComponentManager->update(d->searchPath, d->model->imports()); - Q_ASSERT(d->masterModel); + m_documentLoaded = true; + m_subComponentManager->update(m_searchPath, m_model->imports()); + Q_ASSERT(m_masterModel); QApplication::restoreOverrideCursor(); } @@ -589,7 +543,7 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(const QByteArray void DesignDocumentController::saveAs(QWidget *parent) { - QFileInfo oldFileInfo(d->fileName); + QFileInfo oldFileInfo(m_fileName); XUIFileDialog::runSaveFileDialog(oldFileInfo.path(), parent, this, SLOT(doRealSaveAs(QString))); } @@ -621,8 +575,8 @@ void DesignDocumentController::doRealSaveAs(const QString &fileName) bool DesignDocumentController::isDirty() const { - if (d->textEdit) - return d->textEdit->document()->isModified(); + if (m_textEdit) + return m_textEdit->document()->isModified(); else return false; } @@ -630,33 +584,33 @@ bool DesignDocumentController::isDirty() const bool DesignDocumentController::isUndoAvailable() const { - if (d->textEdit) - return d->textEdit->document()->isUndoAvailable(); + if (m_textEdit) + return m_textEdit->document()->isUndoAvailable(); return false; } bool DesignDocumentController::isRedoAvailable() const { - if (d->textEdit) - return d->textEdit->document()->isRedoAvailable(); + if (m_textEdit) + return m_textEdit->document()->isRedoAvailable(); return false; } void DesignDocumentController::close() { - d->documentLoaded = false; + m_documentLoaded = false; emit designDocumentClosed(); } void DesignDocumentController::deleteSelected() { - if (!d->model) + if (!m_model) return; try { - if (d->formEditorView) { - RewriterTransaction transaction(d->formEditorView.data()); - QList<ModelNode> toDelete = d->formEditorView->selectedModelNodes(); + if (m_formEditorView) { + RewriterTransaction transaction(m_formEditorView.data()); + QList<ModelNode> toDelete = m_formEditorView->selectedModelNodes(); foreach (ModelNode node, toDelete) { if (node.isValid() && !node.isRootNode() && QmlObjectNode(node).isValid()) QmlObjectNode(node).destroy(); @@ -669,15 +623,15 @@ void DesignDocumentController::deleteSelected() void DesignDocumentController::copySelected() { - QScopedPointer<Model> model(Model::create("QtQuick.Rectangle", 1, 0, this->model())); - model->setFileUrl(d->model->fileUrl()); - model->changeImports(d->model->imports(), QList<Import>()); + QScopedPointer<Model> copyModel(Model::create("QtQuick.Rectangle", 1, 0, model())); + copyModel->setFileUrl(model()->fileUrl()); + copyModel->changeImports(model()->imports(), QList<Import>()); - Q_ASSERT(model); + Q_ASSERT(copyModel); DesignDocumentControllerView view; - d->model->attachView(&view); + m_model->attachView(&view); if (view.selectedModelNodes().isEmpty()) return; @@ -697,9 +651,9 @@ void DesignDocumentController::copySelected() if (!selectedNode.isValid()) return; - d->model->detachView(&view); + m_model->detachView(&view); - model->attachView(&view); + copyModel->attachView(&view); view.replaceModel(selectedNode); Q_ASSERT(view.rootModelNode().isValid()); @@ -707,8 +661,8 @@ void DesignDocumentController::copySelected() view.toClipboard(); } else { //multi items selected - d->model->detachView(&view); - model->attachView(&view); + m_model->detachView(&view); + copyModel->attachView(&view); foreach (ModelNode node, view.rootModelNode().allDirectSubModelNodes()) { node.destroy(); @@ -764,17 +718,17 @@ static void scatterItem(ModelNode pastedNode, const ModelNode targetNode, int of void DesignDocumentController::paste() { - QScopedPointer<Model> model(Model::create("empty", 1, 0, this->model())); - model->setFileUrl(d->model->fileUrl()); - model->changeImports(d->model->imports(), QList<Import>()); + QScopedPointer<Model> pasteModel(Model::create("empty", 1, 0, model())); + pasteModel->setFileUrl(model()->fileUrl()); + pasteModel->changeImports(model()->imports(), QList<Import>()); - Q_ASSERT(model); + Q_ASSERT(pasteModel); - if (!d->model) + if (!pasteModel) return; DesignDocumentControllerView view; - model->attachView(&view); + pasteModel->attachView(&view); view.fromClipboard(); @@ -787,8 +741,8 @@ void DesignDocumentController::paste() QList<ModelNode> selectedNodes = rootNode.allDirectSubModelNodes(); qDebug() << rootNode; qDebug() << selectedNodes; - model->detachView(&view); - d->model->attachView(&view); + pasteModel->detachView(&view); + m_model->attachView(&view); ModelNode targetNode; @@ -813,7 +767,7 @@ void DesignDocumentController::paste() QList<ModelNode> pastedNodeList; try { - RewriterTransaction transaction(d->formEditorView.data()); + RewriterTransaction transaction(m_formEditorView.data()); int offset = double(qrand()) / RAND_MAX * 20 - 10; @@ -831,10 +785,10 @@ void DesignDocumentController::paste() } } else { try { - RewriterTransaction transaction(d->formEditorView.data()); + RewriterTransaction transaction(m_formEditorView.data()); - model->detachView(&view); - d->model->attachView(&view); + pasteModel->detachView(&view); + m_model->attachView(&view); ModelNode pastedNode(view.insertModel(rootNode)); ModelNode targetNode; @@ -870,11 +824,11 @@ void DesignDocumentController::paste() void DesignDocumentController::selectAll() { - if (!d->model) + if (!m_model) return; DesignDocumentControllerView view; - d->model->attachView(&view); + m_model->attachView(&view); QList<ModelNode> allNodesExceptRootNode(view.allModelNodes()); @@ -884,21 +838,21 @@ void DesignDocumentController::selectAll() RewriterView *DesignDocumentController::rewriterView() const { - return d->rewriterView.data(); + return m_rewriterView.data(); } void DesignDocumentController::undo() { - if (d->rewriterView && !d->rewriterView->modificationGroupActive()) - d->textEdit->undo(); - d->propertyEditorView->resetView(); + if (m_rewriterView && !m_rewriterView->modificationGroupActive()) + m_textEdit->undo(); + m_propertyEditorView->resetView(); } void DesignDocumentController::redo() { - if (d->rewriterView && !d->rewriterView->modificationGroupActive()) - d->textEdit->redo(); - d->propertyEditorView->resetView(); + if (m_rewriterView && !m_rewriterView->modificationGroupActive()) + m_textEdit->redo(); + m_propertyEditorView->resetView(); } static inline QtSupport::BaseQtVersion *getActiveQtVersion(DesignDocumentController *controller) @@ -929,48 +883,48 @@ void DesignDocumentController::activeQtVersionChanged() QtSupport::BaseQtVersion *newQtVersion = getActiveQtVersion(this); if (!newQtVersion ) { - d->qt_versionId = -1; + m_qt_versionId = -1; return; } - if (d->qt_versionId == newQtVersion->uniqueId()) + if (m_qt_versionId == newQtVersion->uniqueId()) return; - d->qt_versionId = newQtVersion->uniqueId(); + m_qt_versionId = newQtVersion->uniqueId(); - if (d->nodeInstanceView) - d->nodeInstanceView->setPathToQt(pathToQt()); + if (m_nodeInstanceView) + m_nodeInstanceView->setPathToQt(pathToQt()); } #ifdef ENABLE_TEXT_VIEW void DesignDocumentController::showText() { - d->stackedWidget->setCurrentWidget(d->textEdit.data()); + m_stackedWidget->setCurrentWidget(m_textEdit.data()); } #endif // ENABLE_TEXT_VIEW #ifdef ENABLE_TEXT_VIEW void DesignDocumentController::showForm() { - d->stackedWidget->setCurrentWidget(d->formEditorView->widget()); + m_stackedWidget->setCurrentWidget(m_formEditorView->widget()); } #endif // ENABLE_TEXT_VIEW bool DesignDocumentController::save(QWidget *parent) { - // qDebug() << "Saving document to file \"" << d->fileName << "\"..."; + // qDebug() << "Saving document to file \"" << fileName << "\"..."; // - if (d->fileName.isEmpty()) { + if (m_fileName.isEmpty()) { saveAs(parent); return true; } - Utils::FileSaver saver(d->fileName, QIODevice::Text); - if (d->model) - saver.write(d->textEdit->toPlainText().toLatin1()); - if (!saver.finalize(parent ? parent : d->stackedWidget.data())) + Utils::FileSaver saver(m_fileName, QIODevice::Text); + if (m_model) + saver.write(m_textEdit->toPlainText().toLatin1()); + if (!saver.finalize(parent ? parent : m_stackedWidget.data())) return false; - if (d->model) - d->textEdit->setPlainText(d->textEdit->toPlainText()); // clear undo/redo history + if (m_model) + m_textEdit->setPlainText(m_textEdit->toPlainText()); // clear undo/redo history return true; } @@ -979,7 +933,7 @@ bool DesignDocumentController::save(QWidget *parent) QString DesignDocumentController::contextHelpId() const { DesignDocumentControllerView view; - d->model->attachView(&view); + m_model->attachView(&view); QList<ModelNode> nodes = view.selectedModelNodes(); QString helpId; diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h index 097c5a3919..6d74305e9c 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h @@ -32,9 +32,24 @@ #include "rewriterview.h" +#include <model.h> +#include <rewriterview.h> +#include <itemlibraryview.h> +#include <navigatorview.h> +#include <stateseditorview.h> +#include <formeditorview.h> +#include <propertyeditor.h> +#include <componentview.h> +#include <basetexteditmodifier.h> +#include <componenttextmodifier.h> +#include <subcomponentmanager.h> +#include <model/viewlogger.h> + #include <QObject> #include <QString> +#include <QStackedWidget> + QT_BEGIN_NAMESPACE class QUndoStack; class QWidget; @@ -46,23 +61,14 @@ QT_END_NAMESPACE namespace QmlDesigner { -class Model; class ModelNode; class TextModifier; class QmlObjectNode; -class RewriterView; -class ItemLibraryView; -class NavigatorView; -class ComponentView; -class PropertyEditor; -class StatesEditorView; -class FormEditorView; struct CrumbleBarInfo; class DesignDocumentController: public QObject { Q_OBJECT - public: DesignDocumentController(QObject *parent); ~DesignDocumentController(); @@ -71,7 +77,7 @@ public: QString simplfiedDisplayName() const; QString fileName() const; - void setFileName(const QString &fileName); + void setFileName(const QString &m_fileName); QList<RewriterView::Error> loadMaster(QPlainTextEdit *edit); QList<RewriterView::Error> loadMaster(const QByteArray &qml); @@ -93,13 +99,13 @@ public: QString contextHelpId() const; QList<RewriterView::Error> qmlErrors() const; - void setItemLibraryView(ItemLibraryView* itemLibraryView); + void setItemLibraryView(ItemLibraryView* m_itemLibraryView); void setNavigator(NavigatorView* navigatorView); void setPropertyEditorView(PropertyEditor *propertyEditor); - void setStatesEditorView(StatesEditorView* statesEditorView); - void setFormEditorView(FormEditorView *formEditorView); - void setNodeInstanceView(NodeInstanceView *nodeInstanceView); - void setComponentView(ComponentView *componentView); + void setStatesEditorView(StatesEditorView* m_statesEditorView); + void setFormEditorView(FormEditorView *m_formEditorView); + void setNodeInstanceView(NodeInstanceView *m_nodeInstanceView); + void setComponentView(ComponentView *m_componentView); void setCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo); static void setBlockCrumbleBar(bool); @@ -128,7 +134,7 @@ public slots: void activeQtVersionChanged(); void changeCurrentModelTo(const ModelNode &node); void changeToSubComponent(const ModelNode &node); - void changeToExternalSubComponent(const QString &fileName); + void changeToExternalSubComponent(const QString &m_fileName); void goIntoComponent(); #ifdef ENABLE_TEXT_VIEW @@ -137,9 +143,9 @@ public slots: #endif // ENABLE_TEXT_VIEW private slots: - void doRealSaveAs(const QString &fileName); + void doRealSaveAs(const QString &m_fileName); -private: +private: // functions void detachNodeInstanceView(); void attachNodeInstanceView(); void changeToMasterModel(); @@ -148,8 +154,35 @@ private: QWidget *centralWidget() const; QString pathToQt() const; - - class DesignDocumentControllerPrivate *d; +private: // variables + QWeakPointer<FormEditorView> m_formEditorView; + + QWeakPointer<ItemLibraryView> m_itemLibraryView; + QWeakPointer<NavigatorView> m_navigator; + QWeakPointer<PropertyEditor> m_propertyEditorView; + QWeakPointer<StatesEditorView> m_statesEditorView; + QWeakPointer<QStackedWidget> m_stackedWidget; + QWeakPointer<NodeInstanceView> m_nodeInstanceView; + QWeakPointer<ComponentView> m_componentView; + + QWeakPointer<Model> m_model; + QWeakPointer<Model> m_subComponentModel; + QWeakPointer<Model> m_masterModel; + QWeakPointer<QPlainTextEdit> m_textEdit; + QWeakPointer<RewriterView> m_rewriterView; + BaseTextEditModifier *m_textModifier; + ComponentTextModifier *m_componentTextModifier; + QWeakPointer<SubComponentManager> m_subComponentManager; + QWeakPointer<Internal::ViewLogger> m_viewLogger; + ModelNode m_componentNode; + + QString m_fileName; + QUrl m_searchPath; + bool m_documentLoaded; + bool m_syncBlocked; + int m_qt_versionId; + static bool s_clearCrumblePath; + static bool s_pushCrumblePath; }; diff --git a/src/plugins/qmldesigner/components/integration/integration.pri b/src/plugins/qmldesigner/components/integration/integration.pri index 1548688998..66efed8971 100644 --- a/src/plugins/qmldesigner/components/integration/integration.pri +++ b/src/plugins/qmldesigner/components/integration/integration.pri @@ -1,7 +1,6 @@ VPATH += $$PWD INCLUDEPATH += $$PWD SOURCES += \ - integrationcore.cpp \ designdocumentcontroller.cpp \ designdocumentcontrollerview.cpp \ utilitypanelcontroller.cpp \ @@ -11,7 +10,6 @@ SOURCES += \ xuifiledialog.cpp HEADERS += \ - integrationcore.h \ designdocumentcontrollerview.h \ designdocumentcontroller.h \ utilitypanelcontroller.h \ diff --git a/src/plugins/qmldesigner/components/integration/integrationcore.cpp b/src/plugins/qmldesigner/components/integration/integrationcore.cpp deleted file mode 100644 index 9c8ba64eb8..0000000000 --- a/src/plugins/qmldesigner/components/integration/integrationcore.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "integrationcore.h" -#include "pluginmanager.h" -#include "itemlibraryview.h" -#include "navigatorwidget.h" -#include "metainfo.h" - -#include <QCoreApplication> -#include <QObject> - -namespace QmlDesigner { - -class CorePrivate -{ - public: - CorePrivate(); - ~CorePrivate(); - - static IntegrationCore *m_instance; - - PluginManager m_pluginManager; -}; - -CorePrivate::CorePrivate() -{ -} - -CorePrivate::~CorePrivate() -{ - MetaInfo::clearGlobal(); -} - -IntegrationCore *CorePrivate::m_instance = 0; - -/*! - \class QmlDesigner::Core - - Convenience class to access the plugin manager singleton, - and manage the lifecycle of static data (e.g. in the metatype system). -*/ - -IntegrationCore::IntegrationCore() : - d(new CorePrivate) -{ - Q_ASSERT(CorePrivate::m_instance == 0); - CorePrivate::m_instance = this; -} - -IntegrationCore::~IntegrationCore() -{ - CorePrivate::m_instance = 0; - delete d; -} - -IntegrationCore *IntegrationCore::instance() -{ - Q_ASSERT(CorePrivate::m_instance); - return CorePrivate::m_instance; -} - -PluginManager *IntegrationCore::pluginManager() const -{ - return &d->m_pluginManager; -} - -} diff --git a/src/plugins/qmldesigner/components/integration/xuifiledialog.cpp b/src/plugins/qmldesigner/components/integration/xuifiledialog.cpp index 29ae301e58..e573d2f3e4 100644 --- a/src/plugins/qmldesigner/components/integration/xuifiledialog.cpp +++ b/src/plugins/qmldesigner/components/integration/xuifiledialog.cpp @@ -27,6 +27,8 @@ ** ****************************************************************************/ +#include <utils/hostosinfo.h> + #include <QDebug> #include <QDir> #include <QObject> @@ -56,21 +58,21 @@ void XUIFileDialog::runSaveFileDialog(const QString& path, QWidget* parent, QObj if (dir.isNull()) dir = XUIFileDialog::defaultFolder(); -#ifdef Q_OS_MAC - QFileDialog *dialog = new QFileDialog(parent, Qt::Sheet); - dialog->setFileMode(QFileDialog::AnyFile); - dialog->setAcceptMode(QFileDialog::AcceptSave); - dialog->setNameFilters(XUIFileDialog::fileNameFilters()); - dialog->setDirectory(dir); - dialog->open(receiver, member); -#else // !Q_OS_MAC - QString caption = QCoreApplication::translate("QmlDesigner::XUIFileDialog", "Save File"); - QString fileName = QFileDialog::getSaveFileName(parent, caption, dir, XUIFileDialog::fileNameFilters().join(";;")); + if (Utils::HostOsInfo::isMacHost()) { + QFileDialog *dialog = new QFileDialog(parent, Qt::Sheet); + dialog->setFileMode(QFileDialog::AnyFile); + dialog->setAcceptMode(QFileDialog::AcceptSave); + dialog->setNameFilters(XUIFileDialog::fileNameFilters()); + dialog->setDirectory(dir); + dialog->open(receiver, member); + } else { + QString caption = QCoreApplication::translate("QmlDesigner::XUIFileDialog", "Save File"); + QString fileName = QFileDialog::getSaveFileName(parent, caption, dir, XUIFileDialog::fileNameFilters().join(";;")); - QmlDesigner::Internal::SignalEmitter emitter; - QObject::connect(&emitter, SIGNAL(fileNameSelected(QString)), receiver, member); - emitter.emitFileNameSelected(fileName); -#endif // Q_OS_MAC + QmlDesigner::Internal::SignalEmitter emitter; + QObject::connect(&emitter, SIGNAL(fileNameSelected(QString)), receiver, member); + emitter.emitFileNameSelected(fileName); + } } QStringList XUIFileDialog::fileNameFilters() diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index e5e208c04a..273fdd9bed 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -29,10 +29,8 @@ #include "itemlibrarywidget.h" -#include <utils/filterlineedit.h> #include <utils/fileutils.h> #include <coreplugin/coreconstants.h> -#include "itemlibrarycomponents.h" #include "itemlibrarymodel.h" #include "itemlibraryimageprovider.h" #include "customdraganddrop.h" @@ -41,7 +39,6 @@ #include "rewritingexception.h" #include <QFileInfo> -#include <QFileIconProvider> #include <QFileSystemModel> #include <QStackedWidget> #include <QGridLayout> @@ -52,131 +49,62 @@ #include <QMenu> #include <QApplication> -#include <QDeclarativeView> #include <QDeclarativeItem> #include <private/qdeclarativeengine_p.h> namespace QmlDesigner { -class MyFileIconProvider : public QFileIconProvider -{ -public: - MyFileIconProvider(const QSize &iconSize) - : QFileIconProvider(), - m_iconSize(iconSize) - {} - - virtual QIcon icon ( const QFileInfo & info ) const - { - QPixmap pixmap(info.absoluteFilePath()); - if (pixmap.isNull()) { - QIcon defaultIcon(QFileIconProvider::icon(info)); - pixmap = defaultIcon.pixmap(defaultIcon.actualSize(m_iconSize)); - } - - if (pixmap.width() == m_iconSize.width() - && pixmap.height() == m_iconSize.height()) - return pixmap; - if ((pixmap.width() > m_iconSize.width()) - || (pixmap.height() > m_iconSize.height())) - return pixmap.scaled(m_iconSize, Qt::KeepAspectRatio, - Qt::SmoothTransformation); - - QPoint offset((m_iconSize.width() - pixmap.width()) / 2, - (m_iconSize.height() - pixmap.height()) / 2); - QImage newIcon(m_iconSize, QImage::Format_ARGB32_Premultiplied); - newIcon.fill(Qt::transparent); - QPainter painter(&newIcon); - painter.drawPixmap(offset, pixmap); - return QPixmap::fromImage(newIcon); - } -private: - QSize m_iconSize; -}; - - -// ---------- ItemLibraryPrivate -class ItemLibraryWidgetPrivate { -public: - ItemLibraryWidgetPrivate(QObject *object); - - Internal::ItemLibraryModel *m_itemLibraryModel; - QFileSystemModel *m_resourcesFileSystemModel; - - QStackedWidget *m_stackedWidget; - Utils::FilterLineEdit *m_lineEdit; - QDeclarativeView *m_itemsView; - Internal::ItemLibraryTreeView *m_resourcesView; - QWeakPointer<ItemLibraryInfo> m_itemLibraryInfo; - - QSize m_itemIconSize, m_resIconSize; - MyFileIconProvider m_iconProvider; - Model *model; -}; - -ItemLibraryWidgetPrivate::ItemLibraryWidgetPrivate(QObject *object) : - m_itemLibraryModel(0), - m_resourcesFileSystemModel(0), - m_stackedWidget(0), - m_lineEdit(0), - m_itemsView(0), - m_resourcesView(0), - m_itemIconSize(24, 24), - m_resIconSize(24, 24), - m_iconProvider(m_resIconSize), - model(0) -{ - Q_UNUSED(object); -} ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : QFrame(parent), - d(new ItemLibraryWidgetPrivate(this)), + m_iconProvider(m_resIconSize), + m_itemIconSize(24, 24), + m_resIconSize(24, 24), + m_itemsView(new QDeclarativeView(this)), + m_resourcesView(new Internal::ItemLibraryTreeView(this)), m_filterFlag(QtBasic) { setWindowTitle(tr("Library", "Title of library view")); /* create Items view and its model */ - d->m_itemsView = new QDeclarativeView(this); - d->m_itemsView->setAttribute(Qt::WA_OpaquePaintEvent); - d->m_itemsView->setAttribute(Qt::WA_NoSystemBackground); - d->m_itemsView->setAcceptDrops(false); - d->m_itemsView->setFocusPolicy(Qt::ClickFocus); - d->m_itemsView->setResizeMode(QDeclarativeView::SizeRootObjectToView); - d->m_itemLibraryModel = new Internal::ItemLibraryModel(QDeclarativeEnginePrivate::getScriptEngine(d->m_itemsView->engine()), this); - d->m_itemLibraryModel->setItemIconSize(d->m_itemIconSize); - - QDeclarativeContext *rootContext = d->m_itemsView->rootContext(); - rootContext->setContextProperty(QLatin1String("itemLibraryModel"), d->m_itemLibraryModel); - rootContext->setContextProperty(QLatin1String("itemLibraryIconWidth"), d->m_itemIconSize.width()); - rootContext->setContextProperty(QLatin1String("itemLibraryIconHeight"), d->m_itemIconSize.height()); + m_itemsView->setAttribute(Qt::WA_OpaquePaintEvent); + m_itemsView->setAttribute(Qt::WA_NoSystemBackground); + m_itemsView->setAcceptDrops(false); + m_itemsView->setFocusPolicy(Qt::ClickFocus); + m_itemsView->setResizeMode(QDeclarativeView::SizeRootObjectToView); + m_itemLibraryModel = new Internal::ItemLibraryModel(QDeclarativeEnginePrivate::getScriptEngine(m_itemsView->engine()), this); + m_itemLibraryModel->setItemIconSize(m_itemIconSize); + + QDeclarativeContext *rootContext = m_itemsView->rootContext(); + rootContext->setContextProperty(QLatin1String("itemLibraryModel"), m_itemLibraryModel.data()); + rootContext->setContextProperty(QLatin1String("itemLibraryIconWidth"), m_itemIconSize.width()); + rootContext->setContextProperty(QLatin1String("itemLibraryIconHeight"), m_itemIconSize.height()); QColor highlightColor = palette().highlight().color(); if (0.5*highlightColor.saturationF()+0.75-highlightColor.valueF() < 0) highlightColor.setHsvF(highlightColor.hsvHueF(),0.1 + highlightColor.saturationF()*2.0, highlightColor.valueF()); - d->m_itemsView->rootContext()->setContextProperty(QLatin1String("highlightColor"), highlightColor); + m_itemsView->rootContext()->setContextProperty(QLatin1String("highlightColor"), highlightColor); // loading the qml has to come after all needed context properties are set - d->m_itemsView->setSource(QUrl("qrc:/ItemLibrary/qml/ItemsView.qml")); + m_itemsView->setSource(QUrl("qrc:/ItemLibrary/qml/ItemsView.qml")); - QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(d->m_itemsView->rootObject()); + QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(m_itemsView->rootObject()); connect(rootItem, SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(int))); connect(rootItem, SIGNAL(itemDragged(int)), this, SLOT(startDragAndDrop(int))); connect(this, SIGNAL(scrollItemsView(QVariant)), rootItem, SLOT(scrollView(QVariant))); connect(this, SIGNAL(resetItemsView()), rootItem, SLOT(resetView())); /* create Resources view and its model */ - d->m_resourcesFileSystemModel = new QFileSystemModel(this); - d->m_resourcesFileSystemModel->setIconProvider(&d->m_iconProvider); - d->m_resourcesView = new Internal::ItemLibraryTreeView(this); - d->m_resourcesView->setModel(d->m_resourcesFileSystemModel); - d->m_resourcesView->setIconSize(d->m_resIconSize); + m_resourcesFileSystemModel = new QFileSystemModel(this); + m_resourcesFileSystemModel->setIconProvider(&m_iconProvider); + m_resourcesView->setModel(m_resourcesFileSystemModel.data()); + m_resourcesView->setIconSize(m_resIconSize); /* create image provider for loading item icons */ - d->m_itemsView->engine()->addImageProvider(QLatin1String("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider); + m_itemsView->engine()->addImageProvider(QLatin1String("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider); /* other widgets */ QTabBar *tabBar = new QTabBar(this); @@ -184,12 +112,12 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : tabBar->addTab(tr("Resources", "Title of library resources view")); tabBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - d->m_lineEdit = new Utils::FilterLineEdit(this); - d->m_lineEdit->setObjectName(QLatin1String("itemLibrarySearchInput")); - d->m_lineEdit->setPlaceholderText(tr("<Filter>", "Library search input hint text")); - d->m_lineEdit->setDragEnabled(false); - d->m_lineEdit->setMinimumWidth(75); - d->m_lineEdit->setTextMargins(0, 0, 20, 0); + m_lineEdit = new Utils::FilterLineEdit(this); + m_lineEdit->setObjectName(QLatin1String("itemLibrarySearchInput")); + m_lineEdit->setPlaceholderText(tr("<Filter>", "Library search input hint text")); + m_lineEdit->setDragEnabled(false); + m_lineEdit->setMinimumWidth(75); + m_lineEdit->setTextMargins(0, 0, 20, 0); QWidget *lineEditFrame = new QWidget(this); lineEditFrame->setObjectName(QLatin1String("itemLibrarySearchInputFrame")); QGridLayout *lineEditLayout = new QGridLayout(lineEditFrame); @@ -197,15 +125,15 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : lineEditLayout->setSpacing(0); lineEditLayout->addItem(new QSpacerItem(5, 3, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 0, 1, 3); lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 0); - lineEditLayout->addWidget(d->m_lineEdit, 1, 1, 1, 1); + lineEditLayout->addWidget(m_lineEdit.data(), 1, 1, 1, 1); lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2); - connect(d->m_lineEdit, SIGNAL(filterChanged(QString)), this, SLOT(setSearchFilter(QString))); + connect(m_lineEdit.data(), SIGNAL(filterChanged(QString)), this, SLOT(setSearchFilter(QString))); - d->m_stackedWidget = new QStackedWidget(this); - d->m_stackedWidget->addWidget(d->m_itemsView); - d->m_stackedWidget->addWidget(d->m_resourcesView); + m_stackedWidget = new QStackedWidget(this); + m_stackedWidget->addWidget(m_itemsView.data()); + m_stackedWidget->addWidget(m_resourcesView.data()); connect(tabBar, SIGNAL(currentChanged(int)), - d->m_stackedWidget, SLOT(setCurrentIndex(int))); + m_stackedWidget.data(), SLOT(setCurrentIndex(int))); connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(updateSearch())); @@ -219,37 +147,28 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : layout->addWidget(tabBar, 0, 0, 1, 1); layout->addWidget(spacer, 1, 0); layout->addWidget(lineEditFrame, 2, 0, 1, 1); - layout->addWidget(d->m_stackedWidget, 3, 0, 1, 1); + layout->addWidget(m_stackedWidget.data(), 3, 0, 1, 1); setResourcePath(QDir::currentPath()); setSearchFilter(QString()); /* style sheets */ setStyleSheet(QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))); - d->m_resourcesView->setStyleSheet( + m_resourcesView->setStyleSheet( QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css"))); } -ItemLibraryWidget::~ItemLibraryWidget() -{ - /* workaround: delete the items view before the model is deleted. - This prevents qml warnings when the item library is destructed. */ - delete d->m_itemsView; - delete d->m_resourcesView; - delete d; -} - void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo) { - if (d->m_itemLibraryInfo.data() == itemLibraryInfo) + if (m_itemLibraryInfo.data() == itemLibraryInfo) return; - if (d->m_itemLibraryInfo) - disconnect(d->m_itemLibraryInfo.data(), SIGNAL(entriesChanged()), + if (m_itemLibraryInfo) + disconnect(m_itemLibraryInfo.data(), SIGNAL(entriesChanged()), this, SLOT(updateModel())); - d->m_itemLibraryInfo = itemLibraryInfo; + m_itemLibraryInfo = itemLibraryInfo; if (itemLibraryInfo) - connect(d->m_itemLibraryInfo.data(), SIGNAL(entriesChanged()), + connect(m_itemLibraryInfo.data(), SIGNAL(entriesChanged()), this, SLOT(updateModel())); updateModel(); @@ -260,9 +179,9 @@ void ItemLibraryWidget::updateImports() { FilterChangeFlag filter; filter = QtBasic; - if (d->model) { + if (m_model) { QStringList imports; - foreach (const Import &import, d->model->imports()) + foreach (const Import &import, m_model->imports()) if (import.isLibraryImport()) imports << import.url(); if (imports.contains("com.nokia.meego", Qt::CaseInsensitive)) @@ -307,31 +226,31 @@ QList<QToolButton *> ItemLibraryWidget::createToolBarWidgets() void ItemLibraryWidget::setSearchFilter(const QString &searchFilter) { - if (d->m_stackedWidget->currentIndex() == 0) { - d->m_itemLibraryModel->setSearchText(searchFilter); + if (m_stackedWidget->currentIndex() == 0) { + m_itemLibraryModel->setSearchText(searchFilter); emit resetItemsView(); - d->m_itemsView->update(); + m_itemsView->update(); } else { QStringList nameFilterList; if (searchFilter.contains('.')) { nameFilterList.append(QString("*%1*").arg(searchFilter)); } else { foreach (const QByteArray &extension, QImageReader::supportedImageFormats()) { - nameFilterList.append(QString("*%1*.%2").arg(searchFilter, QString::fromAscii(extension))); + nameFilterList.append(QString("*%1*.%2").arg(searchFilter, QString::fromLatin1(extension))); } } - d->m_resourcesFileSystemModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); - d->m_resourcesFileSystemModel->setNameFilterDisables(false); - d->m_resourcesFileSystemModel->setNameFilters(nameFilterList); - d->m_resourcesView->expandToDepth(1); - d->m_resourcesView->scrollToTop(); + m_resourcesFileSystemModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); + m_resourcesFileSystemModel->setNameFilterDisables(false); + m_resourcesFileSystemModel->setNameFilters(nameFilterList); + m_resourcesView->expandToDepth(1); + m_resourcesView->scrollToTop(); } } void ItemLibraryWidget::setModel(Model *model) { - d->model = model; + m_model = model; if (!model) return; setItemLibraryInfo(model->metaInfo().itemLibraryInfo()); @@ -340,13 +259,13 @@ void ItemLibraryWidget::setModel(Model *model) void ItemLibraryWidget::emitImportChecked() { - if (!d->model) + if (!m_model) return; bool qtOnlyImport = false; bool meegoImport = false; - foreach (const Import &import, d->model->imports()) { + foreach (const Import &import, m_model->imports()) { if (import.isLibraryImport()) { if (import.url().contains(QString("meego"), Qt::CaseInsensitive)) meegoImport = true; @@ -367,7 +286,7 @@ void ItemLibraryWidget::setImportFilter(FilterChangeFlag flag) return; static bool block = false; - if (!d->model) + if (!m_model) return; if (flag == m_filterFlag) return; @@ -413,36 +332,36 @@ void ItemLibraryWidget::onMeegoChecked(bool b) void ItemLibraryWidget::updateModel() { - d->m_itemLibraryModel->update(d->m_itemLibraryInfo.data(), d->model); + m_itemLibraryModel->update(m_itemLibraryInfo.data(), m_model.data()); updateImports(); updateSearch(); } void ItemLibraryWidget::updateSearch() { - setSearchFilter(d->m_lineEdit->text()); + setSearchFilter(m_lineEdit->text()); } void ItemLibraryWidget::setResourcePath(const QString &resourcePath) { - if (d->m_resourcesView->model() == d->m_resourcesFileSystemModel) { - d->m_resourcesFileSystemModel->setRootPath(resourcePath); - d->m_resourcesView->setRootIndex(d->m_resourcesFileSystemModel->index(resourcePath)); + if (m_resourcesView->model() == m_resourcesFileSystemModel.data()) { + m_resourcesFileSystemModel->setRootPath(resourcePath); + m_resourcesView->setRootIndex(m_resourcesFileSystemModel->index(resourcePath)); } updateSearch(); } void ItemLibraryWidget::startDragAndDrop(int itemLibId) { - QMimeData *mimeData = d->m_itemLibraryModel->getMimeData(itemLibId); + QMimeData *mimeData = m_itemLibraryModel->getMimeData(itemLibId); CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this); const QImage image = qvariant_cast<QImage>(mimeData->imageData()); - drag->setPixmap(d->m_itemLibraryModel->getIcon(itemLibId).pixmap(32, 32)); + drag->setPixmap(m_itemLibraryModel->getIcon(itemLibId).pixmap(32, 32)); drag->setPreview(QPixmap::fromImage(image)); drag->setMimeData(mimeData); - QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(d->m_itemsView->rootObject()); + QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(m_itemsView->rootObject()); connect(rootItem, SIGNAL(stopDragAndDrop()), drag, SLOT(stopDrag())); drag->exec(); @@ -455,32 +374,62 @@ void ItemLibraryWidget::showItemInfo(int /*itemLibId*/) void ItemLibraryWidget::wheelEvent(QWheelEvent *event) { - if (d->m_stackedWidget->currentIndex() == 0 && - d->m_itemsView->rect().contains(event->pos())) { + if (m_stackedWidget->currentIndex() == 0 && + m_itemsView->rect().contains(event->pos())) { emit scrollItemsView(event->delta()); event->accept(); } else QFrame::wheelEvent(event); } - void ItemLibraryWidget::removeImport(const QString &name) - { - if (!d->model) - return; +void ItemLibraryWidget::removeImport(const QString &name) +{ + if (!m_model) + return; + + QList<Import> toBeRemovedImportList; + foreach (const Import &import, m_model->imports()) + if (import.isLibraryImport() && import.url().compare(name, Qt::CaseInsensitive) == 0) + toBeRemovedImportList.append(import); - QList<Import> toBeRemovedImportList; - foreach (const Import &import, d->model->imports()) - if (import.isLibraryImport() && import.url().compare(name, Qt::CaseInsensitive) == 0) - toBeRemovedImportList.append(import); + m_model->changeImports(QList<Import>(), toBeRemovedImportList); +} - d->model->changeImports(QList<Import>(), toBeRemovedImportList); - } +void ItemLibraryWidget::addImport(const QString &name, const QString &version) +{ + if (!m_model) + return; + m_model->changeImports(QList<Import>() << Import::createLibraryImport(name, version), QList<Import>()); +} - void ItemLibraryWidget::addImport(const QString &name, const QString &version) - { - if (!d->model) - return; - d->model->changeImports(QList<Import>() << Import::createLibraryImport(name, version), QList<Import>()); - } +QIcon ItemLibraryFileIconProvider::icon(const QFileInfo &info) const +{ + QPixmap pixmap(info.absoluteFilePath()); + if (pixmap.isNull()) { + QIcon defaultIcon(QFileIconProvider::icon(info)); + pixmap = defaultIcon.pixmap(defaultIcon.actualSize(m_iconSize)); + } + + if (pixmap.width() == m_iconSize.width() + && pixmap.height() == m_iconSize.height()) + return pixmap; + + if ((pixmap.width() > m_iconSize.width()) + || (pixmap.height() > m_iconSize.height())) + return pixmap.scaled(m_iconSize, Qt::KeepAspectRatio, + Qt::SmoothTransformation); + + QPoint offset((m_iconSize.width() - pixmap.width()) / 2, + (m_iconSize.height() - pixmap.height()) / 2); + QImage newIcon(m_iconSize, QImage::Format_ARGB32_Premultiplied); + newIcon.fill(Qt::transparent); + QPainter painter(&newIcon); + painter.drawPixmap(offset, pixmap); + return QPixmap::fromImage(newIcon); +} +ItemLibraryFileIconProvider::ItemLibraryFileIconProvider(const QSize &iconSize) + : QFileIconProvider(), + m_iconSize(iconSize) +{} } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 309be86013..310b964a8f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -31,16 +31,43 @@ #define ITEMLIBRARYWIDGET_H #include "itemlibraryinfo.h" +#include "itemlibrarycomponents.h" + +#include <utils/filterlineedit.h> + #include <QFrame> #include <QToolButton> +#include <QFileIconProvider> +#include <QDeclarativeView> + +QT_BEGIN_NAMESPACE +class QFileSystemModel; +class QStackedWidget; +QT_END_NAMESPACE namespace QmlDesigner { -class ItemLibraryWidgetPrivate; class MetaInfo; class ItemLibraryEntry; class Model; +namespace Internal { + class ItemLibraryModel; + class ItemLibraryTreeView; +} + +class ItemLibraryFileIconProvider : public QFileIconProvider +{ +public: + ItemLibraryFileIconProvider(const QSize &iconSize); + + QIcon icon( const QFileInfo & info ) const; + +private: + QSize m_iconSize; +}; + + class ItemLibraryWidget : public QFrame { Q_OBJECT @@ -52,7 +79,6 @@ class ItemLibraryWidget : public QFrame public: ItemLibraryWidget(QWidget *parent = 0); - virtual ~ItemLibraryWidget(); void setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo); QList<QToolButton *> createToolBarWidgets(); @@ -90,7 +116,21 @@ signals: void meegoChecked(bool b); private: - ItemLibraryWidgetPrivate *d; + ItemLibraryFileIconProvider m_iconProvider; + QSize m_itemIconSize; + QSize m_resIconSize; + + QWeakPointer<ItemLibraryInfo> m_itemLibraryInfo; + + QWeakPointer<Internal::ItemLibraryModel> m_itemLibraryModel; + QWeakPointer<QFileSystemModel> m_resourcesFileSystemModel; + + QWeakPointer<QStackedWidget> m_stackedWidget; + QWeakPointer<Utils::FilterLineEdit> m_lineEdit; + QScopedPointer<QDeclarativeView> m_itemsView; + QScopedPointer<Internal::ItemLibraryTreeView> m_resourcesView; + + QWeakPointer<Model> m_model; FilterChangeFlag m_filterFlag; }; diff --git a/src/plugins/qmldesigner/components/navigator/navigator.pri b/src/plugins/qmldesigner/components/navigator/navigator.pri index 3ce8bc6877..60b0527f5d 100644 --- a/src/plugins/qmldesigner/components/navigator/navigator.pri +++ b/src/plugins/qmldesigner/components/navigator/navigator.pri @@ -4,6 +4,7 @@ SOURCES += navigatorview.cpp \ navigatortreemodel.cpp \ navigatorwidget.cpp \ navigatortreeview.cpp + HEADERS += navigatorview.h \ navigatortreemodel.h \ navigatorwidget.h \ diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 7747eeb127..0dbab09aec 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -39,6 +39,7 @@ #include <rewriterview.h> #include <invalididexception.h> #include <rewritingexception.h> +#include <modelnodecontextmenu.h> #include <QMimeData> #include <QMessageBox> @@ -544,7 +545,7 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty parentPropert } } - if (parentProperty.isDefaultProperty() && parentProperty.parentModelNode().metaInfo().isSubclassOf("<cpp>.QDeclarativeBasePositioner", -1, -1)) { + if (parentProperty.isDefaultProperty() && parentProperty.parentModelNode().metaInfo().isPositioner()) { ModelNode currentNode = node; if (currentNode.hasProperty("x")) currentNode.removeProperty("x"); @@ -627,7 +628,7 @@ QStringList NavigatorTreeModel::visibleProperties(const ModelNode &node) const QString qmlType = qmlTypeInQtContainer(node.metaInfo().propertyTypeName(propertyName)); if (node.model()->metaInfo(qmlType).isValid() && - node.model()->metaInfo(qmlType).isSubclassOf("<cpp>.QGraphicsObject", -1, -1)) { + node.model()->metaInfo(qmlType).isSubclassOf("QtQuick.Item", -1, -1)) { propertyList.append(propertyName); } } @@ -658,10 +659,9 @@ void NavigatorTreeModel::setVisible(const QModelIndex &index, bool visible) itemRow.visibilityItem->setCheckState(visible ? Qt::Checked : Qt::Unchecked); } -void NavigatorTreeModel::openContextMenu(const QPoint &p) +void NavigatorTreeModel::openContextMenu(const QPoint &position) { - if (m_view) - m_view->showContextMenu(p, QPoint(), false); + ModelNodeContextMenu::showContextMenu(m_view.data(), position, QPoint(), false); } } // QmlDesigner diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 7d7715fbc7..1b2fd58bee 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -30,6 +30,7 @@ #include "navigatorview.h" #include "navigatortreemodel.h" #include "navigatorwidget.h" +#include "modelnodecontextmenu.h" #include <coreplugin/editormanager/editormanager.h> diff --git a/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.cpp b/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.cpp index 4f799e4462..06c68d08d5 100644 --- a/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.cpp +++ b/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.cpp @@ -29,7 +29,6 @@ #include "pluginmanager.h" #include "iplugin.h" -#include "pluginpath.h" #include <metainfo.h> #include <QCoreApplication> @@ -55,88 +54,28 @@ enum { debug = 0 }; namespace QmlDesigner { -// Initialize and create instance of a plugin from scratch, -// that is, make sure the library is loaded and has an instance -// of the IPlugin type. Once something fails, mark it as failed -// ignore it from then on. -//static IPlugin *instance(PluginData &p) -//{ -// // Go stale once something fails -// if (p.failed) -// return 0; -// // Pull up the plugin, retrieve IPlugin instance. -// if (!p.instanceGuard) { -// p.instance = 0; -// QPluginLoader loader(p.path); -// if (!(loader.isLoaded() || loader.load())) { -// p.failed = true; -// p.errorMessage = loader.errorString(); -// return 0; -// } -// QObject *object = loader.instance(); -// if (!object) { -// p.failed = true; -// p.errorMessage = QCoreApplication::translate("PluginManager", "Failed to create instance."); -// return 0; -// } -// IPlugin *iplugin = qobject_cast<IPlugin *>(object); -// if (!iplugin) { -// p.failed = true; -// p.errorMessage = QCoreApplication::translate("PluginManager", "Not a QmlDesigner plugin."); -// delete object; -// return 0; -// } -// p.instanceGuard = object; -// p.instance = iplugin; -// } -// // Ensure it is initialized -// if (!p.instance->isInitialized()) { -// if (!p.instance->initialize(&p.errorMessage)) { -// p.failed = true; -// delete p.instance; -// p.instance = 0; -// return 0; -// } -// } -// return p.instance; -//} - - -// ---- PluginManager[Private] -class PluginManagerPrivate { -public: - typedef QList<PluginPath> PluginPathList; - PluginPathList m_paths; -}; - -PluginManager::PluginManager() : - d(new PluginManagerPrivate) -{ -} - -PluginManager::~PluginManager() -{ - delete d; -} - PluginManager::IPluginList PluginManager::instances() { IPluginList rc; - const PluginManagerPrivate::PluginPathList::iterator end = d->m_paths.end(); - for (PluginManagerPrivate::PluginPathList::iterator it = d->m_paths.begin(); it != end; ++it) + const PluginPathList::iterator end = m_paths.end(); + for (PluginPathList::iterator it = m_paths.begin(); it != end; ++it) it->getInstances(&rc); if (debug) qDebug() << '<' << Q_FUNC_INFO << rc.size(); return rc; } +PluginManager::PluginManager() +{ +} + void PluginManager::setPluginPaths(const QStringList &paths) { foreach (const QString &path, paths) { const QDir dir(path); if (!dir.exists()) continue; - d->m_paths.push_back(PluginPath(dir)); + m_paths.push_back(PluginPath(dir)); } // also register path in widgetpluginmanager @@ -146,8 +85,8 @@ void PluginManager::setPluginPaths(const QStringList &paths) QAbstractItemModel *PluginManager::createModel(QObject *parent) { QStandardItemModel *model = new QStandardItemModel(parent); - const PluginManagerPrivate::PluginPathList::iterator end = d->m_paths.end(); - for (PluginManagerPrivate::PluginPathList::iterator it = d->m_paths.begin(); it != end; ++it) + const PluginPathList::iterator end = m_paths.end(); + for (PluginPathList::iterator it = m_paths.begin(); it != end; ++it) model->appendRow(it->createModelItem()); return model; } diff --git a/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.h b/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.h index bbc209cc41..16fcefa82d 100644 --- a/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.h +++ b/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.h @@ -30,6 +30,7 @@ #ifndef PLUGINMANAGER_H #define PLUGINMANAGER_H +#include "pluginpath.h" #include <QObject> #include <QList> @@ -44,8 +45,6 @@ namespace QmlDesigner { class IPlugin; -class PluginManagerPrivate; - // PluginManager: Loads the plugin libraries on demand "as lazy as // possible", that is, directories are scanned and // instances are created only when instances() is called. @@ -53,11 +52,13 @@ class PluginManagerPrivate; class PluginManager { Q_DISABLE_COPY(PluginManager) + + typedef QList<PluginPath> PluginPathList; + public: typedef QList<IPlugin *> IPluginList; PluginManager(); - ~PluginManager(); void setPluginPaths(const QStringList &paths); @@ -65,12 +66,13 @@ public: QDialog *createAboutPluginDialog(QWidget *parent); -private: +private: // functions // Convenience to create a model for an "About Plugins" // dialog. Forces plugin initialization. QAbstractItemModel *createModel(QObject *parent = 0); - PluginManagerPrivate *d; +private: // variables + PluginPathList m_paths; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/pluginmanager/pluginpath.cpp b/src/plugins/qmldesigner/components/pluginmanager/pluginpath.cpp index 90e98a4eb8..d0fc3cf7c1 100644 --- a/src/plugins/qmldesigner/components/pluginmanager/pluginpath.cpp +++ b/src/plugins/qmldesigner/components/pluginmanager/pluginpath.cpp @@ -28,6 +28,8 @@ ****************************************************************************/ #include "pluginpath.h" +#include "pluginmanager.h" + #include <iplugin.h> #include <QLibrary> #include <QWeakPointer> diff --git a/src/plugins/qmldesigner/components/pluginmanager/pluginpath.h b/src/plugins/qmldesigner/components/pluginmanager/pluginpath.h index d2607c14da..dda674ad82 100644 --- a/src/plugins/qmldesigner/components/pluginmanager/pluginpath.h +++ b/src/plugins/qmldesigner/components/pluginmanager/pluginpath.h @@ -30,8 +30,6 @@ #ifndef PLUGINPATH_H #define PLUGINPATH_H -#include "pluginmanager.h" - #include <QObject> #include <QWeakPointer> #include <QList> @@ -71,11 +69,13 @@ struct PluginData { // IPlugins. class PluginPath { + + typedef QList<IPlugin *> IPluginList; public: explicit PluginPath(const QDir &path); - void getInstances(PluginManager::IPluginList *list); + void getInstances(IPluginList *list); QDir path() const { return m_path; } diff --git a/src/plugins/qmldesigner/components/propertyeditor/declarativewidgetview.cpp b/src/plugins/qmldesigner/components/propertyeditor/declarativewidgetview.cpp index 9d919d6e55..20446215a4 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/declarativewidgetview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/declarativewidgetview.cpp @@ -37,94 +37,71 @@ namespace QmlDesigner { -class DeclarativeWidgetViewPrivate +void DeclarativeWidgetView::execute() { -public: - DeclarativeWidgetViewPrivate(DeclarativeWidgetView *view) - : q(view), root(0), component(0) {} - ~DeclarativeWidgetViewPrivate() { delete root; } - void execute(); + if (m_root) + delete m_root.data(); - DeclarativeWidgetView *q; + if (m_component) + delete m_component.data(); - QPointer<QWidget> root; - QUrl source; - QDeclarativeEngine engine; - QDeclarativeComponent *component; -}; - -void DeclarativeWidgetViewPrivate::execute() -{ - if (root) { - delete root; - root = 0; - } - if (component) { - delete component; - component = 0; - } - if (!source.isEmpty()) { - component = new QDeclarativeComponent(&engine, source, q); - if (!component->isLoading()) { - q->continueExecute(); + if (!m_source.isEmpty()) { + m_component = new QDeclarativeComponent(&m_engine, m_source, this); + if (!m_component->isLoading()) { + continueExecute(); } else { - QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), q, SLOT(continueExecute())); + connect(m_component.data(), SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute())); } } } DeclarativeWidgetView::DeclarativeWidgetView(QWidget *parent) : - QWidget(parent), d(new DeclarativeWidgetViewPrivate(this)) -{ -} - -DeclarativeWidgetView::~DeclarativeWidgetView() + QWidget(parent) { - delete d; } QUrl DeclarativeWidgetView::source() const { - return d->source; + return m_source; } void DeclarativeWidgetView::setSource(const QUrl& url) { - d->source = url; - d->execute(); + m_source = url; + execute(); } QDeclarativeEngine* DeclarativeWidgetView::engine() { - return &d->engine; + return &m_engine; } QWidget *DeclarativeWidgetView::rootWidget() const { - return d->root; + return m_root.data(); } QDeclarativeContext* DeclarativeWidgetView::rootContext() { - return d->engine.rootContext(); + return m_engine.rootContext(); } DeclarativeWidgetView::Status DeclarativeWidgetView::status() const { - if (!d->component) + if (!m_component) return DeclarativeWidgetView::Null; - return DeclarativeWidgetView::Status(d->component->status()); + return DeclarativeWidgetView::Status(m_component->status()); } void DeclarativeWidgetView::continueExecute() { - disconnect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute())); + disconnect(m_component.data(), SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute())); - if (d->component->isError()) { - QList<QDeclarativeError> errorList = d->component->errors(); + if (m_component->isError()) { + QList<QDeclarativeError> errorList = m_component->errors(); foreach (const QDeclarativeError &error, errorList) { qWarning() << error; } @@ -132,10 +109,10 @@ void DeclarativeWidgetView::continueExecute() return; } - QObject *obj = d->component->create(); + QObject *obj = m_component->create(); - if(d->component->isError()) { - QList<QDeclarativeError> errorList = d->component->errors(); + if (m_component->isError()) { + QList<QDeclarativeError> errorList = m_component->errors(); foreach (const QDeclarativeError &error, errorList) { qWarning() << error; } @@ -149,7 +126,7 @@ void DeclarativeWidgetView::continueExecute() void DeclarativeWidgetView::setRootWidget(QWidget *widget) { - if (d->root == widget) + if (m_root.data() == widget) return; window()->setAttribute(Qt::WA_OpaquePaintEvent, false); @@ -159,10 +136,10 @@ void DeclarativeWidgetView::setRootWidget(QWidget *widget) widget->setVisible(true); } resize(widget->size()); - d->root = widget; + m_root.reset(widget); - if (d->root) { - QSize initialSize = d->root->size(); + if (m_root) { + QSize initialSize = m_root->size(); if (initialSize != size()) { resize(initialSize); } diff --git a/src/plugins/qmldesigner/components/propertyeditor/declarativewidgetview.h b/src/plugins/qmldesigner/components/propertyeditor/declarativewidgetview.h index c8ac5accb3..adf52b61d7 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/declarativewidgetview.h +++ b/src/plugins/qmldesigner/components/propertyeditor/declarativewidgetview.h @@ -32,17 +32,16 @@ #include <QWidget> #include <QUrl> +#include <QDeclarativeEngine> QT_BEGIN_NAMESPACE -class QDeclarativeEngine; class QDeclarativeContext; class QDeclarativeError; +class QDeclarativeComponent; QT_END_NAMESPACE namespace QmlDesigner { -class DeclarativeWidgetViewPrivate; - class DeclarativeWidgetView : public QWidget { Q_OBJECT @@ -51,8 +50,6 @@ class DeclarativeWidgetView : public QWidget public: explicit DeclarativeWidgetView(QWidget *parent = 0); - virtual ~DeclarativeWidgetView(); - QUrl source() const; void setSource(const QUrl&); @@ -68,14 +65,17 @@ signals: void statusChanged(DeclarativeWidgetView::Status); protected: - virtual void setRootWidget(QWidget *); + void setRootWidget(QWidget *); + void execute(); private Q_SLOTS: void continueExecute(); private: - friend class DeclarativeWidgetViewPrivate; - DeclarativeWidgetViewPrivate *d; + QScopedPointer<QWidget> m_root; + QUrl m_source; + QDeclarativeEngine m_engine; + QWeakPointer<QDeclarativeComponent> m_component; }; diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientlineqmladaptor.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientlineqmladaptor.cpp index 2aa8961369..3abdf648b6 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/gradientlineqmladaptor.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/gradientlineqmladaptor.cpp @@ -137,7 +137,7 @@ void GradientLineQmlAdaptor::writeGradient() gradientNode.setId(oldId); for (int i = 0;i < stops.size(); i++) { - ModelNode gradientStopNode = modelNode.view()->createModelNode("QtQuick.GradientStop", 1, 0); + ModelNode gradientStopNode = modelNode.view()->createModelNode("QtQuick.GradientStop", modelNode.majorQtQuickVersion(), 0); gradientStopNode.variantProperty("position") = roundReal(stops.at(i).first); gradientStopNode.variantProperty("color") = normalizeColor(stops.at(i).second); gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp index cd4cb48d88..3dcb4176a7 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp @@ -55,6 +55,7 @@ #include "propertyeditortransaction.h" #include "originwidget.h" +#include <qmljs/qmljssimplereader.h> #include <utils/fileutils.h> #include <QCoreApplication> @@ -95,6 +96,11 @@ static inline QString sharedDirPath() return QFileInfo(appPath + SHARE_PATH).absoluteFilePath(); } +static inline QString propertyTemplatesPath() +{ + return sharedDirPath() + QLatin1String("/propertyeditor/PropertyTemplates/"); +} + static QObject *variantToQObject(const QVariant &v) { if (v.userType() == QMetaType::QObjectStar || v.userType() > QMetaType::User) @@ -103,6 +109,32 @@ static QObject *variantToQObject(const QVariant &v) return 0; } +static QmlJS::SimpleReaderNode::Ptr s_templateConfiguration; + +QmlJS::SimpleReaderNode::Ptr templateConfiguration() +{ + if (!s_templateConfiguration) { + QmlJS::SimpleReader reader; + const QString fileName = propertyTemplatesPath() + QLatin1String("TemplateTypes.qml"); + s_templateConfiguration = reader.readFile(fileName); + + if (!s_templateConfiguration) { + qWarning() << PropertyEditor::tr("template defitions:") << reader.errors(); + } + } + + return s_templateConfiguration; +} + +QStringList variantToStringList(const QVariant &variant) { + QStringList stringList; + + foreach (const QVariant &singleValue, variant.toList()) + stringList << singleValue.toString(); + + return stringList; +} + PropertyEditor::NodeType::NodeType(PropertyEditor *propertyEditor) : m_view(new DeclarativeWidgetView), m_propertyEditorTransaction(new PropertyEditorTransaction(propertyEditor)), m_dummyPropertyEditorValue(new PropertyEditorValue()), m_contextObject(new PropertyEditorContextObject()) @@ -111,6 +143,7 @@ PropertyEditor::NodeType::NodeType(PropertyEditor *propertyEditor) : QDeclarativeContext *ctxt = m_view->rootContext(); m_view->engine()->setOutputWarningsToStandardError(debug); + m_view->engine()->addImportPath(sharedDirPath() + QLatin1String("/propertyeditor")); m_dummyPropertyEditorValue->setValue("#000000"); ctxt->setContextProperty("dummyBackendValue", m_dummyPropertyEditorValue.data()); m_contextObject->setBackendValues(&m_backendValuesPropertyMap); @@ -333,7 +366,6 @@ static inline QString fixTypeNameForPanes(const QString &typeName) { QString fixedTypeName = typeName; fixedTypeName.replace('.', '/'); - fixedTypeName.replace("QtQuick/", "Qt/"); return fixedTypeName; } @@ -604,6 +636,7 @@ void PropertyEditor::setQmlDir(const QString &qmlDir) { m_qmlDir = qmlDir; + QFileSystemWatcher *watcher = new QFileSystemWatcher(this); watcher->addPath(m_qmlDir); connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(reloadQml())); @@ -624,7 +657,12 @@ void PropertyEditor::timerEvent(QTimerEvent *timerEvent) QString templateGeneration(NodeMetaInfo type, NodeMetaInfo superType, const QmlObjectNode &objectNode) { - QString qmlTemplate = QLatin1String("import QtQuick 1.0\nimport Bauhaus 1.0\n"); + if (!templateConfiguration() && templateConfiguration()->isValid()) + return QString(); + + QStringList imports = variantToStringList(templateConfiguration()->property(QLatin1String("imports"))); + + QString qmlTemplate = imports.join(QLatin1String("\n")) + QLatin1Char('\n'); qmlTemplate += QLatin1String("GroupBox {\n"); qmlTemplate += QString(QLatin1String("caption: \"%1\"\n")).arg(objectNode.modelNode().simplifiedTypeName()); qmlTemplate += QLatin1String("layout: VerticalLayout {\n"); @@ -645,40 +683,23 @@ QString templateGeneration(NodeMetaInfo type, NodeMetaInfo superType, const QmlO QString typeName = type.propertyTypeName(name); //alias resolution only possible with instance - if (typeName == QLatin1String("alias") && objectNode.isValid()) - typeName = objectNode.instanceType(name); + if (typeName == QLatin1String("alias") && objectNode.isValid()) + typeName = objectNode.instanceType(name); if (!superType.hasProperty(name) && type.propertyIsWritable(name)) { - if (typeName == "int") { - qmlTemplate += QString(QLatin1String( - "IntEditor { backendValue: backendValues.%2\n caption: \"%1\"\nbaseStateFlag: isBaseState\nslider: false\n}" - )).arg(name).arg(properName); - emptyTemplate = false; - } - if (typeName == "real" || typeName == "double" || typeName == "qreal") { - qmlTemplate += QString(QLatin1String( - "DoubleSpinBoxAlternate {\ntext: \"%1\"\nbackendValue: backendValues.%2\nbaseStateFlag: isBaseState\n}\n" - )).arg(name).arg(properName); - emptyTemplate = false; - } - if (typeName == "string" || typeName == "QString" || typeName == "QUrl" || typeName == "url") { - qmlTemplate += QString(QLatin1String( - "QWidget {\nlayout: HorizontalLayout {\nLabel {\ntext: \"%1\"\ntoolTip: \"%1\"\n}\nLineEdit {\nbackendValue: backendValues.%2\nbaseStateFlag: isBaseState\n}\n}\n}\n" - )).arg(name).arg(properName); - emptyTemplate = false; - } - if (typeName == "bool") { - qmlTemplate += QString(QLatin1String( - "QWidget {\nlayout: HorizontalLayout {\nLabel {\ntext: \"%1\"\ntoolTip: \"%1\"\n}\nCheckBox {text: backendValues.%2.value\nbackendValue: backendValues.%2\nbaseStateFlag: isBaseState\ncheckable: true\n}\n}\n}\n" - )).arg(name).arg(properName); - emptyTemplate = false; - } - if (typeName == "color" || typeName == "QColor") { - qmlTemplate += QString(QLatin1String( - "ColorGroupBox {\ncaption: \"%1\"\nfinished: finishedNotify\nbackendColor: backendValues.%2\n}\n\n" - )).arg(name).arg(properName); - emptyTemplate = false; - } + foreach (const QmlJS::SimpleReaderNode::Ptr &node, templateConfiguration()->children()) + if (variantToStringList(node->property(QLatin1String("typeNames"))).contains(typeName)) { + const QString fileName = propertyTemplatesPath() + node->property(QLatin1String("sourceFile")).toString(); + QFile file(fileName); + if (file.open(QIODevice::ReadOnly)) { + QString source = file.readAll(); + file.close(); + qmlTemplate += source.arg(name).arg(properName); + emptyTemplate = false; + } else { + qWarning() << PropertyEditor::tr("template defition source file not found:") << fileName; + } + } } } qmlTemplate += QLatin1String("}\n"); //VerticalLayout @@ -994,7 +1015,7 @@ void PropertyEditor::reloadQml() QString PropertyEditor::qmlFileName(const NodeMetaInfo &nodeInfo) const { if (nodeInfo.typeName().split('.').last() == "QDeclarativeItem") - return "Qt/ItemPane.qml"; + return "QtQuick/ItemPane.qml"; const QString fixedTypeName = fixTypeNameForPanes(nodeInfo.typeName()); return fixedTypeName + QLatin1String("Pane.qml"); } @@ -1032,7 +1053,7 @@ QUrl PropertyEditor::qmlForNode(const ModelNode &modelNode, QString &className) } } } - return fileToUrl(QDir(m_qmlDir).filePath("Qt/emptyPane.qml")); + return fileToUrl(QDir(m_qmlDir).filePath("QtQuick/emptyPane.qml")); } QString PropertyEditor::locateQmlFile(const QString &relativePath) const diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h index 46ba015847..1bb01459bd 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h @@ -33,6 +33,7 @@ #include <QObject> #include <QUrl> #include <QDeclarativePropertyMap> +#include <QColor> namespace QmlDesigner { @@ -64,6 +65,8 @@ public: QDeclarativePropertyMap* backendValues() const { return m_backendValues; } + Q_INVOKABLE QString convertColorToString(const QColor &color) { return color.name(); } + signals: void globalBaseUrlChanged(); void specificsUrlChanged(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 62760fb18d..7320f2d2d0 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -29,6 +29,7 @@ #include "propertyeditorvalue.h" #include <QRegExp> +#include <QUrl> #include <abstractview.h> #include <nodeabstractproperty.h> #include <nodeproperty.h> @@ -172,6 +173,11 @@ void PropertyEditorValue::setExpression(const QString &expression) } } +QString PropertyEditorValue::valueToString() const +{ + return value().toString(); +} + bool PropertyEditorValue::isInSubState() const { const QmlDesigner::QmlObjectNode objectNode(modelNode()); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h index e31a03042a..7f2d2149de 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h @@ -79,6 +79,7 @@ class PropertyEditorValue : public QObject Q_OBJECT Q_PROPERTY(QVariant value READ value WRITE setValueWithEmit NOTIFY valueChangedQml) Q_PROPERTY(QString expression READ expression WRITE setExpressionWithEmit NOTIFY expressionChanged FINAL) + Q_PROPERTY(QString valueToString READ valueToString NOTIFY valueChangedQml FINAL) Q_PROPERTY(bool isInModel READ isInModel NOTIFY valueChangedQml FINAL) Q_PROPERTY(bool isInSubState READ isInSubState NOTIFY valueChangedQml FINAL) Q_PROPERTY(bool isBound READ isBound NOTIFY isBoundChanged FINAL) @@ -99,6 +100,8 @@ public: void setExpressionWithEmit(const QString &expression); void setExpression(const QString &expression); + QString valueToString() const; + bool isInSubState() const; bool isInModel() const; diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index 9ef5e8440a..ca5804700e 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -137,8 +137,9 @@ void StatesEditorView::addState() try { if ((rootStateGroup().allStates().count() < 1) && //QtQuick import might be missing - (!model()->hasImport(Import::createLibraryImport("QtQuick", "1.0"), true) && - !model()->hasImport(Import::createLibraryImport("QtQuick", "1.1"), true))) + (!model()->hasImport(Import::createLibraryImport("QtQuick", "1.0"), true) + && !model()->hasImport(Import::createLibraryImport("QtQuick", "1.1"), true) + && !model()->hasImport(Import::createLibraryImport("QtQuick", "2.0"), true))) model()->changeImports(QList<Import>() << Import::createLibraryImport("QtQuick", "1.0"), QList<Import>()); ModelNode newState = rootStateGroup().addState(newStateName); setCurrentState(newState); diff --git a/src/plugins/qmldesigner/customstyleplugin/customstyle.metainfo b/src/plugins/qmldesigner/customstyleplugin/customstyle.metainfo deleted file mode 100644 index c148923cd1..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/customstyle.metainfo +++ /dev/null @@ -1,93 +0,0 @@ -<metainfo> - <node name="Qt.labs.components.custom.Button" icon=":/customstyleplugin/images/button16.png"> - <itemlibraryentry name="Button" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/button.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="30"/> - <property name="text" type="QString" value="Button"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.BasicButton" icon=":/customstyleplugin/images/button16.png"> - <itemlibraryentry name="BasicButton" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/button.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="30"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.BusyIndicator" icon=":/customstyleplugin/images/busyindicator16.png"> - <itemlibraryentry name="BusyIndicator" category="ComponentsCustom Style" libraryIcon=":/customstyleplugin/images/busyindicator.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="180"/> - <property name="height" type="int" value="30"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.CheckBox" icon=":/customstyleplugin/images/checkbox16.png"> - <itemlibraryentry name="CheckBox" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/checkbox.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="30"/> - <property name="height" type="int" value="30"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.ChoiceList" icon=":/customstyleplugin/images/choicelist16.png"> - <itemlibraryentry name="ChoiceList" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/choicelist.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="180"/> - <property name="height" type="int" value="40"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.ProgressBar" icon=":/customstyleplugin/images/progressbar16.png"> - <itemlibraryentry name="ProgressBar" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/progressbar.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="30"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.SpinBox"> - <itemlibraryentry name="SpinBox" category="Components Custom Style" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="30"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.RadioButton" icon=":/customstyleplugin/images/radiobutton16.png"> - <itemlibraryentry name="RadioButton" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/radiobutton.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="30"/> - <property name="height" type="int" value="30"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.TextArea" icon=":/customstyleplugin/images/textarea16.png"> - <itemlibraryentry name="TextArea" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/textarea.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="180"/> - <property name="height" type="int" value="180"/> - <property name="text" type="QString" value="TextArea"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.ButtonRow" icon=":/customstyleplugin/images/buttonrow16.png"> - <itemlibraryentry name="ButtonRow" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/buttonrow.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="120"/> - <property name="height" type="int" value="20"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.ButtonColumn" icon=":/customstyleplugin/images/buttoncolumn16.png"> - <itemlibraryentry name="ButtonColumn" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/buttoncolumn.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="120"/> - <property name="height" type="int" value="20"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.Slider" icon=":/customstyleplugin/images/slider16.png"> - <itemlibraryentry name="Slider (horizontal)" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/slider.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="180"/> - <property name="height" type="int" value="30"/> - <property name="orientation" type="int" value="1"/> - </itemlibraryentry> - <itemlibraryentry name="Slider (vertical)" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/sliderh.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="30"/> - <property name="height" type="int" value="180"/> - <property name="orientation" type="int" value="2"/> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.Switch" icon=":/customstyleplugin/images/switchbutton16.png"> - <itemlibraryentry name="Switch" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/switchbutton.png" version="1.0" requiredImport="Qt.labs.components.custom"> - </itemlibraryentry> - </node> - <node name="Qt.labs.components.custom.TextField" icon=":/customstyleplugin/images/textfield16.png"> - <itemlibraryentry name="TextField" category="Components Custom Style" libraryIcon=":/customstyleplugin/images/textfield.png" version="1.0" requiredImport="Qt.labs.components.custom"> - <property name="width" type="int" value="180"/> - <property name="height" type="int" value="50"/> - <property name="text" type="QString" value="TextField"/> - </itemlibraryentry> - </node> -</metainfo> diff --git a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.json b/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.json deleted file mode 100644 index d3a62366ae..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - - -"Vendor" : "Digia Plc", - - - - -"Category" : "Qt Quick", - - -"Description" : "Plugin for Custom Style Items.", - - -"Url" : "http://www.qt-project.org" - - - -} diff --git a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.pri b/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.pri deleted file mode 100644 index 3e30ea983e..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.pri +++ /dev/null @@ -1,13 +0,0 @@ -TARGET = customstyleplugin -TEMPLATE = lib -CONFIG += plugin - -include (../designercore/iwidgetplugin.pri) - -SOURCES += $$PWD/customstyleplugin.cpp - -HEADERS += $$PWD/customstyleplugin.h $$PWD/../designercore/include/iwidgetplugin.h - -RESOURCES += $$PWD/customstyleplugin.qrc - -OTHER_FILES += $$PWD/customstyle.metainfo diff --git a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.pro b/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.pro deleted file mode 100644 index 4db17c2462..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.pro +++ /dev/null @@ -1,4 +0,0 @@ -include(../../../../qtcreator.pri) -include(../../../private_headers.pri) -include(customstyleplugin.pri) -include(../plugindestdir.pri) diff --git a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.qrc b/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.qrc deleted file mode 100644 index f0ac6f5ba7..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/customstyleplugin.qrc +++ /dev/null @@ -1,41 +0,0 @@ -<RCC> - <qresource prefix="/customstyleplugin"> - <file>customstyle.metainfo</file> - <file>images/item-icon16.png</file> - <file>images/item-icon.png</file> - <file>images/button.png</file> - <file>images/button16.png</file> - <file>images/checkbox16.png</file> - <file>images/checkbox.png</file> - <file>images/choicelist16.png</file> - <file>images/choicelist.png</file> - <file>images/progressbar.png</file> - <file>images/progressbar16.png</file> - <file>images/radiobutton.png</file> - <file>images/radiobutton16.png</file> - <file>images/slider.png</file> - <file>images/slider16.png</file> - <file>images/textarea16.png</file> - <file>images/textarea.png</file> - <file>images/textfield16.png</file> - <file>images/textfield.png</file> - <file>images/window16.png</file> - <file>images/window.png</file> - <file>images/tabbutton16.png</file> - <file>images/tabbutton.png</file> - <file>images/busyindicator16.png</file> - <file>images/busyindicator.png</file> - <file>images/sliderh16.png</file> - <file>images/sliderh.png</file> - <file>images/switchbutton16.png</file> - <file>images/switchbutton.png</file> - <file>images/buttonrow.png</file> - <file>images/buttonrow16.png</file> - <file>images/tabbar.png</file> - <file>images/tabbar16.png</file> - <file>images/toolbar.png</file> - <file>images/toolbar16.png</file> - <file>images/buttoncolumn.png</file> - <file>images/buttoncolumn16.png</file> - </qresource> -</RCC> diff --git a/src/plugins/qmldesigner/customstyleplugin/images/busyindicator.png b/src/plugins/qmldesigner/customstyleplugin/images/busyindicator.png Binary files differdeleted file mode 100644 index 89d0283f26..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/busyindicator.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/busyindicator16.png b/src/plugins/qmldesigner/customstyleplugin/images/busyindicator16.png Binary files differdeleted file mode 100644 index 7e3b2d3158..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/busyindicator16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/busyindicatora.png b/src/plugins/qmldesigner/customstyleplugin/images/busyindicatora.png Binary files differdeleted file mode 100644 index 433f4d426b..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/busyindicatora.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/busyindicatora16.png b/src/plugins/qmldesigner/customstyleplugin/images/busyindicatora16.png Binary files differdeleted file mode 100644 index 82de5b0a1b..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/busyindicatora16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/button.png b/src/plugins/qmldesigner/customstyleplugin/images/button.png Binary files differdeleted file mode 100644 index 828af210ac..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/button.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/button16.png b/src/plugins/qmldesigner/customstyleplugin/images/button16.png Binary files differdeleted file mode 100644 index 8d95760b27..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/button16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/buttoncolumn.png b/src/plugins/qmldesigner/customstyleplugin/images/buttoncolumn.png Binary files differdeleted file mode 100644 index 46db8f6ab5..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/buttoncolumn.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/buttoncolumn16.png b/src/plugins/qmldesigner/customstyleplugin/images/buttoncolumn16.png Binary files differdeleted file mode 100644 index 883258048f..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/buttoncolumn16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/buttonrow.png b/src/plugins/qmldesigner/customstyleplugin/images/buttonrow.png Binary files differdeleted file mode 100644 index 9727749de9..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/buttonrow.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/buttonrow16.png b/src/plugins/qmldesigner/customstyleplugin/images/buttonrow16.png Binary files differdeleted file mode 100644 index 420de41860..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/buttonrow16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/checkbox.png b/src/plugins/qmldesigner/customstyleplugin/images/checkbox.png Binary files differdeleted file mode 100644 index 0f4a826f4d..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/checkbox.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/checkbox16.png b/src/plugins/qmldesigner/customstyleplugin/images/checkbox16.png Binary files differdeleted file mode 100644 index 01f09e3515..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/checkbox16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/choicelist.png b/src/plugins/qmldesigner/customstyleplugin/images/choicelist.png Binary files differdeleted file mode 100644 index 3fd9876ada..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/choicelist.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/choicelist16.png b/src/plugins/qmldesigner/customstyleplugin/images/choicelist16.png Binary files differdeleted file mode 100644 index 602b28229e..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/choicelist16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/item-icon.png b/src/plugins/qmldesigner/customstyleplugin/images/item-icon.png Binary files differdeleted file mode 100644 index fc53d38ae7..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/item-icon.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/item-icon16.png b/src/plugins/qmldesigner/customstyleplugin/images/item-icon16.png Binary files differdeleted file mode 100644 index 7d2d7a5050..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/item-icon16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/progressbar.png b/src/plugins/qmldesigner/customstyleplugin/images/progressbar.png Binary files differdeleted file mode 100644 index 040f5bac03..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/progressbar.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/progressbar16.png b/src/plugins/qmldesigner/customstyleplugin/images/progressbar16.png Binary files differdeleted file mode 100644 index e2432475d5..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/progressbar16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/radiobutton.png b/src/plugins/qmldesigner/customstyleplugin/images/radiobutton.png Binary files differdeleted file mode 100644 index 143b6a99f4..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/radiobutton.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/radiobutton16.png b/src/plugins/qmldesigner/customstyleplugin/images/radiobutton16.png Binary files differdeleted file mode 100644 index 94912c2034..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/radiobutton16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/slider.png b/src/plugins/qmldesigner/customstyleplugin/images/slider.png Binary files differdeleted file mode 100644 index 746ed51932..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/slider.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/slider16.png b/src/plugins/qmldesigner/customstyleplugin/images/slider16.png Binary files differdeleted file mode 100644 index 10c4928b3c..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/slider16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/sliderh.png b/src/plugins/qmldesigner/customstyleplugin/images/sliderh.png Binary files differdeleted file mode 100644 index 87cd55678f..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/sliderh.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/sliderh16.png b/src/plugins/qmldesigner/customstyleplugin/images/sliderh16.png Binary files differdeleted file mode 100644 index c419911336..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/sliderh16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/switchbutton.png b/src/plugins/qmldesigner/customstyleplugin/images/switchbutton.png Binary files differdeleted file mode 100644 index 48bf247cb8..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/switchbutton.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/switchbutton16.png b/src/plugins/qmldesigner/customstyleplugin/images/switchbutton16.png Binary files differdeleted file mode 100644 index 238a1be632..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/switchbutton16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/tabbar.png b/src/plugins/qmldesigner/customstyleplugin/images/tabbar.png Binary files differdeleted file mode 100644 index 2f44e62b3f..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/tabbar.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/tabbar16.png b/src/plugins/qmldesigner/customstyleplugin/images/tabbar16.png Binary files differdeleted file mode 100644 index 57c7906982..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/tabbar16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/tabbutton.png b/src/plugins/qmldesigner/customstyleplugin/images/tabbutton.png Binary files differdeleted file mode 100644 index d9f5fdb3f9..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/tabbutton.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/tabbutton16.png b/src/plugins/qmldesigner/customstyleplugin/images/tabbutton16.png Binary files differdeleted file mode 100644 index 8e279cff65..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/tabbutton16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/textarea.png b/src/plugins/qmldesigner/customstyleplugin/images/textarea.png Binary files differdeleted file mode 100644 index 86f2969d00..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/textarea.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/textarea16.png b/src/plugins/qmldesigner/customstyleplugin/images/textarea16.png Binary files differdeleted file mode 100644 index 899a4bca2e..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/textarea16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/textfield.png b/src/plugins/qmldesigner/customstyleplugin/images/textfield.png Binary files differdeleted file mode 100644 index b0f13da50d..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/textfield.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/textfield16.png b/src/plugins/qmldesigner/customstyleplugin/images/textfield16.png Binary files differdeleted file mode 100644 index 7feb8c7158..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/textfield16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/toolbar.png b/src/plugins/qmldesigner/customstyleplugin/images/toolbar.png Binary files differdeleted file mode 100644 index e67c042422..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/toolbar.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/toolbar16.png b/src/plugins/qmldesigner/customstyleplugin/images/toolbar16.png Binary files differdeleted file mode 100644 index f4a0c5ef69..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/toolbar16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/window.png b/src/plugins/qmldesigner/customstyleplugin/images/window.png Binary files differdeleted file mode 100644 index fc53d38ae7..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/window.png +++ /dev/null diff --git a/src/plugins/qmldesigner/customstyleplugin/images/window16.png b/src/plugins/qmldesigner/customstyleplugin/images/window16.png Binary files differdeleted file mode 100644 index 7d2d7a5050..0000000000 --- a/src/plugins/qmldesigner/customstyleplugin/images/window16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/designercore/designercore.pri b/src/plugins/qmldesigner/designercore/designercore-lib.pri index 4cd9644a99..1bd4814696 100644 --- a/src/plugins/qmldesigner/designercore/designercore.pri +++ b/src/plugins/qmldesigner/designercore/designercore-lib.pri @@ -5,6 +5,7 @@ QT += script \ network DEFINES += TEST_EXPORTS +DEFINES += DESIGNER_CORE_LIBRARY INCLUDEPATH += $$PWD \ $$PWD/include @@ -16,7 +17,7 @@ include (../../../../share/qtcreator/qml/qmlpuppet/container/container.pri) SOURCES += $$PWD/model/abstractview.cpp \ $$PWD/model/rewriterview.cpp \ $$PWD/metainfo/metainfo.cpp \ - $$PWD/metainfo/metainfoparser.cpp \ + $$PWD/metainfo/metainforeader.cpp \ $$PWD/metainfo/nodemetainfo.cpp \ $$PWD/metainfo/itemlibraryinfo.cpp \ $$PWD/metainfo/subcomponentmanager.cpp \ @@ -74,15 +75,14 @@ SOURCES += $$PWD/model/abstractview.cpp \ $$PWD/model/rewriteactioncompressor.cpp \ $$PWD/model/qmltextgenerator.cpp \ $$PWD/model/modelmerger.cpp \ - $$PWD/exceptions/rewritingexception.cpp \ - $$PWD/model/modelnodecontextmenu.cpp + $$PWD/exceptions/rewritingexception.cpp -HEADERS += $$PWD/include/corelib_global.h \ +HEADERS += $$PWD/include/qmldesignercorelib_global.h \ $$PWD/include/abstractview.h \ $$PWD/include/nodeinstanceview.h \ $$PWD/include/rewriterview.h \ $$PWD/include/metainfo.h \ - $$PWD/include/metainfoparser.h \ + $$PWD/include/metainforeader.h \ $$PWD/include/nodemetainfo.h \ $$PWD/include/itemlibraryinfo.h \ $$PWD/model/internalproperty.h \ @@ -144,8 +144,7 @@ HEADERS += $$PWD/include/corelib_global.h \ $$PWD/include/modelmerger.h \ $$PWD/include/mathutils.h \ $$PWD/include/customnotifications.h \ - $$PWD/include/rewritingexception.h \ - $$PWD//model/modelnodecontextmenu.h + $$PWD/include/rewritingexception.h contains(CONFIG, plugin) { # If core.pri has been included in the qmldesigner plugin diff --git a/src/plugins/qmldesigner/designercore/filemanager/filemanager.pri b/src/plugins/qmldesigner/designercore/filemanager/filemanager.pri index a2a6933c03..ac11d4c4c6 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/filemanager.pri +++ b/src/plugins/qmldesigner/designercore/filemanager/filemanager.pri @@ -13,7 +13,8 @@ SOURCES += \ $$PWD/objectlengthcalculator.cpp \ $$PWD/firstdefinitionfinder.cpp \ $$PWD/moveobjectbeforeobjectvisitor.cpp \ - $$PWD/changeimportsvisitor.cpp + $$PWD/changeimportsvisitor.cpp \ + $$PWD/qmlwarningdialog.cpp HEADERS += \ $$PWD/qmlrewriter.h \ $$PWD/qmlrefactoring.h \ @@ -29,4 +30,8 @@ HEADERS += \ $$PWD/objectlengthcalculator.h \ $$PWD/firstdefinitionfinder.h \ $$PWD/moveobjectbeforeobjectvisitor.h \ - $$PWD/changeimportsvisitor.h + $$PWD/changeimportsvisitor.h \ + $$PWD/qmlwarningdialog.h + +FORMS += \ + $$PWD/qmlwarningdialog.ui diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.cpp b/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.cpp new file mode 100644 index 0000000000..199bb453ec --- /dev/null +++ b/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.cpp @@ -0,0 +1,69 @@ +#include "qmlwarningdialog.h" +#include "ui_qmlwarningdialog.h" + +#include <qmldesignerplugin.h> + +namespace QmlDesigner { + +namespace Internal { + +QmlWarningDialog::QmlWarningDialog(QWidget *parent, const QStringList &warnings) : + QDialog(parent), + ui(new Ui::QmlWarningDialog), + m_warnings(warnings) +{ + ui->setupUi(this); + setResult (0); + + ui->checkBox->setChecked(true); + connect(ui->ignoreButton, SIGNAL(clicked()), this, SLOT(ignoreButtonPressed())); + connect(ui->okButton, SIGNAL(clicked()), this, SLOT(okButtonPressed())); + connect(ui->checkBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxToggled(bool))); + + connect(ui->warnings, SIGNAL(linkActivated(QString)), this, SLOT(linkClicked(QString))); + + QString warningText; + foreach (const QString &string, warnings) + warningText += QLatin1String(" ") + string + QLatin1String("\n"); + ui->warnings->setText(warningText); + + ui->warnings->setForegroundRole(QPalette::ToolTipText); + ui->warnings->setBackgroundRole(QPalette::ToolTipBase); + ui->warnings->setAutoFillBackground(true); +} + +QmlWarningDialog::~QmlWarningDialog() +{ + delete ui; +} + +void QmlWarningDialog::ignoreButtonPressed() +{ + done(0); +} + +void QmlWarningDialog::okButtonPressed() +{ + done(-1); +} + +bool QmlWarningDialog::warningsEnabled() const +{ + DesignerSettings settings = BauhausPlugin::pluginInstance()->settings(); + return settings.warningsInDesigner; +} + +void QmlWarningDialog::checkBoxToggled(bool b) +{ + DesignerSettings settings = BauhausPlugin::pluginInstance()->settings(); + settings.warningsInDesigner = b; + BauhausPlugin::pluginInstance()->setSettings(settings); +} + +void QmlWarningDialog::linkClicked(const QString &link) +{ + done(link.toInt()); +} + +} //Internal +} //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.h b/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.h new file mode 100644 index 0000000000..61cbaa2c7b --- /dev/null +++ b/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.h @@ -0,0 +1,41 @@ +#ifndef QMLWARNINGDIALOG_H +#define QMLWARNINGDIALOG_H + +#include <QDialog> + +QT_BEGIN_NAMESPACE +namespace Ui { + class QmlWarningDialog; +} +QT_END_NAMESPACE + +namespace QmlDesigner { + +namespace Internal { + +class QmlWarningDialog : public QDialog +{ + Q_OBJECT + +public: + explicit QmlWarningDialog(QWidget *parent, const QStringList &warnings); + ~QmlWarningDialog(); + + bool warningsEnabled() const; + +public slots: + void ignoreButtonPressed(); + void okButtonPressed(); + void checkBoxToggled(bool); + void linkClicked(const QString &link); + +private: + Ui::QmlWarningDialog *ui; + const QStringList m_warnings; +}; + +} //Internal + +} //QmlDesigner + +#endif // QMLWARNINGDIALOG_H diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.ui b/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.ui new file mode 100644 index 0000000000..026881e434 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/filemanager/qmlwarningdialog.ui @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QmlWarningDialog</class> + <widget class="QDialog" name="QmlWarningDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>458</width> + <height>229</height> + </rect> + </property> + <property name="windowTitle"> + <string>Warning</string> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>12</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="minimumSize"> + <size> + <width>440</width> + <height>0</height> + </size> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>This QML file contains features which are not supported by Qt Quick Designer</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="warnings"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>120</height> + </size> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <property name="text"> + <string/> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="margin"> + <number>6</number> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBox"> + <property name="text"> + <string>Warn about QML features which are not properly supported by the Qt Quick Designer</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>88</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="ignoreButton"> + <property name="toolTip"> + <string>Ignore this warning and open the file</string> + </property> + <property name="text"> + <string>Ignore</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>Ok</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/qmldesigner/designercore/include/abstractproperty.h b/src/plugins/qmldesigner/designercore/include/abstractproperty.h index 925ea92736..8c38613564 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractproperty.h +++ b/src/plugins/qmldesigner/designercore/include/abstractproperty.h @@ -33,7 +33,7 @@ #include <QVariant> #include <QWeakPointer> #include <QSharedPointer> -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" QT_BEGIN_NAMESPACE class QTextStream; @@ -52,11 +52,11 @@ namespace QmlDesigner { class Model; class ModelNode; class AbstractView; -class CORESHARED_EXPORT VariantProperty; -class CORESHARED_EXPORT NodeListProperty; -class CORESHARED_EXPORT NodeAbstractProperty; -class CORESHARED_EXPORT BindingProperty; -class CORESHARED_EXPORT NodeProperty; +class QMLDESIGNERCORE_EXPORT VariantProperty; +class QMLDESIGNERCORE_EXPORT NodeListProperty; +class QMLDESIGNERCORE_EXPORT NodeAbstractProperty; +class QMLDESIGNERCORE_EXPORT BindingProperty; +class QMLDESIGNERCORE_EXPORT NodeProperty; class QmlObjectNode; @@ -65,14 +65,14 @@ namespace Internal { class ModelPrivate; } -class CORESHARED_EXPORT AbstractProperty +class QMLDESIGNERCORE_EXPORT AbstractProperty { friend class QmlDesigner::ModelNode; friend class QmlDesigner::Internal::ModelPrivate; - friend CORESHARED_EXPORT bool operator ==(const AbstractProperty &property1, const AbstractProperty &property2); - friend CORESHARED_EXPORT bool operator !=(const AbstractProperty &property1, const AbstractProperty &property2); - friend CORESHARED_EXPORT uint qHash(const AbstractProperty& property); + friend QMLDESIGNERCORE_EXPORT bool operator ==(const AbstractProperty &property1, const AbstractProperty &property2); + friend QMLDESIGNERCORE_EXPORT bool operator !=(const AbstractProperty &property1, const AbstractProperty &property2); + friend QMLDESIGNERCORE_EXPORT uint qHash(const AbstractProperty& property); public: AbstractProperty(); @@ -117,11 +117,11 @@ private: QWeakPointer<AbstractView> m_view; }; -CORESHARED_EXPORT bool operator ==(const AbstractProperty &property1, const AbstractProperty &property2); -CORESHARED_EXPORT bool operator !=(const AbstractProperty &property1, const AbstractProperty &property2); -CORESHARED_EXPORT uint qHash(const AbstractProperty& property); -CORESHARED_EXPORT QTextStream& operator<<(QTextStream &stream, const AbstractProperty &property); -CORESHARED_EXPORT QDebug operator<<(QDebug debug, const AbstractProperty &AbstractProperty); +QMLDESIGNERCORE_EXPORT bool operator ==(const AbstractProperty &property1, const AbstractProperty &property2); +QMLDESIGNERCORE_EXPORT bool operator !=(const AbstractProperty &property1, const AbstractProperty &property2); +QMLDESIGNERCORE_EXPORT uint qHash(const AbstractProperty& property); +QMLDESIGNERCORE_EXPORT QTextStream& operator<<(QTextStream &stream, const AbstractProperty &property); +QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const AbstractProperty &AbstractProperty); } #endif //ABSTRACTPROPERTY_H diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 5acd62499f..5b45b1a1b2 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -30,7 +30,7 @@ #ifndef ABSTRACTVIEW_H #define ABSTRACTVIEW_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include <model.h> #include <modelnode.h> @@ -58,7 +58,7 @@ class QmlModelView; class NodeInstanceView; class RewriterView; -class CORESHARED_EXPORT AbstractView : public QObject +class QMLDESIGNERCORE_EXPORT AbstractView : public QObject { Q_OBJECT public: @@ -191,8 +191,8 @@ private: QWeakPointer<Model> m_model; }; -CORESHARED_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList); -CORESHARED_EXPORT QList<ModelNode> toModelNodeList(const QList<Internal::InternalNodePointer> &nodeList, AbstractView *view); +QMLDESIGNERCORE_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList); +QMLDESIGNERCORE_EXPORT QList<ModelNode> toModelNodeList(const QList<Internal::InternalNodePointer> &nodeList, AbstractView *view); } diff --git a/src/plugins/qmldesigner/designercore/include/basetexteditmodifier.h b/src/plugins/qmldesigner/designercore/include/basetexteditmodifier.h index 6595183356..01866b32d3 100644 --- a/src/plugins/qmldesigner/designercore/include/basetexteditmodifier.h +++ b/src/plugins/qmldesigner/designercore/include/basetexteditmodifier.h @@ -31,7 +31,7 @@ #ifndef BASETEXTEDITMODIFIER_H #define BASETEXTEDITMODIFIER_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "plaintexteditmodifier.h" #include <texteditor/basetexteditor.h> @@ -44,7 +44,7 @@ class Snapshot; namespace QmlDesigner { -class CORESHARED_EXPORT BaseTextEditModifier: public PlainTextEditModifier +class QMLDESIGNERCORE_EXPORT BaseTextEditModifier: public PlainTextEditModifier { public: BaseTextEditModifier(TextEditor::BaseTextEditorWidget *textEdit); diff --git a/src/plugins/qmldesigner/designercore/include/bindingproperty.h b/src/plugins/qmldesigner/designercore/include/bindingproperty.h index be6ea0b3fa..43f2e64890 100644 --- a/src/plugins/qmldesigner/designercore/include/bindingproperty.h +++ b/src/plugins/qmldesigner/designercore/include/bindingproperty.h @@ -30,12 +30,12 @@ #ifndef BINDINGPROPERTY_H #define BINDINGPROPERTY_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "abstractproperty.h" namespace QmlDesigner { -class CORESHARED_EXPORT BindingProperty : public QmlDesigner::AbstractProperty +class QMLDESIGNERCORE_EXPORT BindingProperty : public QmlDesigner::AbstractProperty { friend class QmlDesigner::ModelNode; friend class QmlDesigner::Internal::ModelPrivate; diff --git a/src/plugins/qmldesigner/designercore/include/exception.h b/src/plugins/qmldesigner/designercore/include/exception.h index d2efe6a856..87f8d75d57 100644 --- a/src/plugins/qmldesigner/designercore/include/exception.h +++ b/src/plugins/qmldesigner/designercore/include/exception.h @@ -30,14 +30,14 @@ #ifndef EXCEPTION_H #define EXCEPTION_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include <QString> #include <QDebug> namespace QmlDesigner { -class CORESHARED_EXPORT Exception +class QMLDESIGNERCORE_EXPORT Exception { public: Exception(int line, @@ -64,7 +64,7 @@ private: static bool s_shouldAssert; }; -CORESHARED_EXPORT QDebug operator<<(QDebug debug, const Exception &exception); +QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const Exception &exception); } diff --git a/src/plugins/qmldesigner/designercore/include/import.h b/src/plugins/qmldesigner/designercore/include/import.h index 6e5b167ba9..5c2807aa2b 100644 --- a/src/plugins/qmldesigner/designercore/include/import.h +++ b/src/plugins/qmldesigner/designercore/include/import.h @@ -33,11 +33,11 @@ #include <QString> #include <QStringList> -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" namespace QmlDesigner { -class CORESHARED_EXPORT Import +class QMLDESIGNERCORE_EXPORT Import { public: static Import createLibraryImport(const QString &url, const QString &version = QString(), const QString &alias = QString(), const QStringList &importPaths = QStringList()); @@ -71,7 +71,7 @@ private: QStringList m_importPathList; }; -CORESHARED_EXPORT uint qHash(const Import &import); +QMLDESIGNERCORE_EXPORT uint qHash(const Import &import); } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/invalidargumentexception.h b/src/plugins/qmldesigner/designercore/include/invalidargumentexception.h index a6ddb3437b..fc28d15a3c 100644 --- a/src/plugins/qmldesigner/designercore/include/invalidargumentexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalidargumentexception.h @@ -35,7 +35,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidArgumentException : public Exception +class QMLDESIGNERCORE_EXPORT InvalidArgumentException : public Exception { public: InvalidArgumentException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/invalididexception.h b/src/plugins/qmldesigner/designercore/include/invalididexception.h index d3b2dce3ab..8e5be36130 100644 --- a/src/plugins/qmldesigner/designercore/include/invalididexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalididexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidIdException : public InvalidArgumentException +class QMLDESIGNERCORE_EXPORT InvalidIdException : public InvalidArgumentException { public: enum Reason { InvalidCharacters, DuplicateId }; diff --git a/src/plugins/qmldesigner/designercore/include/invalidmetainfoexception.h b/src/plugins/qmldesigner/designercore/include/invalidmetainfoexception.h index 7737f724fb..1d3e646c01 100644 --- a/src/plugins/qmldesigner/designercore/include/invalidmetainfoexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalidmetainfoexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidMetaInfoException : public Exception +class QMLDESIGNERCORE_EXPORT InvalidMetaInfoException : public Exception { public: InvalidMetaInfoException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/invalidmodelnodeexception.h b/src/plugins/qmldesigner/designercore/include/invalidmodelnodeexception.h index e20b32219e..34c856e7ea 100644 --- a/src/plugins/qmldesigner/designercore/include/invalidmodelnodeexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalidmodelnodeexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidModelNodeException : public Exception +class QMLDESIGNERCORE_EXPORT InvalidModelNodeException : public Exception { public: InvalidModelNodeException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/invalidmodelstateexception.h b/src/plugins/qmldesigner/designercore/include/invalidmodelstateexception.h index 07977d49c9..c19c1b4eea 100644 --- a/src/plugins/qmldesigner/designercore/include/invalidmodelstateexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalidmodelstateexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidModelStateException : public Exception +class QMLDESIGNERCORE_EXPORT InvalidModelStateException : public Exception { public: InvalidModelStateException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/invalidpropertyexception.h b/src/plugins/qmldesigner/designercore/include/invalidpropertyexception.h index ecafa191e2..e04febdfb0 100644 --- a/src/plugins/qmldesigner/designercore/include/invalidpropertyexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalidpropertyexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidPropertyException : public Exception +class QMLDESIGNERCORE_EXPORT InvalidPropertyException : public Exception { public: InvalidPropertyException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/invalidqmlsourceexception.h b/src/plugins/qmldesigner/designercore/include/invalidqmlsourceexception.h index 1eb2f665f6..e1ed1b3ac0 100644 --- a/src/plugins/qmldesigner/designercore/include/invalidqmlsourceexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalidqmlsourceexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidQmlSourceException : public QmlDesigner::Exception +class QMLDESIGNERCORE_EXPORT InvalidQmlSourceException : public QmlDesigner::Exception { public: InvalidQmlSourceException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/invalidreparentingexception.h b/src/plugins/qmldesigner/designercore/include/invalidreparentingexception.h index 867d1b3a35..b01ac78528 100644 --- a/src/plugins/qmldesigner/designercore/include/invalidreparentingexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalidreparentingexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidReparentingException : public Exception +class QMLDESIGNERCORE_EXPORT InvalidReparentingException : public Exception { public: InvalidReparentingException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/invalidslideindexexception.h b/src/plugins/qmldesigner/designercore/include/invalidslideindexexception.h index 76168009c9..42a1ead7bc 100644 --- a/src/plugins/qmldesigner/designercore/include/invalidslideindexexception.h +++ b/src/plugins/qmldesigner/designercore/include/invalidslideindexexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT InvalidSlideIndexException : public Exception +class QMLDESIGNERCORE_EXPORT InvalidSlideIndexException : public Exception { public: InvalidSlideIndexException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h b/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h index e0ae84eac1..11059b4bab 100644 --- a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h +++ b/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h @@ -30,7 +30,7 @@ #ifndef ITEMLIBRARYINFO_H #define ITEMLIBRARYINFO_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "propertycontainer.h" #include <QSharedPointer> @@ -40,21 +40,22 @@ namespace QmlDesigner { namespace Internal { class ItemLibraryEntryData; -class ItemLibraryInfoPrivate; class MetaInfoPrivate; } class ItemLibraryEntry; -CORESHARED_EXPORT QDataStream& operator<<(QDataStream& stream, const ItemLibraryEntry &itemLibraryEntry); -CORESHARED_EXPORT QDataStream& operator>>(QDataStream& stream, ItemLibraryEntry &itemLibraryEntry); +QMLDESIGNERCORE_EXPORT QDataStream& operator<<(QDataStream& stream, const ItemLibraryEntry &itemLibraryEntry); +QMLDESIGNERCORE_EXPORT QDataStream& operator>>(QDataStream& stream, ItemLibraryEntry &itemLibraryEntry); +QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const ItemLibraryEntry &itemLibraryEntry); -class CORESHARED_EXPORT ItemLibraryEntry +class QMLDESIGNERCORE_EXPORT ItemLibraryEntry { //friend class QmlDesigner::MetaInfo; //friend class QmlDesigner::Internal::MetaInfoParser; - friend CORESHARED_EXPORT QDataStream& operator<<(QDataStream& stream, const ItemLibraryEntry &itemLibraryEntry); - friend CORESHARED_EXPORT QDataStream& operator>>(QDataStream& stream, ItemLibraryEntry &itemLibraryEntry); + friend QMLDESIGNERCORE_EXPORT QDataStream& operator<<(QDataStream& stream, const ItemLibraryEntry &itemLibraryEntry); + friend QMLDESIGNERCORE_EXPORT QDataStream& operator>>(QDataStream& stream, ItemLibraryEntry &itemLibraryEntry); + friend QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const ItemLibraryEntry &itemLibraryEntry); public: ItemLibraryEntry(); @@ -83,7 +84,7 @@ public: void setName(const QString &name); void setIconPath(const QString &iconPath); void addProperty(const Property &p); - void addProperty(QString &name, QString &type, QString &value); + void addProperty(QString &name, QString &type, QVariant &value); void setDragIcon(const QIcon &icon); void setIcon(const QIcon &icon); void setCategory(const QString &category); @@ -94,13 +95,12 @@ private: QExplicitlySharedDataPointer<Internal::ItemLibraryEntryData> m_data; }; -class CORESHARED_EXPORT ItemLibraryInfo : public QObject +class QMLDESIGNERCORE_EXPORT ItemLibraryInfo : public QObject { Q_OBJECT friend class Internal::MetaInfoPrivate; public: - ~ItemLibraryInfo(); QList<ItemLibraryEntry> entries() const; QList<ItemLibraryEntry> entriesForType(const QString &typeName, int majorVersion, int minorVersion) const; @@ -113,10 +113,13 @@ public: signals: void entriesChanged(); -private: +private: // functions ItemLibraryInfo(QObject *parent = 0); - void setBaseInfo(ItemLibraryInfo *baseInfo); - Internal::ItemLibraryInfoPrivate *d; + void setBaseInfo(ItemLibraryInfo *m_baseInfo); + +private: // variables + QHash<QString, ItemLibraryEntry> m_nameToEntryHash; + QWeakPointer<ItemLibraryInfo> m_baseInfo; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/metainfo.h b/src/plugins/qmldesigner/designercore/include/metainfo.h index e1f97a547a..ec7cb61acf 100644 --- a/src/plugins/qmldesigner/designercore/include/metainfo.h +++ b/src/plugins/qmldesigner/designercore/include/metainfo.h @@ -30,7 +30,7 @@ #ifndef METAINFO_H #define METAINFO_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include <QMultiHash> #include <QString> @@ -53,15 +53,15 @@ namespace Internal { typedef QSharedPointer<MetaInfoPrivate> MetaInfoPrivatePointer; } -CORESHARED_EXPORT bool operator==(const MetaInfo &first, const MetaInfo &second); -CORESHARED_EXPORT bool operator!=(const MetaInfo &first, const MetaInfo &second); +QMLDESIGNERCORE_EXPORT bool operator==(const MetaInfo &first, const MetaInfo &second); +QMLDESIGNERCORE_EXPORT bool operator!=(const MetaInfo &first, const MetaInfo &second); -class CORESHARED_EXPORT MetaInfo +class QMLDESIGNERCORE_EXPORT MetaInfo { friend class QmlDesigner::Internal::MetaInfoPrivate; friend class QmlDesigner::Internal::ModelPrivate; - friend class QmlDesigner::Internal::MetaInfoParser; + friend class QmlDesigner::Internal::MetaInfoReader; friend class QmlDesigner::Internal::SubComponentManagerPrivate; friend bool operator==(const MetaInfo &, const MetaInfo &); diff --git a/src/plugins/qmldesigner/designercore/include/metainforeader.h b/src/plugins/qmldesigner/designercore/include/metainforeader.h new file mode 100644 index 0000000000..8dbf934786 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/include/metainforeader.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef METAINFOREADER_H +#define METAINFOREADER_H + +#include "qmldesignercorelib_global.h" +#include <metainfo.h> + +#include <qmljs/qmljssimplereader.h> + +#include <QString> +#include <QFile> + + +namespace QmlDesigner { + +class ItemLibraryEntry; + +namespace Internal { + + +class MetaInfoReader : protected QmlJS::SimpleAbstractStreamReader +{ + Q_DECLARE_TR_FUNCTIONS(QmlDesigner::Internal::MetaInfoReader) + +public: + MetaInfoReader(const MetaInfo &metaInfo); + + void readMetaInfoFile(const QString &path); + + + QStringList errors(); + +protected: + virtual void elementStart(const QString &name); + virtual void elementEnd(); + virtual void propertyDefinition(const QString &name, const QVariant &value); + +private: + enum ParserSate { Error, + Finished, + Undefined, + ParsingDocument, + ParsingMetaInfo, + ParsingType, + ParsingItemLibrary, + ParsingProperty, + ParsingQmlSource + }; + + ParserSate readDocument(const QString &name); + + ParserSate readMetaInfoRootElement(const QString &name); + ParserSate readTypeElement(const QString &name); + ParserSate readItemLibraryEntryElement(const QString &name); + ParserSate readPropertyElement(const QString &name); + ParserSate readQmlSourceElement(const QString &name); + + void readTypeProperty(const QString &name, const QVariant &value); + void readItemLibraryEntryProperty(const QString &name, const QVariant &value); + void readPropertyProperty(const QString &name, const QVariant &value); + void readQmlSourceProperty(const QString &name, const QVariant &value); + + void setVersion(const QString &versionNumber); + + ParserSate parserState() const; + void setParserState(ParserSate newParserState); + + void insertItemLibraryEntry(); + void insertProperty(); + + void addErrorInvalidType(const QString &typeName); + + ParserSate m_parserState; + MetaInfo m_metaInfo; + + QString m_currentClassName; + QString m_currentIcon; + QString m_currentSource; + ItemLibraryEntry m_currentEntry; + + QString m_currentPropertyName; + QString m_currentPropertyType; + QVariant m_currentPropertyValue; +}; + +} +} +#endif // METAINFOREADER_H diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index d6cd667922..73da1aadbd 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -30,11 +30,10 @@ #ifndef DESIGNERMODEL_H #define DESIGNERMODEL_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include <QObject> #include <QMimeData> #include <QPair> -#include <QDeclarativeError> #include <import.h> @@ -52,7 +51,6 @@ class AnchorLine; class ModelNode; class NodeState; class AbstractView; -class WidgetQueryView; class NodeStateChangeSet; class MetaInfo; class NodeMetaInfo; @@ -63,7 +61,7 @@ class RewriterView; typedef QList<QPair<QString, QVariant> > PropertyListType; -class CORESHARED_EXPORT Model : public QObject +class QMLDESIGNERCORE_EXPORT Model : public QObject { friend class QmlDesigner::ModelNode; friend class QmlDesigner::NodeState; @@ -80,7 +78,7 @@ public: virtual ~Model(); - static Model *create(QString type, int major = 4, int minor = 7, Model *metaInfoPropxyModel = 0); + static Model *create(QString type, int major = 1, int minor = 1, Model *metaInfoPropxyModel = 0); Model *masterModel() const; void setMasterModel(Model *model); diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h index ebf5e5124e..b494e2f708 100644 --- a/src/plugins/qmldesigner/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/designercore/include/modelnode.h @@ -30,7 +30,7 @@ #ifndef DESIGNERNODE_H #define DESIGNERNODE_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include <QWeakPointer> #include <QList> #include <QMetaType> @@ -63,18 +63,18 @@ class NodeProperty; class NodeAbstractProperty; class ModelNode; -CORESHARED_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList); +QMLDESIGNERCORE_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList); typedef QList<QPair<QString, QVariant> > PropertyListType; -class CORESHARED_EXPORT ModelNode +class QMLDESIGNERCORE_EXPORT ModelNode { - friend CORESHARED_EXPORT bool operator ==(const ModelNode &firstNode, const ModelNode &secondNode); - friend CORESHARED_EXPORT bool operator !=(const ModelNode &firstNode, const ModelNode &secondNode); - friend CORESHARED_EXPORT uint qHash(const ModelNode & node); - friend CORESHARED_EXPORT QDebug operator<<(QDebug debug, const ModelNode &modelNode); - friend CORESHARED_EXPORT bool operator <(const ModelNode &firstNode, const ModelNode &secondNode); - friend CORESHARED_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList); + friend QMLDESIGNERCORE_EXPORT bool operator ==(const ModelNode &firstNode, const ModelNode &secondNode); + friend QMLDESIGNERCORE_EXPORT bool operator !=(const ModelNode &firstNode, const ModelNode &secondNode); + friend QMLDESIGNERCORE_EXPORT uint qHash(const ModelNode & node); + friend QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const ModelNode &modelNode); + friend QMLDESIGNERCORE_EXPORT bool operator <(const ModelNode &firstNode, const ModelNode &secondNode); + friend QMLDESIGNERCORE_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList); friend class QmlDesigner::Model; friend class QmlDesigner::AbstractView; friend class QmlDesigner::NodeListProperty; @@ -192,12 +192,12 @@ private: // variables QWeakPointer<AbstractView> m_view; }; -CORESHARED_EXPORT bool operator ==(const ModelNode &firstNode, const ModelNode &secondNode); -CORESHARED_EXPORT bool operator !=(const ModelNode &firstNode, const ModelNode &secondNode); -CORESHARED_EXPORT uint qHash(const ModelNode & node); -CORESHARED_EXPORT bool operator <(const ModelNode &firstNode, const ModelNode &secondNode); -CORESHARED_EXPORT QDebug operator<<(QDebug debug, const ModelNode &modelNode); -CORESHARED_EXPORT QTextStream& operator<<(QTextStream &stream, const ModelNode &modelNode); +QMLDESIGNERCORE_EXPORT bool operator ==(const ModelNode &firstNode, const ModelNode &secondNode); +QMLDESIGNERCORE_EXPORT bool operator !=(const ModelNode &firstNode, const ModelNode &secondNode); +QMLDESIGNERCORE_EXPORT uint qHash(const ModelNode & node); +QMLDESIGNERCORE_EXPORT bool operator <(const ModelNode &firstNode, const ModelNode &secondNode); +QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const ModelNode &modelNode); +QMLDESIGNERCORE_EXPORT QTextStream& operator<<(QTextStream &stream, const ModelNode &modelNode); } Q_DECLARE_METATYPE(QmlDesigner::ModelNode) diff --git a/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h b/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h index 9493b6001d..78f52a4d52 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h @@ -45,9 +45,9 @@ class NodeAbstractProperty : public AbstractProperty friend class QmlDesigner::Internal::ModelPrivate; friend class QmlDesigner::AbstractProperty; - friend CORESHARED_EXPORT bool operator ==(const NodeAbstractProperty &property1, const NodeAbstractProperty &property2); - friend CORESHARED_EXPORT bool operator !=(const NodeAbstractProperty &property1, const NodeAbstractProperty &property2); - friend CORESHARED_EXPORT uint qHash(const NodeAbstractProperty& property); + friend QMLDESIGNERCORE_EXPORT bool operator ==(const NodeAbstractProperty &property1, const NodeAbstractProperty &property2); + friend QMLDESIGNERCORE_EXPORT bool operator !=(const NodeAbstractProperty &property1, const NodeAbstractProperty &property2); + friend QMLDESIGNERCORE_EXPORT uint qHash(const NodeAbstractProperty& property); public: NodeAbstractProperty(); @@ -66,11 +66,11 @@ protected: }; -CORESHARED_EXPORT bool operator ==(const NodeAbstractProperty &property1, const NodeAbstractProperty &property2); -CORESHARED_EXPORT bool operator !=(const NodeAbstractProperty &property1, const NodeAbstractProperty &property2); -CORESHARED_EXPORT uint qHash(const NodeAbstractProperty& property); -CORESHARED_EXPORT QTextStream& operator<<(QTextStream &stream, const NodeAbstractProperty &property); -CORESHARED_EXPORT QDebug operator<<(QDebug debug, const NodeAbstractProperty &property); +QMLDESIGNERCORE_EXPORT bool operator ==(const NodeAbstractProperty &property1, const NodeAbstractProperty &property2); +QMLDESIGNERCORE_EXPORT bool operator !=(const NodeAbstractProperty &property1, const NodeAbstractProperty &property2); +QMLDESIGNERCORE_EXPORT uint qHash(const NodeAbstractProperty& property); +QMLDESIGNERCORE_EXPORT QTextStream& operator<<(QTextStream &stream, const NodeAbstractProperty &property); +QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const NodeAbstractProperty &property); } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index 29e3d2cb1d..2be9671a98 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -30,7 +30,7 @@ #ifndef NODEINSTANCEVIEW_H #define NODEINSTANCEVIEW_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "abstractview.h" #include <modelnode.h> @@ -69,7 +69,7 @@ class CompleteComponentCommand; class InformationContainer; class TokenCommand; -class CORESHARED_EXPORT NodeInstanceView : public AbstractView, public NodeInstanceClientInterface +class QMLDESIGNERCORE_EXPORT NodeInstanceView : public AbstractView, public NodeInstanceClientInterface { Q_OBJECT @@ -135,6 +135,7 @@ public: void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command); void componentCompleted(const ComponentCompletedCommand &command); void token(const TokenCommand &command); + void debugOutput(const DebugOutputCommand &command); QImage statePreviewImage(const ModelNode &stateNode) const; @@ -183,6 +184,8 @@ private: // functions RemoveInstancesCommand createRemoveInstancesCommand(const QList<ModelNode> &nodeList) const; RemoveInstancesCommand createRemoveInstancesCommand(const ModelNode &node) const; RemovePropertiesCommand createRemovePropertiesCommand(const QList<AbstractProperty> &propertyList) const; + RemoveSharedMemoryCommand createRemoveSharedMemoryCommand(const QString &sharedMemoryTypeName, quint32 keyNumber); + RemoveSharedMemoryCommand createRemoveSharedMemoryCommand(const QString &sharedMemoryTypeName, const QList<ModelNode> &nodeList); void resetHorizontalAnchors(const ModelNode &node); void resetVerticalAnchors(const ModelNode &node); diff --git a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h index 25980a51d5..258ec5f73e 100644 --- a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h @@ -31,7 +31,7 @@ #define NODELISTPROPERTY_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "nodeabstractproperty.h" #include <QList> @@ -45,7 +45,7 @@ namespace Internal { } -class CORESHARED_EXPORT NodeListProperty : public NodeAbstractProperty +class QMLDESIGNERCORE_EXPORT NodeListProperty : public NodeAbstractProperty { friend class QmlDesigner::ModelNode; friend class QmlDesigner::AbstractProperty; diff --git a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h index 4771f1eb1c..ec9e428eaf 100644 --- a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h @@ -35,7 +35,7 @@ #include <QExplicitlySharedDataPointer> #include <QIcon> -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "invalidmetainfoexception.h" QT_BEGIN_NAMESPACE @@ -50,13 +50,13 @@ class AbstractProperty; namespace Internal { class MetaInfoPrivate; - class MetaInfoParser; + class MetaInfoReader; class SubComponentManagerPrivate; class ItemLibraryEntryData; class NodeMetaInfoPrivate; } -class CORESHARED_EXPORT NodeMetaInfo +class QMLDESIGNERCORE_EXPORT NodeMetaInfo { public: NodeMetaInfo(); @@ -97,6 +97,8 @@ public: bool availableInVersion(int majorVersion, int minorVersion) const; bool isSubclassOf(const QString& type, int majorVersion, int minorVersio) const; + bool isPositioner() const; + static void clearCache(); private: diff --git a/src/plugins/qmldesigner/designercore/include/nodeproperty.h b/src/plugins/qmldesigner/designercore/include/nodeproperty.h index fac2594b46..86aef86e0c 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodeproperty.h @@ -30,7 +30,7 @@ #ifndef NODEPROPERTY_H #define NODEPROPERTY_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "nodeabstractproperty.h" namespace QmlDesigner { @@ -39,7 +39,7 @@ namespace Internal { class ModelPrivate; } -class CORESHARED_EXPORT NodeProperty : public NodeAbstractProperty +class QMLDESIGNERCORE_EXPORT NodeProperty : public NodeAbstractProperty { friend class QmlDesigner::ModelNode; friend class QmlDesigner::Internal::ModelPrivate; diff --git a/src/plugins/qmldesigner/designercore/include/notimplementedexception.h b/src/plugins/qmldesigner/designercore/include/notimplementedexception.h index 80e0319473..301e92c768 100644 --- a/src/plugins/qmldesigner/designercore/include/notimplementedexception.h +++ b/src/plugins/qmldesigner/designercore/include/notimplementedexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT NotImplementedException : public Exception +class QMLDESIGNERCORE_EXPORT NotImplementedException : public Exception { public: NotImplementedException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/plaintexteditmodifier.h b/src/plugins/qmldesigner/designercore/include/plaintexteditmodifier.h index 362ccfe8d3..ad79a1a64f 100644 --- a/src/plugins/qmldesigner/designercore/include/plaintexteditmodifier.h +++ b/src/plugins/qmldesigner/designercore/include/plaintexteditmodifier.h @@ -30,7 +30,7 @@ #ifndef PLAINTEXTEDITMODIFIER_H #define PLAINTEXTEDITMODIFIER_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "textmodifier.h" QT_BEGIN_NAMESPACE @@ -44,7 +44,7 @@ namespace Utils { namespace QmlDesigner { -class CORESHARED_EXPORT PlainTextEditModifier: public TextModifier +class QMLDESIGNERCORE_EXPORT PlainTextEditModifier: public TextModifier { Q_OBJECT @@ -98,7 +98,7 @@ private: bool m_ongoingTextChange; }; -class CORESHARED_EXPORT NotIndentingTextEditModifier: public PlainTextEditModifier +class QMLDESIGNERCORE_EXPORT NotIndentingTextEditModifier: public PlainTextEditModifier { public: NotIndentingTextEditModifier(QPlainTextEdit *textEdit) diff --git a/src/plugins/qmldesigner/designercore/include/propertycontainer.h b/src/plugins/qmldesigner/designercore/include/propertycontainer.h index 411ea5d190..69972a5e50 100644 --- a/src/plugins/qmldesigner/designercore/include/propertycontainer.h +++ b/src/plugins/qmldesigner/designercore/include/propertycontainer.h @@ -30,7 +30,7 @@ #ifndef PROPERTYCONTAINER_H #define PROPERTYCONTAINER_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include <QString> #include <QExplicitlySharedDataPointer> @@ -41,13 +41,15 @@ namespace QmlDesigner { class PropertyContainer; -CORESHARED_EXPORT QDataStream &operator<<(QDataStream &stream, const PropertyContainer &propertyContainer); -CORESHARED_EXPORT QDataStream &operator>>(QDataStream &stream, PropertyContainer &propertyContainer); +QMLDESIGNERCORE_EXPORT QDataStream &operator<<(QDataStream &stream, const PropertyContainer &propertyContainer); +QMLDESIGNERCORE_EXPORT QDataStream &operator>>(QDataStream &stream, PropertyContainer &propertyContainer); +QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const PropertyContainer &propertyContainer); -class CORESHARED_EXPORT PropertyContainer +class QMLDESIGNERCORE_EXPORT PropertyContainer { - friend CORESHARED_EXPORT QDataStream &operator<<(QDataStream &stream, const PropertyContainer &propertyContainer); - friend CORESHARED_EXPORT QDataStream &operator>>(QDataStream &stream, PropertyContainer &propertyContainer); + friend QMLDESIGNERCORE_EXPORT QDataStream &operator<<(QDataStream &stream, const PropertyContainer &propertyContainer); + friend QMLDESIGNERCORE_EXPORT QDataStream &operator>>(QDataStream &stream, PropertyContainer &propertyContainer); + friend QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const PropertyContainer &propertyContainer); public: PropertyContainer(); @@ -70,8 +72,9 @@ private: mutable QVariant m_value; }; -CORESHARED_EXPORT QDataStream &operator<<(QDataStream &stream, const QList<PropertyContainer> &propertyContainerList); -CORESHARED_EXPORT QDataStream &operator>>(QDataStream &stream, QList<PropertyContainer> &propertyContainerList); +QMLDESIGNERCORE_EXPORT QDataStream &operator<<(QDataStream &stream, const QList<PropertyContainer> &propertyContainerList); +QMLDESIGNERCORE_EXPORT QDataStream &operator>>(QDataStream &stream, QList<PropertyContainer> &propertyContainerList); +QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, QList<PropertyContainer> &propertyContainerList); } //namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/propertynode.h b/src/plugins/qmldesigner/designercore/include/propertynode.h index 62eaac1f21..4c5b674fa3 100644 --- a/src/plugins/qmldesigner/designercore/include/propertynode.h +++ b/src/plugins/qmldesigner/designercore/include/propertynode.h @@ -30,11 +30,11 @@ #ifndef PROPERTYNODE_H #define PROPERTYNODE_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" namespace QmlDesigner { -class CORESHARED_EXPORT PropertyNode // : public BaseModelNode +class QMLDESIGNERCORE_EXPORT PropertyNode // : public BaseModelNode { public: PropertyNode(); diff --git a/src/plugins/qmldesigner/designercore/include/qmlanchors.h b/src/plugins/qmldesigner/designercore/include/qmlanchors.h index 3b30ee8abb..63b784f707 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlanchors.h +++ b/src/plugins/qmldesigner/designercore/include/qmlanchors.h @@ -30,13 +30,13 @@ #ifndef QmlAnchors_H #define QmlAnchors_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include <qmlitemnode.h> namespace QmlDesigner { -class CORESHARED_EXPORT AnchorLine +class QMLDESIGNERCORE_EXPORT AnchorLine { public: enum Type { @@ -73,7 +73,7 @@ private: }; -class CORESHARED_EXPORT QmlAnchors +class QMLDESIGNERCORE_EXPORT QmlAnchors { public: QmlAnchors(const QmlItemNode &fxItemNode); diff --git a/src/plugins/qmldesigner/designercore/include/qmlchangeset.h b/src/plugins/qmldesigner/designercore/include/qmlchangeset.h index ff29b5083e..82dde2866d 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlchangeset.h +++ b/src/plugins/qmldesigner/designercore/include/qmlchangeset.h @@ -30,13 +30,13 @@ #ifndef QMLCHANGESET_H #define QMLCHANGESET_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include <modelnode.h> #include "qmlmodelnodefacade.h" namespace QmlDesigner { -class CORESHARED_EXPORT QmlModelStateOperation : public QmlModelNodeFacade +class QMLDESIGNERCORE_EXPORT QmlModelStateOperation : public QmlModelNodeFacade { public: QmlModelStateOperation() : QmlModelNodeFacade() {} @@ -47,7 +47,7 @@ public: }; -class CORESHARED_EXPORT QmlPropertyChanges : public QmlModelStateOperation +class QMLDESIGNERCORE_EXPORT QmlPropertyChanges : public QmlModelStateOperation { public: QmlPropertyChanges() : QmlModelStateOperation() {} diff --git a/src/plugins/qmldesigner/designercore/include/corelib_global.h b/src/plugins/qmldesigner/designercore/include/qmldesignercorelib_global.h index 0d63fc559e..444db0cf89 100644 --- a/src/plugins/qmldesigner/designercore/include/corelib_global.h +++ b/src/plugins/qmldesigner/designercore/include/qmldesignercorelib_global.h @@ -32,15 +32,14 @@ // Unnecessary since core isn't a dll any more. -#define CORESHARED_EXPORT #define TEST_CORESHARED_EXPORT -//#if defined(CORE_LIBRARY) -//# define CORESHARED_EXPORT Q_DECL_EXPORT -//#else -//# define CORESHARED_EXPORT Q_DECL_IMPORT -//#endif -// +#if defined(DESIGNER_CORE_LIBRARY) +# define QMLDESIGNERCORE_EXPORT Q_DECL_EXPORT +#else +# define QMLDESIGNERCORE_EXPORT Q_DECL_IMPORT +#endif + //#if defined(TEST_EXPORTS) //#if defined(CORE_LIBRARY) //# define TEST_CORESHARED_EXPORT Q_DECL_EXPORT diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index 53532f1e03..a8a3537230 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -30,7 +30,7 @@ #ifndef QmlItemNode_H #define QmlItemNode_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include <modelnode.h> #include "qmlobjectnode.h" #include "qmlstate.h" @@ -44,9 +44,9 @@ namespace QmlDesigner { class QmlModelStateGroup; class QmlAnchors; -class CORESHARED_EXPORT QmlItemNode : public QmlObjectNode +class QMLDESIGNERCORE_EXPORT QmlItemNode : public QmlObjectNode { - friend class CORESHARED_EXPORT QmlAnchors; + friend class QMLDESIGNERCORE_EXPORT QmlAnchors; public: QmlItemNode() : QmlObjectNode() {} QmlItemNode(const ModelNode &modelNode) : QmlObjectNode(modelNode) {} @@ -97,9 +97,9 @@ public: bool hasAnySubModelNodes() const; }; -CORESHARED_EXPORT uint qHash(const QmlItemNode &node); +QMLDESIGNERCORE_EXPORT uint qHash(const QmlItemNode &node); -class CORESHARED_EXPORT QmlModelStateGroup +class QMLDESIGNERCORE_EXPORT QmlModelStateGroup { friend class QmlItemNode; friend class QmlModelView; @@ -122,8 +122,8 @@ private: ModelNode m_modelNode; }; -CORESHARED_EXPORT QList<ModelNode> toModelNodeList(const QList<QmlItemNode> &fxItemNodeList); -CORESHARED_EXPORT QList<QmlItemNode> toQmlItemNodeList(const QList<ModelNode> &modelNodeList); +QMLDESIGNERCORE_EXPORT QList<ModelNode> toModelNodeList(const QList<QmlItemNode> &fxItemNodeList); +QMLDESIGNERCORE_EXPORT QList<QmlItemNode> toQmlItemNodeList(const QList<ModelNode> &modelNodeList); } //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/qmlmodelnodefacade.h b/src/plugins/qmldesigner/designercore/include/qmlmodelnodefacade.h index c7dfa30ee3..8e8c875f20 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlmodelnodefacade.h +++ b/src/plugins/qmldesigner/designercore/include/qmlmodelnodefacade.h @@ -30,14 +30,14 @@ #ifndef FXMODELNODEFACADE_H #define FXMODELNODEFACADE_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include <modelnode.h> namespace QmlDesigner { class QmlModelView; -class CORESHARED_EXPORT QmlModelNodeFacade +class QMLDESIGNERCORE_EXPORT QmlModelNodeFacade { public: operator ModelNode() const { return m_modelNode; } @@ -47,10 +47,10 @@ public: QmlModelNodeFacade(); bool isRootNode() const; + QmlModelView* qmlModelView() const; protected: QmlModelNodeFacade(const ModelNode &modelNode); - QmlModelView* qmlModelView() const; private: ModelNode m_modelNode; diff --git a/src/plugins/qmldesigner/designercore/include/qmlmodelview.h b/src/plugins/qmldesigner/designercore/include/qmlmodelview.h index 63b8c24c19..f8c093dc36 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlmodelview.h +++ b/src/plugins/qmldesigner/designercore/include/qmlmodelview.h @@ -30,7 +30,7 @@ #ifndef QMLMODELVIEW_H #define QMLMODELVIEW_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include <QPoint> #include <abstractview.h> #include "qmlitemnode.h" @@ -42,11 +42,11 @@ namespace QmlDesigner { class ItemLibraryEntry; -class CORESHARED_EXPORT QmlModelView : public AbstractView +class QMLDESIGNERCORE_EXPORT QmlModelView : public AbstractView { Q_OBJECT - friend CORESHARED_EXPORT class QmlObjectNode; - friend CORESHARED_EXPORT class QmlModelNodeFacade; + friend QMLDESIGNERCORE_EXPORT class QmlObjectNode; + friend QMLDESIGNERCORE_EXPORT class QmlModelNodeFacade; public: QmlModelView(QObject *parent) ; @@ -67,6 +67,8 @@ public: int minorVersion, const PropertyListType &propertyList = PropertyListType()); + ModelNode createQmlState(const PropertyListType &propertyList = PropertyListType()); + QmlItemNode createQmlItemNode(const ItemLibraryEntry &itemLibraryEntry, const QPointF &position, QmlItemNode parentNode); QmlItemNode createQmlItemNodeFromImage(const QString &imageName, const QPointF &position, QmlItemNode parentNode); @@ -120,8 +122,6 @@ public: void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports); void nodeSourceChanged(const ModelNode &modelNode, const QString &newNodeSource); - void showContextMenu(const QPoint &globalPos, const QPoint &scenePos, bool showSelection); - protected: NodeInstance instanceForModelNode(const ModelNode &modelNode); bool hasInstanceForModelNode(const ModelNode &modelNode); diff --git a/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h b/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h index fc17a0c3f5..b5339fe1c7 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h @@ -30,7 +30,7 @@ #ifndef FXOBJECTNODE_H #define FXOBJECTNODE_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include "qmlmodelnodefacade.h" #include "qmlstate.h" #include "qmlchangeset.h" @@ -42,7 +42,7 @@ namespace QmlDesigner { class QmlItemNode; class QmlPropertyChanges; -class CORESHARED_EXPORT QmlObjectNode : public QmlModelNodeFacade +class QMLDESIGNERCORE_EXPORT QmlObjectNode : public QmlModelNodeFacade { public: QmlObjectNode() : QmlModelNodeFacade() {} @@ -106,9 +106,9 @@ protected: QList<QmlModelState> allDefinedStates() const; }; -CORESHARED_EXPORT uint qHash(const QmlObjectNode &node); -CORESHARED_EXPORT QList<ModelNode> toModelNodeList(const QList<QmlObjectNode> &fxObjectNodeList); -CORESHARED_EXPORT QList<QmlObjectNode> toQmlObjectNodeList(const QList<ModelNode> &modelNodeList); +QMLDESIGNERCORE_EXPORT uint qHash(const QmlObjectNode &node); +QMLDESIGNERCORE_EXPORT QList<ModelNode> toModelNodeList(const QList<QmlObjectNode> &fxObjectNodeList); +QMLDESIGNERCORE_EXPORT QList<QmlObjectNode> toQmlObjectNodeList(const QList<ModelNode> &modelNodeList); }// QmlDesigner #endif // FXOBJECTNODE_H diff --git a/src/plugins/qmldesigner/designercore/include/qmlstate.h b/src/plugins/qmldesigner/designercore/include/qmlstate.h index d21ee6572d..f87a4aec01 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlstate.h +++ b/src/plugins/qmldesigner/designercore/include/qmlstate.h @@ -30,7 +30,7 @@ #ifndef FXSTATE_H #define FXSTATE_H -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> #include "qmlmodelnodefacade.h" #include "qmlchangeset.h" @@ -40,9 +40,9 @@ class QmlModelView; class QmlModelStateGroup; class QmlObjectNode; -class CORESHARED_EXPORT QmlModelState : public QmlModelNodeFacade +class QMLDESIGNERCORE_EXPORT QmlModelState : public QmlModelNodeFacade { - friend class CORESHARED_EXPORT QmlModelView; + friend class QMLDESIGNERCORE_EXPORT QmlModelView; public: QmlModelState(); diff --git a/src/plugins/qmldesigner/designercore/include/removebasestateexception.h b/src/plugins/qmldesigner/designercore/include/removebasestateexception.h index f058dd368f..695d24d7d2 100644 --- a/src/plugins/qmldesigner/designercore/include/removebasestateexception.h +++ b/src/plugins/qmldesigner/designercore/include/removebasestateexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT RemoveBaseStateException : public Exception +class QMLDESIGNERCORE_EXPORT RemoveBaseStateException : public Exception { public: RemoveBaseStateException(int line, diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index 7e80eba745..5c72511bcf 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -30,7 +30,7 @@ #ifndef REWRITERVIEW_H #define REWRITERVIEW_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "abstractview.h" #include "exception.h" #include <modelnodepositionstorage.h> @@ -39,6 +39,7 @@ #include <QPointer> #include <QWeakPointer> #include <QHash> +#include <QUrl> #include <modelnode.h> #include <QScopedPointer> @@ -54,7 +55,7 @@ class ScopeChain; namespace QmlDesigner { -class CORESHARED_EXPORT TextModifier; +class TextModifier; namespace Internal { @@ -64,7 +65,7 @@ class ModelNodePositionStorage; } //Internal -class CORESHARED_EXPORT RewriterView : public AbstractView +class QMLDESIGNERCORE_EXPORT RewriterView : public AbstractView { Q_OBJECT diff --git a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h b/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h index 9528c2ee9f..58ef809068 100644 --- a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h +++ b/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h @@ -30,7 +30,7 @@ #ifndef SUBCOMPONENTMANAGER_H #define SUBCOMPONENTMANAGER_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include <import.h> @@ -45,7 +45,7 @@ namespace QmlDesigner { class Model; -class CORESHARED_EXPORT SubComponentManager : public QObject +class QMLDESIGNERCORE_EXPORT SubComponentManager : public QObject { Q_OBJECT public: diff --git a/src/plugins/qmldesigner/designercore/include/textmodifier.h b/src/plugins/qmldesigner/designercore/include/textmodifier.h index 764e46de1a..a00276db50 100644 --- a/src/plugins/qmldesigner/designercore/include/textmodifier.h +++ b/src/plugins/qmldesigner/designercore/include/textmodifier.h @@ -30,7 +30,7 @@ #ifndef TEXTMODIFIER_H #define TEXTMODIFIER_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include <qmljs/qmljsdocument.h> @@ -41,7 +41,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT TextModifier: public QObject +class QMLDESIGNERCORE_EXPORT TextModifier: public QObject { Q_OBJECT diff --git a/src/plugins/qmldesigner/designercore/include/variantproperty.h b/src/plugins/qmldesigner/designercore/include/variantproperty.h index f375fba7d8..c4aa37a9a5 100644 --- a/src/plugins/qmldesigner/designercore/include/variantproperty.h +++ b/src/plugins/qmldesigner/designercore/include/variantproperty.h @@ -30,7 +30,7 @@ #ifndef VARIANTROPERTY_H #define VARIANTROPERTY_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "abstractproperty.h" QT_BEGIN_NAMESPACE @@ -45,7 +45,7 @@ namespace Internal { class ModelPrivate; } -class CORESHARED_EXPORT VariantProperty : public AbstractProperty +class QMLDESIGNERCORE_EXPORT VariantProperty : public AbstractProperty { friend class QmlDesigner::ModelNode; friend class QmlDesigner::Internal::ModelPrivate; @@ -57,7 +57,7 @@ public: VariantProperty& operator= (const QVariant &value); void setDynamicTypeNameAndValue(const QString &type, const QVariant &value); - VariantProperty& operator= (const QPair<QString, QVariant> &typeValuePair); + Q_DECL_DEPRECATED VariantProperty& operator= (const QPair<QString, QVariant> &typeValuePair); VariantProperty(); VariantProperty(const VariantProperty &property, AbstractView *view); @@ -65,8 +65,8 @@ protected: VariantProperty(const QString &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); }; -CORESHARED_EXPORT QTextStream& operator<<(QTextStream &stream, const VariantProperty &property); -CORESHARED_EXPORT QDebug operator<<(QDebug debug, const VariantProperty &VariantProperty); +QMLDESIGNERCORE_EXPORT QTextStream& operator<<(QTextStream &stream, const VariantProperty &property); +QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const VariantProperty &VariantProperty); } diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp index 2144aa4fc7..c7f372d39e 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp @@ -35,6 +35,7 @@ #include <QCoreApplication> #include <QUuid> #include <QFileInfo> +#include <QTimer> #include "propertyabstractcontainer.h" #include "propertyvaluecontainer.h" @@ -63,14 +64,28 @@ #include "statepreviewimagechangedcommand.h" #include "componentcompletedcommand.h" #include "tokencommand.h" - +#include "removesharedmemorycommand.h" +#include "endpuppetcommand.h" #include "synchronizecommand.h" +#include "debugoutputcommand.h" #include "nodeinstanceview.h" #include "import.h" + +#include <utils/hostosinfo.h> + #include <QMessageBox> +namespace { +static QLatin1String qmlPuppetApplicationDirectoryForTests() +{ + if (Utils::HostOsInfo::isWindowsHost()) + //one more - debug/release dir + return QLatin1String("/../../../../../../bin/"); + return QLatin1String("/../../../../../bin/"); +} +} //namespace namespace QmlDesigner { @@ -108,7 +123,9 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV QString applicationPath = pathToQt + QLatin1String("/bin"); if (runModus == TestModus) { - applicationPath = QCoreApplication::applicationDirPath() + QLatin1String("/../../../../../bin"); + applicationPath = QCoreApplication::applicationDirPath() + + qmlPuppetApplicationDirectoryForTests() + + qmlPuppetApplicationName(); } else { applicationPath = macOSBundlePath(applicationPath); applicationPath += QLatin1Char('/') + qmlPuppetApplicationName(); @@ -126,7 +143,6 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV } QProcessEnvironment enviroment = QProcessEnvironment::systemEnvironment(); - enviroment.insert("QML_NO_THREADED_RENDERER", "true"); if (QFileInfo(applicationPath).exists()) { m_qmlPuppetEditorProcess = new QProcess; @@ -218,6 +234,8 @@ NodeInstanceServerProxy::~NodeInstanceServerProxy() { disconnect(this, SLOT(processFinished(int,QProcess::ExitStatus))); + writeCommand(QVariant::fromValue(EndPuppetCommand())); + if (m_firstSocket) m_firstSocket->close(); @@ -229,13 +247,13 @@ NodeInstanceServerProxy::~NodeInstanceServerProxy() if (m_qmlPuppetEditorProcess) - m_qmlPuppetEditorProcess->kill(); + QTimer::singleShot(3000, m_qmlPuppetEditorProcess.data(), SLOT(terminate())); if (m_qmlPuppetPreviewProcess) - m_qmlPuppetPreviewProcess->kill(); + QTimer::singleShot(3000, m_qmlPuppetPreviewProcess.data(), SLOT(terminate())); if (m_qmlPuppetRenderProcess) - m_qmlPuppetRenderProcess->kill(); + QTimer::singleShot(3000, m_qmlPuppetRenderProcess.data(), SLOT(terminate())); } void NodeInstanceServerProxy::dispatchCommand(const QVariant &command) @@ -248,6 +266,7 @@ void NodeInstanceServerProxy::dispatchCommand(const QVariant &command) static const int componentCompletedCommandType = QMetaType::type("ComponentCompletedCommand"); static const int synchronizeCommandType = QMetaType::type("SynchronizeCommand"); static const int tokenCommandType = QMetaType::type("TokenCommand"); + static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand"); if (command.userType() == informationChangedCommandType) nodeInstanceClient()->informationChanged(command.value<InformationChangedCommand>()); @@ -263,6 +282,8 @@ void NodeInstanceServerProxy::dispatchCommand(const QVariant &command) nodeInstanceClient()->componentCompleted(command.value<ComponentCompletedCommand>()); else if (command.userType() == tokenCommandType) nodeInstanceClient()->token(command.value<TokenCommand>()); + else if (command.userType() == debugOutputCommandType) + nodeInstanceClient()->debugOutput(command.value<DebugOutputCommand>()); else if (command.userType() == synchronizeCommandType) { SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>(); m_synchronizeId = synchronizeCommand.synchronizeId(); @@ -305,7 +326,7 @@ void NodeInstanceServerProxy::writeCommand(const QVariant &command) writeCommandToSocket(QVariant::fromValue(synchronizeCommand), m_firstSocket.data(), m_writeCommandCounter); m_writeCommandCounter++; - while(m_firstSocket->waitForReadyRead()) { + while (m_firstSocket->waitForReadyRead(100)) { readFirstDataStream(); if (m_synchronizeId == synchronizeId) return; @@ -316,6 +337,9 @@ void NodeInstanceServerProxy::writeCommand(const QVariant &command) void NodeInstanceServerProxy::processFinished(int /*exitCode*/, QProcess::ExitStatus exitStatus) { qDebug() << "Process finished:" << sender(); + + writeCommand(QVariant::fromValue(EndPuppetCommand())); + if (m_firstSocket) m_firstSocket->close(); if (m_secondSocket) @@ -444,25 +468,16 @@ void NodeInstanceServerProxy::readThirdDataStream() QString NodeInstanceServerProxy::qmlPuppetApplicationName() const { - QString appName; - if (hasQtQuick2(m_nodeInstanceView.data())) { - appName = QLatin1String("qml2puppet"); - } else { - appName = QLatin1String("qmlpuppet"); - } - #ifdef Q_OS_WIN - appName += QLatin1String(".exe"); - #endif - - return appName; + if (hasQtQuick2(m_nodeInstanceView.data())) + return QLatin1String("qml2puppet" QTC_HOST_EXE_SUFFIX); + return QLatin1String("qmlpuppet" QTC_HOST_EXE_SUFFIX); } QString NodeInstanceServerProxy::macOSBundlePath(const QString &path) const { QString applicationPath = path; -#ifdef Q_OS_MACX - applicationPath += QLatin1String("/qmlpuppet.app/Contents/MacOS"); -#endif + if (Utils::HostOsInfo::isMacHost()) + applicationPath += QLatin1String("/qmlpuppet.app/Contents/MacOS"); return applicationPath; } @@ -541,4 +556,9 @@ void NodeInstanceServerProxy::token(const TokenCommand &command) writeCommand(QVariant::fromValue(command)); } +void NodeInstanceServerProxy::removeSharedMemory(const RemoveSharedMemoryCommand &command) +{ + writeCommand(QVariant::fromValue(command)); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h index 8f2c983b18..9156c667fc 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h @@ -69,6 +69,7 @@ public: void completeComponent(const CompleteComponentCommand &command); void changeNodeSource(const ChangeNodeSourceCommand &command); void token(const TokenCommand &command); + void removeSharedMemory(const RemoveSharedMemoryCommand &command); protected: void writeCommand(const QVariant &command); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 91f344a461..afcec786fa 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -29,10 +29,6 @@ #include "nodeinstanceview.h" -#include <QDeclarativeEngine> -#include <QDeclarativeContext> - -#include <QDebug> #include <QUrl> #include <QGraphicsView> #include <QGraphicsScene> @@ -77,6 +73,7 @@ #include "completecomponentcommand.h" #include "componentcompletedcommand.h" #include "tokencommand.h" +#include "removesharedmemorycommand.h" #include "nodeinstanceserverproxy.h" @@ -240,6 +237,7 @@ void NodeInstanceView::nodeCreated(const ModelNode &createdNode) void NodeInstanceView::nodeAboutToBeRemoved(const ModelNode &removedNode) { nodeInstanceServer()->removeInstances(createRemoveInstancesCommand(removedNode)); + nodeInstanceServer()->removeSharedMemory(createRemoveSharedMemoryCommand("Image", removedNode.internalId())); removeInstanceAndSubInstances(removedNode); } @@ -311,6 +309,7 @@ void NodeInstanceView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& } nodeInstanceServer()->removeInstances(createRemoveInstancesCommand(nodeList)); + nodeInstanceServer()->removeSharedMemory(createRemoveSharedMemoryCommand("Image", nodeList)); nodeInstanceServer()->removeProperties(createRemovePropertiesCommand(nonNodePropertyList)); foreach (const AbstractProperty &property, propertyList) { @@ -1033,6 +1032,21 @@ RemovePropertiesCommand NodeInstanceView::createRemovePropertiesCommand(const QL return RemovePropertiesCommand(containerList); } +RemoveSharedMemoryCommand NodeInstanceView::createRemoveSharedMemoryCommand(const QString &sharedMemoryTypeName, quint32 keyNumber) +{ + return RemoveSharedMemoryCommand(sharedMemoryTypeName, QVector<qint32>() << keyNumber); +} + +RemoveSharedMemoryCommand NodeInstanceView::createRemoveSharedMemoryCommand(const QString &sharedMemoryTypeName, const QList<ModelNode> &nodeList) +{ + QVector<qint32> keyNumberVector; + + foreach (const ModelNode &modelNode, nodeList) + keyNumberVector.append(modelNode.internalId()); + + return RemoveSharedMemoryCommand(sharedMemoryTypeName, keyNumberVector); +} + void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command) { if (!model()) @@ -1050,6 +1064,8 @@ void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command) } } + nodeInstanceServer()->removeSharedMemory(createRemoveSharedMemoryCommand(QLatin1String("Values"), command.keyNumber())); + if (!valuePropertyChangeList.isEmpty()) emitInstancePropertyChange(valuePropertyChangeList); } @@ -1128,7 +1144,7 @@ void NodeInstanceView::statePreviewImagesChanged(const StatePreviewImageChangedC QVector<ModelNode> previewImageChangeVector; foreach (const ImageContainer &container, command.previews()) { - if (container.instanceId() == 0) { + if (container.keyNumber() == -1) { m_baseStatePreviewImage = container.image(); previewImageChangeVector.append(rootModelNode()); } else if (hasInstanceForId(container.instanceId())) { @@ -1201,6 +1217,10 @@ void NodeInstanceView::token(const TokenCommand &command) emitInstanceToken(command.tokenName(), command.tokenNumber(), nodeVector); } +void NodeInstanceView::debugOutput(const DebugOutputCommand & /*command*/) +{ +} + void NodeInstanceView::sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector) { QVector<qint32> instanceIdVector; diff --git a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp index d4a0e03688..f17f57d95d 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp @@ -55,14 +55,6 @@ public: bool forceImport; }; -class ItemLibraryInfoPrivate -{ -public: - QHash<QString, ItemLibraryEntry> nameToEntryHash; - - QWeakPointer<ItemLibraryInfo> baseInfo; -}; - } // namespace Internal // @@ -203,7 +195,7 @@ void ItemLibraryEntry::setForceImport(bool b) m_data->forceImport = b; } -void ItemLibraryEntry::addProperty(QString &name, QString &type, QString &value) +void ItemLibraryEntry::addProperty(QString &name, QString &type, QVariant &value) { Property property; property.set(name, type, value); @@ -248,68 +240,83 @@ QDataStream& operator>>(QDataStream& stream, ItemLibraryEntry &itemLibraryEntry) return stream; } +QDebug operator<<(QDebug debug, const ItemLibraryEntry &itemLibraryEntry) +{ + debug << itemLibraryEntry.m_data->name; + debug << itemLibraryEntry.m_data->typeName; + debug << itemLibraryEntry.m_data->majorVersion; + debug << itemLibraryEntry.m_data->minorVersion; + debug << itemLibraryEntry.m_data->icon; + debug << itemLibraryEntry.m_data->iconPath; + debug << itemLibraryEntry.m_data->category; + debug << itemLibraryEntry.m_data->dragIcon; + debug << itemLibraryEntry.m_data->requiredImport; + debug << itemLibraryEntry.m_data->forceImport; + + debug << itemLibraryEntry.m_data->properties; + debug << itemLibraryEntry.m_data->qml; + + return debug.space(); +} + // // ItemLibraryInfo // -ItemLibraryInfo::ItemLibraryInfo(QObject *parent) : - QObject(parent), - d(new Internal::ItemLibraryInfoPrivate()) +ItemLibraryInfo::ItemLibraryInfo(QObject *parent) + : QObject(parent) { } -ItemLibraryInfo::~ItemLibraryInfo() -{ - delete d; -} + QList<ItemLibraryEntry> ItemLibraryInfo::entriesForType(const QString &typeName, int majorVersion, int minorVersion) const { QList<ItemLibraryEntry> entries; - foreach (const ItemLibraryEntry &entry, d->nameToEntryHash) { + foreach (const ItemLibraryEntry &entry, m_nameToEntryHash) { if (entry.typeName() == typeName && entry.majorVersion() >= majorVersion && entry.minorVersion() >= minorVersion) entries += entry; } - if (d->baseInfo) - entries += d->baseInfo->entriesForType(typeName, majorVersion, minorVersion); + if (m_baseInfo) + entries += m_baseInfo->entriesForType(typeName, majorVersion, minorVersion); return entries; } ItemLibraryEntry ItemLibraryInfo::entry(const QString &name) const { - if (d->nameToEntryHash.contains(name)) - return d->nameToEntryHash.value(name); + if (m_nameToEntryHash.contains(name)) + return m_nameToEntryHash.value(name); - if (d->baseInfo) - return d->baseInfo->entry(name); + if (m_baseInfo) + return m_baseInfo->entry(name); return ItemLibraryEntry(); } QList<ItemLibraryEntry> ItemLibraryInfo::entries() const { - QList<ItemLibraryEntry> list = d->nameToEntryHash.values(); - if (d->baseInfo) - list += d->baseInfo->entries(); + QList<ItemLibraryEntry> list = m_nameToEntryHash.values(); + if (m_baseInfo) + list += m_baseInfo->entries(); return list; } static inline QString keyForEntry(const ItemLibraryEntry &entry) { - return entry.name() + entry.category(); + return entry.name() + entry.category() + QString::number(entry.majorVersion()); } void ItemLibraryInfo::addEntry(const ItemLibraryEntry &entry) { const QString key = keyForEntry(entry); - if (d->nameToEntryHash.contains(key)) + if (m_nameToEntryHash.contains(key)) throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__); - d->nameToEntryHash.insert(key, entry); + m_nameToEntryHash.insert(key, entry); emit entriesChanged(); } @@ -317,18 +324,18 @@ void ItemLibraryInfo::addEntry(const ItemLibraryEntry &entry) bool ItemLibraryInfo::containsEntry(const ItemLibraryEntry &entry) { const QString key = keyForEntry(entry); - return d->nameToEntryHash.contains(key); + return m_nameToEntryHash.contains(key); } void ItemLibraryInfo::clearEntries() { - d->nameToEntryHash.clear(); + m_nameToEntryHash.clear(); emit entriesChanged(); } void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo) { - d->baseInfo = baseInfo; + m_baseInfo = baseInfo; } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp index a40d5747ff..de9b693074 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp @@ -33,12 +33,14 @@ #include "modelnode.h" #include "invalidmodelnodeexception.h" #include "invalidargumentexception.h" -#include "metainfoparser.h" +#include "metainforeader.h" #include "iwidgetplugin.h" #include "pluginmanager/widgetpluginmanager.h" + #include <QDebug> +#include <QMessageBox> #include <QPair> #include <QtAlgorithms> @@ -62,7 +64,7 @@ public: void initialize(); - void parseXmlFiles(); + void parseItemLibraryDescriptions(); QScopedPointer<ItemLibraryInfo> m_itemLibraryInfo; @@ -87,7 +89,7 @@ void MetaInfoPrivate::clear() void MetaInfoPrivate::initialize() { - parseXmlFiles(); + parseItemLibraryDescriptions(); m_isInitialized = true; } @@ -107,15 +109,23 @@ static inline bool isDepricatedQtType(const QString &typeName) return typeName.contains("Qt."); } -void MetaInfoPrivate::parseXmlFiles() +void MetaInfoPrivate::parseItemLibraryDescriptions() { Internal::WidgetPluginManager pluginManager; foreach (const QString &pluginDir, m_q->s_pluginDirs) pluginManager.addPath(pluginDir); QList<IWidgetPlugin *> widgetPluginList = pluginManager.instances(); foreach (IWidgetPlugin *plugin, widgetPluginList) { - Internal::MetaInfoParser parser(*m_q); - parser.parseFile(plugin->metaInfo()); + Internal::MetaInfoReader reader(*m_q); + try { + reader.readMetaInfoFile(plugin->metaInfo()); + } catch (InvalidMetaInfoException &e) { + qWarning() << e.description(); + const QString errorMessage = plugin->metaInfo() + QLatin1Char('\n') + QLatin1Char('\n') + reader.errors().join(QLatin1String("\n")); + QMessageBox::critical(0, + QCoreApplication::translate("QmlDesigner::Internal::MetaInfoPrivate", "Invalid meta info"), + errorMessage); + } } } diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainfoparser.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainfoparser.cpp deleted file mode 100644 index ab6eb6e35c..0000000000 --- a/src/plugins/qmldesigner/designercore/metainfo/metainfoparser.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "metainfoparser.h" -#include "metainfo.h" - -#include <propertyparser.h> -#include <QXmlStreamReader> -#include <QString> -#include <QFile> -#include <QDebug> -#include <QIcon> - -namespace QmlDesigner { -namespace Internal { - - -MetaInfoParser::MetaInfoParser(const MetaInfo &metaInfo) - : m_metaInfo(metaInfo) -{ -} - -void MetaInfoParser::parseFile(const QString &path) -{ - QFile file; - file.setFileName(path); - if (!file.open(QIODevice::ReadOnly)) - throw new InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__); - - QXmlStreamReader reader; - reader.setDevice(&file); - - while (!reader.atEnd()) { - reader.readNext(); - tokenHandler(reader); - } - errorHandling(reader, file); -} - -void MetaInfoParser::tokenHandler(QXmlStreamReader &reader) -{ - if (reader.isStartElement() && reader.name() == "metainfo") - handleMetaInfoElement(reader); -} - -void MetaInfoParser::handleMetaInfoElement(QXmlStreamReader &reader) -{ - while (!reader.atEnd() && !(reader.isEndElement() && reader.name() == "metainfo")) { - reader.readNext(); - metaInfoHandler(reader); - } -} - -void MetaInfoParser::metaInfoHandler(QXmlStreamReader &reader) -{ - if (reader.isStartElement()) - { - if (reader.name() == "node") - handleNodeElement(reader); - } -} - -void MetaInfoParser::handleNodeElement(QXmlStreamReader &reader) -{ - const QXmlStreamAttributes attributes = reader.attributes(); - - const QString className = attributes.value("name").toString(); - const QIcon icon = QIcon(attributes.value("icon").toString()); - - if (className.isEmpty()) { - reader.raiseError("Invalid element 'node' - mandatory attribute 'name' is missing"); - return; - } - - while (!reader.atEnd() && !(reader.isEndElement() && reader.name() == "node")) { - reader.readNext(); - - handleNodeItemLibraryEntryElement(reader, className, icon); - } -} - -void MetaInfoParser::handleNodeItemLibraryEntryElement(QXmlStreamReader &reader, const QString &className, const QIcon &icon) -{ - if (reader.isStartElement() && reader.name() == "itemlibraryentry") - { - const QString versionNumber = reader.attributes().value("version").toString(); - - int major = 1; - int minor = 0; - - if (!versionNumber.isEmpty()) { - int val; - bool ok; - if (versionNumber.contains('.')) { - val = versionNumber.split('.').first().toInt(&ok); - major = ok ? val : major; - val = versionNumber.split('.').last().toInt(&ok); - minor = ok ? val : minor; - } else { - val = versionNumber.toInt(&ok); - major = ok ? val : major; - } - } - - const QString name = reader.attributes().value("name").toString(); - - ItemLibraryEntry entry; - entry.setType(className, major, minor); - entry.setName(name); - entry.setIcon(icon); - - QString iconPath = reader.attributes().value("libraryIcon").toString(); - if (!iconPath.isEmpty()) - entry.setIconPath(iconPath); - - QString category = reader.attributes().value("category").toString(); - if (!category.isEmpty()) - entry.setCategory(category); - - QString requiredImport = reader.attributes().value("requiredImport").toString(); - if (!requiredImport.isEmpty()) - entry.setRequiredImport(requiredImport); - - if (reader.attributes().hasAttribute("forceImport")) { - QString forceImport = reader.attributes().value("forceImport").toString(); - if (forceImport == QLatin1String("true") || forceImport == QLatin1String("True")) - entry.setForceImport(true); - else - entry.setForceImport(false); - } else { - entry.setForceImport(false); - } - - while (!reader.atEnd() && !(reader.isEndElement() && reader.name() == "itemlibraryentry")) { - reader.readNext(); - handleItemLibraryEntryPropertyElement(reader, entry); - handleItemLibraryEntryQmlElement(reader, entry); - } - - m_metaInfo.itemLibraryInfo()->addEntry(entry); - } -} - -void MetaInfoParser::handleItemLibraryEntryPropertyElement(QXmlStreamReader &reader, ItemLibraryEntry &itemLibraryEntry) -{ - if (reader.isStartElement() && reader.name() == "property") - { - QXmlStreamAttributes attributes(reader.attributes()); - QString name = attributes.value("name").toString(); - QString type = attributes.value("type").toString(); - QString value = attributes.value("value").toString(); - itemLibraryEntry.addProperty(name, type, value); - - reader.readNext(); - } -} - -void MetaInfoParser::handleItemLibraryEntryQmlElement(QXmlStreamReader &reader, ItemLibraryEntry &itemLibraryEntry) -{ - if (reader.isStartElement() && reader.name() == "qml") - { - QXmlStreamAttributes attributes(reader.attributes()); - QString source = attributes.value("source").toString(); - itemLibraryEntry.setQml(source); - - reader.readNext(); - } -} - -void MetaInfoParser::errorHandling(QXmlStreamReader &reader, QFile &file) -{ - if (!reader.hasError()) - return; - - qDebug() << QString("Error at %1, %2:%3: %4") - .arg(file.fileName()) - .arg(reader.lineNumber()) - .arg(reader.columnNumber()) - .arg(reader.errorString()); - - file.reset(); - - QString fileString = file.readAll(); - QString snippetString; - int lineCount = 0; - int position = reader.characterOffset(); - while (position >= 0) - { - if (fileString[position] == '\n') { - if (lineCount > 3) - break; - lineCount++; - } - - snippetString.prepend(fileString[position]); - position--; - } - - lineCount = 0; - position = reader.characterOffset(); - while (position >= 0) - { - position++; - if (fileString[position] == '\n') { - if (lineCount > 1) - break; - lineCount++; - } - - snippetString.append(fileString[position]); - } - - qDebug() << snippetString; - -} - - -} -} diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp new file mode 100644 index 0000000000..abdf070244 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp @@ -0,0 +1,314 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "metainforeader.h" +#include "metainfo.h" + +#include <propertyparser.h> +#include <QXmlStreamReader> +#include <QString> +#include <QFile> +#include <QDebug> +#include <QIcon> + +namespace QmlDesigner { +namespace Internal { + +enum { + debug = false +}; + +const char rootElementName[] = "MetaInfo"; +const char typeElementName[] = "Type"; +const char ItemLibraryEntryElementName[] = "ItemLibraryEntry"; +const char QmlSourceElementName[] = "QmlSource"; +const char PropertyElementName[] = "Property"; + +MetaInfoReader::MetaInfoReader(const MetaInfo &metaInfo) + : m_parserState(Undefined), + m_metaInfo(metaInfo) +{ +} + +void MetaInfoReader::readMetaInfoFile(const QString &path) +{ + m_parserState = ParsingDocument; + if (!SimpleAbstractStreamReader::readFile(path)) { + qWarning() << "readMetaInfoFile()" << path; + qWarning() << errors(); + m_parserState = Error; + throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__); + } + + if (!errors().isEmpty()) { + qWarning() << "readMetaInfoFile()" << path; + qWarning() << errors(); + m_parserState = Error; + throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__); + } +} + +QStringList MetaInfoReader::errors() +{ + return QmlJS::SimpleAbstractStreamReader::errors(); +} + +void MetaInfoReader::elementStart(const QString &name) +{ + switch (parserState()) { + case ParsingDocument: setParserState(readDocument(name)); break; + case ParsingMetaInfo: setParserState(readMetaInfoRootElement(name)); break; + case ParsingType: setParserState(readTypeElement(name)); break; + case ParsingItemLibrary: setParserState(readItemLibraryEntryElement(name)); break; + case ParsingProperty: setParserState(readPropertyElement(name)); break; + case ParsingQmlSource: setParserState(readQmlSourceElement(name)); break; + case Finished: + case Undefined: setParserState(Error); + addError(tr("Illegal state while parsing"), currentSourceLocation()); + case Error: + default: return; + } +} + +void MetaInfoReader::elementEnd() +{ + switch (parserState()) { + case ParsingMetaInfo: setParserState(Finished); break; + case ParsingType: setParserState(ParsingMetaInfo); break; + case ParsingItemLibrary: insertItemLibraryEntry(); setParserState((ParsingType)); break; + case ParsingProperty: insertProperty(); setParserState(ParsingItemLibrary); break; + case ParsingQmlSource: setParserState(ParsingItemLibrary); break; + case ParsingDocument: + case Finished: + case Undefined: setParserState(Error); + addError(tr("Illegal state while parsing"), currentSourceLocation()); + case Error: + default: return; + } +} + +void MetaInfoReader::propertyDefinition(const QString &name, const QVariant &value) +{ + switch (parserState()) { + case ParsingType: readTypeProperty(name, value); break; + case ParsingItemLibrary: readItemLibraryEntryProperty(name, value); break; + case ParsingProperty: readPropertyProperty(name, value); break; + case ParsingQmlSource: readQmlSourceProperty(name, value); break; + case ParsingMetaInfo: addError(tr("No property definition allowed"), currentSourceLocation()); break; + case ParsingDocument: + case Finished: + case Undefined: setParserState(Error); + addError(tr("Illegal state while parsing"), currentSourceLocation()); + case Error: + default: return; + } +} + +MetaInfoReader::ParserSate MetaInfoReader::readDocument(const QString &name) +{ + if (name == QLatin1String(rootElementName)) { + m_currentClassName = QString(); + m_currentIcon = QString(); + return ParsingMetaInfo; + } else { + addErrorInvalidType(name); + return Error; + } +} + +MetaInfoReader::ParserSate MetaInfoReader::readMetaInfoRootElement(const QString &name) +{ + if (name == QLatin1String(typeElementName)) { + m_currentClassName = QString(); + m_currentIcon = QString(); + return ParsingType; + } else { + addErrorInvalidType(name); + return Error; + } +} + +MetaInfoReader::ParserSate MetaInfoReader::readTypeElement(const QString &name) +{ + if (name == QLatin1String(ItemLibraryEntryElementName)) { + m_currentEntry = ItemLibraryEntry(); + m_currentEntry.setForceImport(false); + m_currentEntry.setType(m_currentClassName, -1, -1); + m_currentEntry.setIcon(QIcon(m_currentIcon)); + return ParsingItemLibrary; + } else { + addErrorInvalidType(name); + return Error; + } +} + +MetaInfoReader::ParserSate MetaInfoReader::readItemLibraryEntryElement(const QString &name) +{ + if (name == QmlSourceElementName) { + return ParsingQmlSource; + } else if (name == PropertyElementName) { + m_currentPropertyName = QString(); + m_currentPropertyType = QString(); + m_currentPropertyValue = QVariant(); + return ParsingProperty; + } else { + addError(tr("Invalid type %1").arg(name), currentSourceLocation()); + return Error; + } +} + +MetaInfoReader::ParserSate MetaInfoReader::readPropertyElement(const QString &name) +{ + addError(tr("Invalid type %1").arg(name), currentSourceLocation()); + return Error; +} + +MetaInfoReader::ParserSate MetaInfoReader::readQmlSourceElement(const QString &name) +{ + addError(tr("Invalid type %1").arg(name), currentSourceLocation()); + return Error; +} + +void MetaInfoReader::readTypeProperty(const QString &name, const QVariant &value) +{ + if (name == QLatin1String("name")) { + m_currentClassName = value.toString(); + } else if (name == QLatin1String("icon")) { + m_currentIcon = value.toString(); + } else { + addError(tr("Unknown property for Type %1").arg(name), currentSourceLocation()); + setParserState(Error); + } +} + +void MetaInfoReader::readItemLibraryEntryProperty(const QString &name, const QVariant &value) +{ + if (name == QLatin1String("name")) { + m_currentEntry.setName(value.toString()); + } else if (name == QLatin1String("category")) { + m_currentEntry.setCategory(value.toString()); + } else if (name == QLatin1String("libraryIcon")) { + m_currentEntry.setIconPath(value.toString()); + } else if (name == QLatin1String("version")) { + setVersion(value.toString()); + } else if (name == QLatin1String("requiredImport")) { + m_currentEntry.setRequiredImport(value.toString()); + } else if (name == QLatin1String("forceImport")) { + m_currentEntry.setForceImport(value.toBool()); + } else { + addError(tr("Unknown property for ItemLibraryEntry %1").arg(name), currentSourceLocation()); + setParserState(Error); + } +} + +void MetaInfoReader::readPropertyProperty(const QString &name, const QVariant &value) +{ + if (name == QLatin1String("name")) { + m_currentPropertyName = value.toString(); + } else if (name == QLatin1String("type")) { + m_currentPropertyType = value.toString(); + } else if (name == QLatin1String("value")) { + m_currentPropertyValue = value; + } else { + addError(tr("Unknown property for Property %1").arg(name), currentSourceLocation()); + setParserState(Error); + } +} + +void MetaInfoReader::readQmlSourceProperty(const QString &name, const QVariant &value) +{ + if (name == QLatin1String("source")) { + m_currentEntry.setQml(value.toString()); + } else { + addError(tr("Unknown property for QmlSource %1").arg(name), currentSourceLocation()); + setParserState(Error); + } +} + +void MetaInfoReader::setVersion(const QString &versionNumber) +{ + const QString typeName = m_currentEntry.typeName(); + int major = 1; + int minor = 0; + + if (!versionNumber.isEmpty()) { + int val; + bool ok; + if (versionNumber.contains('.')) { + val = versionNumber.split('.').first().toInt(&ok); + major = ok ? val : major; + val = versionNumber.split('.').last().toInt(&ok); + minor = ok ? val : minor; + } else { + val = versionNumber.toInt(&ok); + major = ok ? val : major; + } + } + m_currentEntry.setType(typeName, major, minor); +} + +MetaInfoReader::ParserSate MetaInfoReader::parserState() const +{ + return m_parserState; +} + +void MetaInfoReader::setParserState(ParserSate newParserState) +{ + if (debug && newParserState == Error) + qDebug() << "Error"; + + m_parserState = newParserState; +} + +void MetaInfoReader::insertItemLibraryEntry() +{ + if (debug) { + qDebug() << "insertItemLibraryEntry()"; + qDebug() << m_currentEntry; + } + + try { + m_metaInfo.itemLibraryInfo()->addEntry(m_currentEntry); + } catch (InvalidMetaInfoException &) { + addError(tr("Invalid or duplicate item library entry %1").arg(m_currentEntry.name()), currentSourceLocation()); + } +} + +void MetaInfoReader::insertProperty() +{ + m_currentEntry.addProperty(m_currentPropertyName, m_currentPropertyType, m_currentPropertyValue); +} + +void MetaInfoReader::addErrorInvalidType(const QString &typeName) +{ + addError(tr("Invalid type %1").arg(typeName), currentSourceLocation()); +} + +} //Internal +} //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 72d362dac4..066db88584 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -29,7 +29,6 @@ #include "nodemetainfo.h" #include "model.h" -#include "widgetqueryview.h" #include "invalidargumentexception.h" #include "metainfo.h" @@ -40,9 +39,6 @@ #include <QSharedData> #include <QDebug> #include <QIcon> -#include <QDeclarativeContext> -#include <QDeclarativeEngine> -#include <QDeclarativeComponent> #include <qmljs/qmljsdocument.h> #include <qmljs/qmljscontext.h> @@ -87,16 +83,53 @@ using namespace QmlJS; typedef QPair<QString, QString> PropertyInfo; +static QString resolveTypeName(const ASTPropertyReference *ref, const ContextPtr &context) +{ + QString type = QLatin1String("unknown"); + + if (!ref->ast()->memberType.isEmpty()) { + type = ref->ast()->memberType.toString(); + + if (type == QLatin1String("alias")) { + const Value *value = context->lookupReference(ref); + + if (!value) + return type; + + if (const ASTObjectValue * astObjectValue = value->asAstObjectValue()) { + if (astObjectValue->typeName()) + type = astObjectValue->typeName()->name.toString(); + } else if (const ObjectValue * objectValue = value->asObjectValue()) { + type = objectValue->className(); + } else if (value->asColorValue()) { + type = QLatin1String("color"); + } else if (value->asUrlValue()) { + type = QLatin1String("url"); + } else if (value->asStringValue()) { + type = QLatin1String("string"); + } else if (value->asRealValue()) { + type = QLatin1String("real"); + } else if (value->asIntValue()) { + type = QLatin1String("int"); + } else if (value->asBooleanValue()) { + type = QLatin1String("boolean"); + } + } + } + + return type; +} + class PropertyMemberProcessor : public MemberProcessor { public: + PropertyMemberProcessor(const ContextPtr &context) : m_context(context) + {} virtual bool processProperty(const QString &name, const Value *value) { const ASTPropertyReference *ref = value_cast<ASTPropertyReference>(value); if (ref) { - QString type = "unknown"; - if (!ref->ast()->memberType.isEmpty()) - type = ref->ast()->memberType.toString(); + const QString type = resolveTypeName(ref, m_context); m_properties.append(qMakePair(name, type)); } else { if (const CppComponentValue * ov = value_cast<CppComponentValue>(value)) { @@ -122,6 +155,7 @@ public: private: QList<PropertyInfo> m_properties; + const ContextPtr m_context; }; static inline bool isValueType(const QString &type) @@ -181,7 +215,7 @@ QList<PropertyInfo> getQmlTypes(const CppComponentValue *ov, const ContextPtr &c if (ov->className().isEmpty()) return list; - PropertyMemberProcessor processor; + PropertyMemberProcessor processor(context); ov->processMembers(&processor); QList<PropertyInfo> newList = processor.properties(); @@ -257,7 +291,7 @@ QList<PropertyInfo> getObjectTypes(const ObjectValue *ov, const ContextPtr &cont if (ov->className().isEmpty()) return list; - PropertyMemberProcessor processor; + PropertyMemberProcessor processor(context); ov->processMembers(&processor); list << processor.properties(); @@ -337,7 +371,7 @@ public: Model *model() const { return m_model; } - QString packageName() const; + QString cppPackageName() const; QString componentSource() const; QString componentFileName() const; @@ -440,9 +474,15 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, QString type, int maj, in if (objectValue) { const CppComponentValue *qmlValue = value_cast<CppComponentValue>(objectValue); if (qmlValue) { - m_majorVersion = qmlValue->componentVersion().majorVersion(); - m_minorVersion = qmlValue->componentVersion().minorVersion(); - m_qualfiedTypeName = qmlValue->moduleName() + '.' + qmlValue->className(); + if (m_majorVersion == -1 && m_minorVersion == -1) { + m_majorVersion = qmlValue->componentVersion().majorVersion(); + m_minorVersion = qmlValue->componentVersion().minorVersion(); + m_qualfiedTypeName = qmlValue->moduleName() + '.' + qmlValue->className(); + } else if (m_majorVersion == qmlValue->componentVersion().majorVersion() && m_minorVersion == qmlValue->componentVersion().minorVersion()) { + m_qualfiedTypeName = qmlValue->moduleName() + '.' + qmlValue->className(); + } else { + return; + } } else { m_isComponent = true; } @@ -480,8 +520,12 @@ const QmlJS::CppComponentValue *NodeMetaInfoPrivate::getCppComponentValue() cons if (import.info.path() != module) continue; const Value *lookupResult = import.object->lookupMember(type, context()); - if ((value = value_cast<CppComponentValue>(lookupResult))) - return value; + const CppComponentValue *cppValue = value_cast<CppComponentValue>(lookupResult); + if (cppValue + && (m_majorVersion == -1 || m_majorVersion == cppValue->componentVersion().majorVersion()) + && (m_minorVersion == -1 || m_minorVersion == cppValue->componentVersion().minorVersion()) + ) + return cppValue; } return 0; @@ -672,6 +716,14 @@ QString NodeMetaInfoPrivate::propertyEnumScope(const QString &propertyName) cons return QString(); } +static QString getUnqualifiedName(const QString &name) +{ + const QStringList nameComponents = name.split('.'); + if (nameComponents.size() < 2) + return QString(); + return nameComponents.last(); +} + bool NodeMetaInfoPrivate::cleverCheckType(const QString &otherType) const { if (otherType == qualfiedTypeName()) @@ -687,8 +739,8 @@ bool NodeMetaInfoPrivate::cleverCheckType(const QString &otherType) const package = split.first(); typeName = split.at(1); } - if (packageName() == package) - return QString(package + '.' + typeName) == qualfiedTypeName(); + if (cppPackageName() == package) + return QString(package + '.' + typeName) == cppPackageName() + '.' + getUnqualifiedName(qualfiedTypeName()); const CppComponentValue *qmlObjectValue = getCppComponentValue(); if (!qmlObjectValue) @@ -751,7 +803,7 @@ QStringList NodeMetaInfoPrivate::keysForEnum(const QString &enumName) const return qmlObjectValue->getEnum(enumName).keys(); } -QString NodeMetaInfoPrivate::packageName() const +QString NodeMetaInfoPrivate::cppPackageName() const { if (!isComponent()) { if (const CppComponentValue *qmlObject = getCppComponentValue()) @@ -819,7 +871,7 @@ bool NodeMetaInfoPrivate::isValid() const QString NodeMetaInfoPrivate::propertyType(const QString &propertyName) const { if (!m_properties.contains(propertyName)) - return QString(); + return QLatin1String("Property does not exist..."); return m_propertyTypes.at(m_properties.indexOf(propertyName)); } @@ -1096,4 +1148,11 @@ void NodeMetaInfo::clearCache() Internal::NodeMetaInfoPrivate::clearCache(); } +bool NodeMetaInfo::isPositioner() const +{ + if (majorVersion() < 2) + return isSubclassOf("<cpp>.QDeclarativeBasePositioner", -1, -1); + return isSubclassOf("QtQuick.Positioner", -1, -1); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp index 02c27b7e87..e88f7519b6 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp @@ -31,6 +31,8 @@ #include "model.h" #include "metainfo.h" +#include <utils/hostosinfo.h> + #include <QDir> #include <QMetaType> #include <QUrl> @@ -55,12 +57,8 @@ static inline QStringList importPaths() { // env import paths QByteArray envImportPath = qgetenv("QML_IMPORT_PATH"); if (!envImportPath.isEmpty()) { -#if defined(Q_OS_WIN) - QLatin1Char pathSep(';'); -#else - QLatin1Char pathSep(':'); -#endif - paths = QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts); + paths = QString::fromLatin1(envImportPath) + .split(Utils::HostOsInfo::pathListSeparator(), QString::SkipEmptyParts); } return paths; @@ -79,7 +77,7 @@ SubComponentManager::SubComponentManager(Model *model, QObject *parent) void SubComponentManager::addImport(int pos, const Import &import) { if (debug) - qDebug() << Q_FUNC_INFO << pos << import.file().toAscii(); + qDebug() << Q_FUNC_INFO << pos << import.file().toLatin1(); if (import.isFileImport()) { QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile()); diff --git a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp index a2bc0acada..4b9cb25b9f 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp @@ -42,7 +42,6 @@ #include "nodelistproperty.h" #include <QTextStream> #include <qmlobjectnode.h> -#include <QDeclarativeView> namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/designercore/model/internalnode.cpp index bd37949aef..74323c351a 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnode.cpp @@ -36,7 +36,7 @@ #include "invalidpropertyexception.h" #include <QDebug> -#include <corelib_global.h> +#include <qmldesignercorelib_global.h> namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.h b/src/plugins/qmldesigner/designercore/model/internalproperty.h index e6a6e2002a..8fe2203ce3 100644 --- a/src/plugins/qmldesigner/designercore/model/internalproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalproperty.h @@ -30,7 +30,7 @@ #ifndef INTERNALPROPERTY_H #define INTERNALPROPERTY_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include <QVariant> #include <QString> @@ -55,7 +55,7 @@ class InternalNode; typedef QSharedPointer<InternalNode> InternalNodePointer; typedef QWeakPointer<InternalNode> InternalNodeWeakPointer; -class CORESHARED_EXPORT InternalProperty +class QMLDESIGNERCORE_EXPORT InternalProperty { public: typedef QSharedPointer<InternalProperty> Pointer; diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 261622d4ff..f6f40c9871 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -91,7 +91,7 @@ ModelPrivate::ModelPrivate(Model *model) : m_writeLock(false), m_internalIdCounter(1) { - m_rootInternalNode = createNode("QtQuick/Item", 1, 0, PropertyListType(), PropertyListType(), QString(), ModelNode::NodeWithoutSource,true); + m_rootInternalNode = createNode("QtQuick.Item", 1, 0, PropertyListType(), PropertyListType(), QString(), ModelNode::NodeWithoutSource,true); m_acutalStateNode = m_rootInternalNode; } @@ -107,15 +107,15 @@ void ModelPrivate::detachAllViews() m_viewList.clear(); - if (m_rewriterView) { - m_rewriterView->modelAboutToBeDetached(m_q); - m_rewriterView.clear(); - } - if (m_nodeInstanceView) { m_nodeInstanceView->modelAboutToBeDetached(m_q); m_nodeInstanceView.clear(); } + + if (m_rewriterView) { + m_rewriterView->modelAboutToBeDetached(m_q); + m_rewriterView.clear(); + } } Model *ModelPrivate::create(QString type, int major, int minor, Model *metaInfoPropxyModel) diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index 5a563cb205..b1cfcdc0c8 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -39,7 +39,7 @@ #include "abstractview.h" #include "metainfo.h" -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" QT_BEGIN_NAMESPACE class QPlainTextEdit; diff --git a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp index c3589223ad..14c257c264 100644 --- a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp @@ -42,6 +42,7 @@ #include <QSet> #include <QStringList> +#include <QUrl> #include <QDebug> diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index 3b16155a76..4c5c4f5745 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -248,10 +248,12 @@ int ModelNode::majorQtQuickVersion() const } if (metaInfo().isValid()) { + if (type() == "QtQuick.QtObject") + return majorVersion(); NodeMetaInfo superClass = metaInfo().directSuperClass(); while (superClass.isValid()) { - if (superClass.typeName() == "QtQuick.Item") + if (superClass.typeName() == "QtQuick.QtObject") return superClass.majorVersion(); superClass = superClass.directSuperClass(); } diff --git a/src/plugins/qmldesigner/designercore/model/modeltotextmerger.h b/src/plugins/qmldesigner/designercore/model/modeltotextmerger.h index 0ced918c99..e3779d0b3a 100644 --- a/src/plugins/qmldesigner/designercore/model/modeltotextmerger.h +++ b/src/plugins/qmldesigner/designercore/model/modeltotextmerger.h @@ -30,7 +30,7 @@ #ifndef MODELTOTEXTMERGER_H #define MODELTOTEXTMERGER_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include <modelnode.h> #include "abstractview.h" #include "nodeabstractproperty.h" @@ -46,7 +46,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT RewriterView; +class RewriterView; namespace Internal { diff --git a/src/plugins/qmldesigner/designercore/model/propertycontainer.cpp b/src/plugins/qmldesigner/designercore/model/propertycontainer.cpp index 9c8a4b8ca4..d9f3014304 100644 --- a/src/plugins/qmldesigner/designercore/model/propertycontainer.cpp +++ b/src/plugins/qmldesigner/designercore/model/propertycontainer.cpp @@ -115,6 +115,15 @@ QDataStream &operator>>(QDataStream &stream, PropertyContainer &propertyContaine return stream; } +QDebug operator<<(QDebug debug, const PropertyContainer &propertyContainer) +{ + debug << propertyContainer.m_name; + debug << propertyContainer.m_type; + debug << propertyContainer.m_value; + + return debug.space(); +} + QDataStream &operator<<(QDataStream &stream, const QList<PropertyContainer> &propertyContainerList) { stream << propertyContainerList.count(); @@ -138,6 +147,14 @@ QDataStream &operator>>(QDataStream &stream, QList<PropertyContainer> &propertyC return stream; } +QDebug operator<<(QDebug debug, QList<PropertyContainer> &propertyContainerList) +{ + foreach (const PropertyContainer &propertyContainer, propertyContainerList) + debug << propertyContainer; + + return debug.space(); +} + } //namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/propertyparser.cpp b/src/plugins/qmldesigner/designercore/model/propertyparser.cpp index e29963afa9..934a6c20dd 100644 --- a/src/plugins/qmldesigner/designercore/model/propertyparser.cpp +++ b/src/plugins/qmldesigner/designercore/model/propertyparser.cpp @@ -59,8 +59,8 @@ static uchar fromHex(const uchar c, const uchar c2) static uchar fromHex(const QString &s, int idx) { - uchar c = s.at(idx).toAscii(); - uchar c2 = s.at(idx + 1).toAscii(); + uchar c = s.at(idx).toLatin1(); + uchar c2 = s.at(idx + 1).toLatin1(); return fromHex(c, c2); } @@ -191,7 +191,7 @@ QVariant read(const QString &typeStr, const QString &str, const MetaInfo &) QVariant read(const QString &typeStr, const QString &str) { - int type = QMetaType::type(typeStr.toAscii().constData()); + int type = QMetaType::type(typeStr.toLatin1().constData()); if (type == 0) { qWarning() << "Type " << typeStr << " is unknown to QMetaType system. Cannot create properly typed QVariant for value " diff --git a/src/plugins/qmldesigner/designercore/model/qmlchangeset.cpp b/src/plugins/qmldesigner/designercore/model/qmlchangeset.cpp index 08f3917607..dd69cc85a4 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlchangeset.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlchangeset.cpp @@ -56,7 +56,9 @@ bool QmlPropertyChanges::isValid() const bool QmlModelStateOperation::isValid() const { - return QmlModelNodeFacade::isValid() && modelNode().metaInfo().isSubclassOf("<cpp>.QDeclarativeStateOperation", -1, -1); + return QmlModelNodeFacade::isValid() && ( + modelNode().metaInfo().isSubclassOf("<cpp>.QDeclarative1StateOperation", -1, -1) + || modelNode().metaInfo().isSubclassOf("<cpp>.QDeclarativeStateOperation", -1, -1)); } void QmlPropertyChanges::removeProperty(const QString &name) diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index 12edc2012b..bdfb27c2bb 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -29,7 +29,6 @@ #include "qmlitemnode.h" #include <metainfo.h> -#include <QDeclarativeView> #include "qmlchangeset.h" #include "variantproperty.h" #include "nodeproperty.h" @@ -328,7 +327,7 @@ QmlModelState QmlModelStateGroup::addState(const QString &name) PropertyListType propertyList; propertyList.append(qMakePair(QString("name"), QVariant(name))); - ModelNode newState = modelNode().view()->createModelNode("QtQuick.State", 1, 0, propertyList); + ModelNode newState = QmlObjectNode(modelNode()).qmlModelView()->createQmlState(propertyList); modelNode().nodeListProperty("states").reparentHere(newState); return newState; diff --git a/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp b/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp index c993335281..86002b5ece 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp @@ -45,8 +45,8 @@ #include "rewriterview.h" #include "plaintexteditmodifier.h" #include "modelmerger.h" -#include "modelnodecontextmenu.h" +#include <utils/qtcassert.h> namespace QmlDesigner { @@ -424,13 +424,6 @@ void QmlModelView::nodeSourceChanged(const ModelNode &, const QString & /*newNod } -void QmlModelView::showContextMenu(const QPoint &globalPos, const QPoint &scenePos, bool showSelection) -{ - ModelNodeContextMenu contextMenu(this); - contextMenu.setScenePos(scenePos); - contextMenu.execute(globalPos, showSelection); -} - void QmlModelView::rewriterBeginTransaction() { @@ -473,5 +466,17 @@ void QmlModelView::otherPropertyChanged(const QmlObjectNode &/*qmlObjectNode*/, { } +ModelNode QmlModelView::createQmlState(const QmlDesigner::PropertyListType &propertyList) +{ + + QTC_CHECK(rootModelNode().majorQtQuickVersion() < 3); + + if (rootModelNode().majorQtQuickVersion() > 1) { + return createModelNode("QtQuick.State", 2, 0, propertyList); + } else { + return createModelNode("QtQuick.State", 1, 0, propertyList); + } +} + } //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qmlstate.cpp b/src/plugins/qmldesigner/designercore/model/qmlstate.cpp index a1b87fc02e..623c6c23ac 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlstate.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlstate.cpp @@ -177,7 +177,13 @@ void QmlModelState::addChangeSetIfNotExists(const ModelNode &node) return; //changeSet already there } - ModelNode newChangeSet = modelNode().view()->createModelNode("QtQuick.PropertyChanges", 1, 0); + ModelNode newChangeSet; + if (qmlModelView()->rootModelNode().majorQtQuickVersion() > 1) { + newChangeSet = modelNode().view()->createModelNode("QtQuick.PropertyChanges", 2, 0); + } else { + newChangeSet = modelNode().view()->createModelNode("QtQuick.PropertyChanges", 1, 0); + } + modelNode().nodeListProperty("changes").reparentHere(newChangeSet); QmlPropertyChanges(newChangeSet).setTarget(node); @@ -244,7 +250,7 @@ bool QmlModelState::isValid() const { return QmlModelNodeFacade::isValid() && modelNode().metaInfo().isValid() && - (modelNode().metaInfo().isSubclassOf("QtQuick.State", 1, 0) || isBaseState()); + (modelNode().metaInfo().isSubclassOf("QtQuick.State", -1, -1) || isBaseState()); } /** @@ -278,7 +284,7 @@ QmlModelState QmlModelState::duplicate(const QString &name) const // QmlModelState newState(stateGroup().addState(name)); PropertyListType propertyList; propertyList.append(qMakePair(QString("name"), QVariant(name))); - QmlModelState newState ( qmlModelView()->createModelNode("QtQuick.State", 1, 0, propertyList) ); + QmlModelState newState ( qmlModelView()->createQmlState(propertyList) ); foreach (const ModelNode &childNode, modelNode().nodeListProperty("changes").toModelNodeList()) { ModelNode newModelNode(qmlModelView()->createModelNode(childNode.type(), childNode.majorVersion(), childNode.minorVersion())); diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp index be42f2151c..c331365a85 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp @@ -54,8 +54,12 @@ inline static QString properColorName(const QColor &color) inline static QString doubleToString(double d) { QString string = QString::number(d, 'f', 3); - if (string.endsWith(".000")) - string.chop(4); + if (string.contains(QLatin1Char('.'))) { + while (string.at(string.length()- 1) == QLatin1Char('0')) + string.chop(1); + if (string.at(string.length()- 1) == QLatin1Char('.')) + string.chop(1); + } return string; } diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index ffa98fa6ed..9c43b3aa0f 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -493,6 +493,8 @@ void RewriterView::applyChanges() throw RewritingException(__LINE__, __FUNCTION__, __FILE__, "RewriterView::applyChanges() already in error state", content); } + m_differenceHandling = Validate; + try { modelToTextMerger()->applyChanges(); if (!errors().isEmpty()) { @@ -505,6 +507,8 @@ void RewriterView::applyChanges() enterErrorState(e.description()); } + m_differenceHandling = Amend; + if (inErrorState()) { const QString content = textModifierContent(); qDebug() << "RewriterException:" << m_rewritingErrorMessage; diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index ae7947eeb6..e60d4173d4 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -32,6 +32,7 @@ #include "filemanager/firstdefinitionfinder.h" #include "filemanager/objectlengthcalculator.h" #include "filemanager/qmlrefactoring.h" +#include "filemanager/qmlwarningdialog.h" #include "rewriteaction.h" #include "nodeproperty.h" #include "propertyparser.h" @@ -66,7 +67,7 @@ namespace { static inline QStringList supportedVersionsList() { QStringList list; - list << QLatin1String("1.0") << QLatin1String("1.1"); + list << QLatin1String("1.0") << QLatin1String("1.1") << QLatin1String("2.0"); return list; } @@ -139,27 +140,6 @@ static inline QString fixEscapedUnicodeChar(const QString &value) //convert "\u2 return value; } -static inline int fixUpMajorVersionForQt(const QString &value, int i) -{ - if (i == 4 && value == "Qt") - return 1; - else return i; -} - -static inline int fixUpMinorVersionForQt(const QString &value, int i) -{ - if (i == 7 && value == "Qt") - return 0; - else return i; -} - -static inline QString fixUpPackeNameForQt(const QString &value) -{ - if (value == "Qt") - return "QtQuick"; - return value; -} - static inline bool isSignalPropertyName(const QString &signalName) { // see QmlCompiler::isSignalPropertyName @@ -357,11 +337,10 @@ public: const CppComponentValue * qmlValue = value_cast<CppComponentValue>(value); if (qmlValue) { - typeName = fixUpPackeNameForQt(qmlValue->moduleName()) + QLatin1String(".") + qmlValue->className(); + typeName = qmlValue->moduleName() + QLatin1String(".") + qmlValue->className(); - //### todo this is just a hack to support QtQuick 1.0 - majorVersion = fixUpMajorVersionForQt(qmlValue->moduleName(), qmlValue->componentVersion().majorVersion()); - minorVersion = fixUpMinorVersionForQt(qmlValue->moduleName(), qmlValue->componentVersion().minorVersion()); + majorVersion = qmlValue->componentVersion().majorVersion(); + minorVersion = qmlValue->componentVersion().minorVersion(); } else { for (UiQualifiedId *iter = astTypeNode; iter; iter = iter->next) if (!iter->next && !iter->name.isEmpty()) @@ -550,20 +529,26 @@ public: } } - QVariant v(cleanedValue); + if (property->asColorValue()) { + return PropertyParser::read(QVariant::Color, cleanedValue); + } else if (property->asUrlValue()) { + return PropertyParser::read(QVariant::Url, cleanedValue); + } + + QVariant value(cleanedValue); if (property->asBooleanValue()) { - v.convert(QVariant::Bool); - } else if (property->asColorValue()) { - v.convert(QVariant::Color); + value.convert(QVariant::Bool); + return value; } else if (property->asNumberValue()) { - v.convert(QVariant::Double); + value.convert(QVariant::Double); + return value; } else if (property->asStringValue()) { // nothing to do } else { //property alias et al if (!hasQuotes) return cleverConvert(cleanedValue); } - return v; + return value; } QVariant convertToEnum(Statement *rhs, const QString &propertyPrefix, UiQualifiedId *propertyId) @@ -762,6 +747,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH m_document = doc; QList<RewriterView::Error> errors; + QList<RewriterView::Error> warnings; foreach (const QmlJS::DiagnosticMessage &diagnosticMessage, ctxt.diagnosticLinkMessages()) { errors.append(RewriterView::Error(diagnosticMessage, QUrl::fromLocalFile(doc->fileName()))); @@ -788,9 +774,26 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH check.disableMessage(StaticAnalysis::ErrPrototypeCycle); check.disableMessage(StaticAnalysis::ErrCouldNotResolvePrototype); check.disableMessage(StaticAnalysis::ErrCouldNotResolvePrototypeOf); + + foreach (StaticAnalysis::Type type, StaticAnalysis::Message::allMessageTypes()) { + StaticAnalysis::Message message(type, AST::SourceLocation()); + if (message.severity == StaticAnalysis::MaybeWarning + || message.severity == StaticAnalysis::Warning) { + check.disableMessage(type); + } + } + + check.enableMessage(StaticAnalysis::WarnImperativeCodeNotEditableInVisualDesigner); + check.enableMessage(StaticAnalysis::WarnUnsupportedTypeInVisualDesigner); + check.enableMessage(StaticAnalysis::WarnReferenceToParentItemNotSupportedByVisualDesigner); + check.enableMessage(StaticAnalysis::WarnUndefinedValueForVisualDesigner); + check.enableMessage(StaticAnalysis::WarnStatesOnlyInRootItemForVisualDesigner); + foreach (const StaticAnalysis::Message &message, check()) { if (message.severity == StaticAnalysis::Error) errors.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName()))); + if (message.severity == StaticAnalysis::Warning) + warnings.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName()))); } if (!errors.isEmpty()) { @@ -798,6 +801,27 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH setActive(false); return false; } + + if (!warnings.isEmpty() && differenceHandler.isValidator()) { + + QString title = QCoreApplication::translate("QmlDesigner::TextToModelMerger warning message", "This .qml file contains features" + "which are not supported by Qt Quick Designer"); + + QStringList message; + + foreach (const RewriterView::Error &warning, warnings) { + QString string = QLatin1String("Line: ") + QString::number(warning.line()) + QLatin1String(": ") + warning.description(); + //string += QLatin1String(" <a href=\"") + QString::number(warning.line()) + QLatin1String("\">Go to error</a>") + QLatin1String("<p>"); + message << string; + } + + QmlWarningDialog warningDialog(0, message); + if (warningDialog.warningsEnabled() && warningDialog.exec()) { + m_rewriterView->setErrors(warnings); + setActive(false); + return false; + } + } } UiObjectMember *astRootNode = 0; diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h index 1de76d88a6..76d4fe6ba1 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h @@ -30,7 +30,7 @@ #ifndef TEXTTOMODELMERGER_H #define TEXTTOMODELMERGER_H -#include "corelib_global.h" +#include "qmldesignercorelib_global.h" #include "import.h" #include "nodelistproperty.h" #include "modelnode.h" @@ -43,7 +43,7 @@ namespace QmlDesigner { -class CORESHARED_EXPORT RewriterView; +class RewriterView; namespace Internal { diff --git a/src/plugins/qmldesigner/designercore/model/viewlogger.cpp b/src/plugins/qmldesigner/designercore/model/viewlogger.cpp index 19d6f3ea4f..e225b5aae0 100644 --- a/src/plugins/qmldesigner/designercore/model/viewlogger.cpp +++ b/src/plugins/qmldesigner/designercore/model/viewlogger.cpp @@ -31,6 +31,7 @@ #include <QDebug> #include <QTemporaryFile> #include <QDir> +#include <QUrl> #include <variantproperty.h> #include <bindingproperty.h> #include <nodeabstractproperty.h> diff --git a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.cpp b/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.cpp index 47acad9d72..5ef5a980b0 100644 --- a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.cpp +++ b/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.cpp @@ -28,7 +28,6 @@ ****************************************************************************/ #include "widgetpluginmanager.h" -#include "widgetpluginpath.h" #include <iwidgetplugin.h> #include <QCoreApplication> @@ -51,28 +50,15 @@ namespace QmlDesigner { namespace Internal { -// ---- PluginManager[Private] -class WidgetPluginManagerPrivate { -public: - typedef QList<WidgetPluginPath> PluginPathList; - PluginPathList m_paths; -}; - -WidgetPluginManager::WidgetPluginManager() : - d(new WidgetPluginManagerPrivate) -{ -} - -WidgetPluginManager::~WidgetPluginManager() +WidgetPluginManager::WidgetPluginManager() { - delete d; } WidgetPluginManager::IWidgetPluginList WidgetPluginManager::instances() { IWidgetPluginList rc; - const WidgetPluginManagerPrivate::PluginPathList::iterator end = d->m_paths.end(); - for (WidgetPluginManagerPrivate::PluginPathList::iterator it = d->m_paths.begin(); it != end; ++it) + const PluginPathList::iterator end = m_paths.end(); + for (PluginPathList::iterator it = m_paths.begin(); it != end; ++it) it->getInstances(&rc); if (debug) qDebug() << '<' << Q_FUNC_INFO << rc.size(); @@ -84,15 +70,15 @@ bool WidgetPluginManager::addPath(const QString &path) const QDir dir(path); if (!dir.exists()) return false; - d->m_paths.push_back(WidgetPluginPath(dir)); + m_paths.push_back(WidgetPluginPath(dir)); return true; } QAbstractItemModel *WidgetPluginManager::createModel(QObject *parent) { QStandardItemModel *model = new QStandardItemModel(parent); - const WidgetPluginManagerPrivate::PluginPathList::iterator end = d->m_paths.end(); - for (WidgetPluginManagerPrivate::PluginPathList::iterator it = d->m_paths.begin(); it != end; ++it) + const PluginPathList::iterator end = m_paths.end(); + for (PluginPathList::iterator it = m_paths.begin(); it != end; ++it) model->appendRow(it->createModelItem()); return model; } diff --git a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.h b/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.h index 2e7ceb75e0..fe1fa66161 100644 --- a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.h +++ b/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.h @@ -33,6 +33,9 @@ #include <QObject> #include <QList> +#include "widgetpluginpath.h" + + QT_BEGIN_NAMESPACE class QString; class QAbstractItemModel; @@ -44,8 +47,6 @@ class IWidgetPlugin; namespace Internal { -class WidgetPluginManagerPrivate; - // PluginManager: Loads the plugin libraries on demand "as lazy as // possible", that is, directories are scanned and // instances are created only when instances() is called. @@ -53,11 +54,11 @@ class WidgetPluginManagerPrivate; class WidgetPluginManager { Q_DISABLE_COPY(WidgetPluginManager) + typedef QList<WidgetPluginPath> PluginPathList; public: typedef QList<IWidgetPlugin *> IWidgetPluginList; WidgetPluginManager(); - ~WidgetPluginManager(); bool addPath(const QString &path); @@ -68,7 +69,7 @@ public: QAbstractItemModel *createModel(QObject *parent = 0); private: - WidgetPluginManagerPrivate *d; + PluginPathList m_paths; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.cpp b/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.cpp index d150e983e7..dd09e3fd69 100644 --- a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.cpp +++ b/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.cpp @@ -172,7 +172,7 @@ void WidgetPluginPath::ensureLoaded() } } -void WidgetPluginPath::getInstances(WidgetPluginManager::IWidgetPluginList *list) +void WidgetPluginPath::getInstances(IWidgetPluginList *list) { ensureLoaded(); // Compile list of instances diff --git a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.h b/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.h index 2e61bee02b..292eb5c1c5 100644 --- a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.h +++ b/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.h @@ -30,8 +30,6 @@ #ifndef WIDGETPLUGINPATH_H #define WIDGETPLUGINPATH_H -#include "widgetpluginmanager.h" - #include <QObject> #include <QWeakPointer> #include <QList> @@ -73,11 +71,12 @@ struct WidgetPluginData { // IPlugins. class WidgetPluginPath { + typedef QList<IWidgetPlugin *> IWidgetPluginList; public: explicit WidgetPluginPath(const QDir &path); - void getInstances(WidgetPluginManager::IWidgetPluginList *list); + void getInstances(IWidgetPluginList *list); QDir path() const { return m_path; } diff --git a/src/plugins/qmldesigner/designersettings.cpp b/src/plugins/qmldesigner/designersettings.cpp index 27867b1c7f..31ddb46568 100644 --- a/src/plugins/qmldesigner/designersettings.cpp +++ b/src/plugins/qmldesigner/designersettings.cpp @@ -39,7 +39,9 @@ DesignerSettings::DesignerSettings() itemSpacing(0), snapMargin(0), canvasWidth(10000), - canvasHeight(10000) + canvasHeight(10000), + warningsInDesigner(true), + designerWarningsInEditor(false) {} void DesignerSettings::fromSettings(QSettings *settings) @@ -55,6 +57,11 @@ void DesignerSettings::fromSettings(QSettings *settings) QLatin1String(QmlDesigner::Constants::QML_SNAPMARGIN_KEY), QVariant(0)).toInt(); canvasWidth = settings->value(QLatin1String(QmlDesigner::Constants::QML_CANVASWIDTH_KEY), QVariant(10000)).toInt(); canvasHeight = settings->value(QLatin1String(QmlDesigner::Constants::QML_CANVASHEIGHT_KEY), QVariant(10000)).toInt(); + warningsInDesigner = settings->value( + QLatin1String(QmlDesigner::Constants::QML_WARNIN_FOR_FEATURES_IN_DESIGNER_KEY), QVariant(true)).toBool(); + designerWarningsInEditor = settings->value( + QLatin1String(QmlDesigner::Constants::QML_WARNIN_FOR_DESIGNER_FEATURES_IN_EDITOR_KEY), QVariant(false)).toBool(); + settings->endGroup(); settings->endGroup(); } @@ -68,6 +75,9 @@ void DesignerSettings::toSettings(QSettings *settings) const settings->setValue(QLatin1String(QmlDesigner::Constants::QML_SNAPMARGIN_KEY), snapMargin); settings->setValue(QLatin1String(QmlDesigner::Constants::QML_CANVASWIDTH_KEY), canvasWidth); settings->setValue(QLatin1String(QmlDesigner::Constants::QML_CANVASHEIGHT_KEY), canvasHeight); + settings->setValue(QLatin1String(QmlDesigner::Constants::QML_WARNIN_FOR_FEATURES_IN_DESIGNER_KEY), warningsInDesigner); + settings->setValue(QLatin1String(QmlDesigner::Constants::QML_WARNIN_FOR_DESIGNER_FEATURES_IN_EDITOR_KEY), designerWarningsInEditor); + settings->endGroup(); settings->endGroup(); } @@ -77,5 +87,7 @@ bool DesignerSettings::equals(const DesignerSettings &other) const return openDesignMode == other.openDesignMode && snapMargin == other.snapMargin && canvasWidth == other.canvasWidth - && canvasHeight == other.canvasHeight; + && canvasHeight == other.canvasHeight + && warningsInDesigner == other.warningsInDesigner + && designerWarningsInEditor == other.designerWarningsInEditor; } diff --git a/src/plugins/qmldesigner/designersettings.h b/src/plugins/qmldesigner/designersettings.h index 9c1ad43c6b..07d4290f16 100644 --- a/src/plugins/qmldesigner/designersettings.h +++ b/src/plugins/qmldesigner/designersettings.h @@ -52,6 +52,8 @@ public: int snapMargin; int canvasWidth; int canvasHeight; + bool warningsInDesigner; + bool designerWarningsInEditor; }; inline bool operator==(const DesignerSettings &s1, const DesignerSettings &s2) diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index 2736a3aabe..14c746198a 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -35,8 +35,6 @@ #include <utils/faketooltip.h> #include <texteditor/itexteditor.h> -#include <integrationcore.h> - #include <designdocumentcontroller.h> #include <itemlibraryview.h> #include <navigatorwidget.h> diff --git a/src/plugins/qmldesigner/desktopplugin/desktop.metainfo b/src/plugins/qmldesigner/desktopplugin/desktop.metainfo index 07f4a5aed0..da774b58f0 100644 --- a/src/plugins/qmldesigner/desktopplugin/desktop.metainfo +++ b/src/plugins/qmldesigner/desktopplugin/desktop.metainfo @@ -1,139 +1,383 @@ -<metainfo> - <node name="QtDesktop.Button" icon=":/desktopplugin/images/button16.png"> - <itemlibraryentry name="Button" category="Components Desktop" libraryIcon=":/desktopplugin/images/button.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="100"/> - <property name="text" type="QString" value="Button"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.ComboBox" icon=":/desktopplugin/images/button16.png"> - <itemlibraryentry name="ComboBox" category="Components Desktop" libraryIcon=":/desktopplugin/images/button.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="100"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.ToolButton" icon=":/desktopplugin/images/button16.png"> - <itemlibraryentry name="ToolButton" category="Components Desktop" libraryIcon=":/desktopplugin/images/button.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="100"/> - <property name="text" type="QString" value="Button"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.CheckBox" icon=":/desktopplugin/images/checkbox16.png"> - <itemlibraryentry name="CheckBox" category="Components Desktop" libraryIcon=":/desktopplugin/images/checkbox.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="180"/> - <property name="text" type="QString" value="CheckBox"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.ChoiceList" icon=":/desktopplugin/images/choicelist16.png"> - <itemlibraryentry name="ChoiceList" category="Components Desktop" libraryIcon=":/desktopplugin/images/choicelist.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="180"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.ProgressBar" icon=":/desktopplugin/images/progressbar16.png"> - <itemlibraryentry name="ProgressBar" category="Components Desktop" libraryIcon=":/desktopplugin/images/progressbar.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="100"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.SpinBox"> - <itemlibraryentry name="SpinBox" category="Components Desktop" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="100"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.Dial"> - <itemlibraryentry name="Dial" category="Components Desktop" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="100"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.SplitterRow"> - <itemlibraryentry name="SplitterRow" category="Components Desktop" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="200"/> - <property name="height" type="int" value="200"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.RadioButton" icon=":/desktopplugin/images/radiobutton16.png"> - <itemlibraryentry name="RadioButton" category="Components Desktop" libraryIcon=":/desktopplugin/images/radiobutton.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="180"/> - <property name="text" type="QString" value="RadioButton"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.TextArea" icon=":/desktopplugin/images/textarea16.png"> - <itemlibraryentry name="TextArea" category="Components Desktop" libraryIcon=":/desktopplugin/images/textarea.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="180"/> - <property name="height" type="int" value="180"/> - <property name="text" type="QString" value="TextArea"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.ButtonRow" icon=":/desktopplugin/images/buttonrow16.png"> - <itemlibraryentry name="ButtonRow" category="Components Desktop" libraryIcon=":/desktopplugin/images/buttonrow.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="120"/> - <property name="height" type="int" value="20"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.TabBar" icon=":/desktopplugin/images/tabbar16.png"> - <itemlibraryentry name="TabBar" category="Components Desktop" libraryIcon=":/desktopplugin/images/tabbar.png" version="0.1" requiredImport="QtDesktop"> - </itemlibraryentry> - </node> - <node name="QtDesktop.Slider" icon=":/desktopplugin/images/slider16.png"> - <itemlibraryentry name="Slider (horizontal)" category="Components Desktop" libraryIcon=":/desktopplugin/images/slider.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="180"/> - <property name="orientation" type="int" value="1"/> - </itemlibraryentry> - <itemlibraryentry name="Slider (vertical)" category="Components Desktop" libraryIcon=":/desktopplugin/images/sliderh.png" version="0.1" requiredImport="QtDesktop"> - <property name="height" type="int" value="180"/> - <property name="orientation" type="int" value="2"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.ScrollBar"> - <itemlibraryentry name="ScrollBar (horizontal)" category="Components Desktop" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="180"/> - <property name="orientation" type="int" value="1"/> - </itemlibraryentry> - <itemlibraryentry name="ScrollBar (vertical)" category="Components Desktop" version="0.1" requiredImport="QtDesktop"> - <property name="height" type="int" value="180"/> - <property name="orientation" type="int" value="2"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.TabFrame" icon=":/desktopplugin//images/window16.png"> - <itemlibraryentry name="TabGroup" category="Components Desktop" libraryIcon=":/desktopplugin/images/window.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="360"/> - <property name="height" type="int" value="40"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.ScrollArea"> - <itemlibraryentry name="ScrollArea" category="Components Desktop" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="300"/> - <property name="height" type="int" value="300"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.GroupBox"> - <itemlibraryentry name="GroupBox" category="Components Desktop" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="300"/> - <property name="height" type="int" value="300"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.Frame"> - <itemlibraryentry name="Frame" category="Components Desktop" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="300"/> - <property name="height" type="int" value="300"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.ToolBar" icon=":/desktopplugin/images/toolbar16.png"> - <itemlibraryentry name="ToolBar" category="Components Desktop" libraryIcon=":/desktopplugin/images/toolbar.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="300"/> - <property name="height" type="int" value="50"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.Switch" icon=":/desktopplugin/images/switchbutton16.png"> - <itemlibraryentry name="Switch" category="Components Desktop" libraryIcon=":/desktopplugin/images/switchbutton.png" version="0.1" requiredImport="QtDesktop"> - </itemlibraryentry> - </node> - <node name="QtDesktop.TextField" icon=":/desktopplugin/images/textfield16.png"> - <itemlibraryentry name="TextField" category="Components Desktop" libraryIcon=":/desktopplugin/images/textfield.png" version="0.1" requiredImport="QtDesktop"> - <property name="width" type="int" value="180"/> - <property name="text" type="QString" value="TextField"/> - </itemlibraryentry> - </node> - <node name="QtDesktop.Label" icon=":/desktopplugin/images/window16.png.png"> - <itemlibraryentry name="Label" category="Components Desktop" libraryIcon=":/desktopplugin/images/window.png" version="0.1" requiredImport="QtDesktop"> - <property name="text" type="QString" value="Label"/> - </itemlibraryentry> - </node> -</metainfo> +MetaInfo { + + Type { + name: "QtDesktop.Button" + icon: ":/desktopplugin/images/button16.png" + + ItemLibraryEntry { + name: "Button" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/button.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "text"; type: "QString"; value: "Button"; } + } + } + + Type { + name: "QtDesktop.ComboBox" + icon: ":/desktopplugin/images/button16.png" + + ItemLibraryEntry { + name: "ComboBox" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/button.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 100; } + } + } + + Type { + name: "QtDesktop.ToolButton" + icon: ":/desktopplugin/images/button16.png" + + ItemLibraryEntry { + name: "Tool Button" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/button.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "text"; type: "QString"; value: "Tool Button"; } + } + } + + Type { + name: "QtDesktop.CheckBox" + icon: ":/desktopplugin/images/button16.png" + + ItemLibraryEntry { + name: "Check Box" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/button.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "text"; type: "QString"; value: "CheckBox"; } + } + } + + Type { + name: "QtDesktop.ChoiceList" + icon: ":/desktopplugin/images/choicelist16.png" + + ItemLibraryEntry { + name: "Choice List" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/choicelist.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 180; } + } + } + + Type { + name: "QtDesktop.ProgressBar" + icon: ":/desktopplugin/images/progressbar16.png" + + ItemLibraryEntry { + name: "Progress Bar" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/progressbar.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 100; } + } + } + + Type { + name: "QtDesktop.SpinBox" + icon: ":/desktopplugin/images/progressbar16.png" + + ItemLibraryEntry { + name: "Spin Box" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/progressbar.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 100; } + } + } + + Type { + name: "QtDesktop.Dial" + //icon: ":/desktopplugin/images/progressbar16.png" + + ItemLibraryEntry { + name: "Dial" + category: "Components Desktop" + //libraryIcon: ":/desktopplugin/images/progressbar.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 100; } + } + } + + Type { + name: "QtDesktop.RadioButton" + icon: ":/desktopplugin/images/radiobutton16.png" + + ItemLibraryEntry { + name: "Radio Button" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/radiobutton.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 180; } + Property { name: "text"; type: "QString"; value: "Radio Button"; } + } + } + + Type { + name: "QtDesktop.TextArea" + icon: ":/desktopplugin/images/textarea16.png" + + ItemLibraryEntry { + name: "Text Area" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/textarea.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 180; } + Property { name: "height"; type: "int"; value: 180; } + Property { name: "text"; type: "QString"; value: "Text Area"; } + } + } + + Type { + name: "QtDesktop.ButtonRow" + icon: ":/desktopplugin/images/buttonrow16.png" + + ItemLibraryEntry { + name: "Button Row" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/buttonrow.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 120; } + Property { name: "height"; type: "int"; value: 120; } + } + } + + Type { + name: "QtDesktop.SplitterRow" + icon: ":/desktopplugin/images/buttonrow16.png" + + ItemLibraryEntry { + name: "Splitter Row" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/buttonrow.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 020; } + } + } + + Type { + name: "QtDesktop.TabBar" + icon: ":/desktopplugin/images/tabbar16.png" + + ItemLibraryEntry { + name: "Tab Bar" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/tabbar.png" + version: "0.1" + requiredImport: "QtDesktop" + } + } + + Type { + name: "QtDesktop.Slider" + icon: ":/desktopplugin/images/slider16.png" + + ItemLibraryEntry { + name: "Slider (horizontal)" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/slider.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 180; } + Property { name: "orientation"; type: "int"; value: "1"; } + + } + + ItemLibraryEntry { + name: "Slider (vertical)" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/sliderh.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "height"; type: "int"; value: 180; } + Property { name: "orientation"; type: "int"; value: "2"; } + } + } + + Type { + name: "QtDesktop.ScrollBar" + icon: ":/desktopplugin/images/slider16.png" + + ItemLibraryEntry { + name: "ScrollBar (horizontal)" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/slider.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 180; } + Property { name: "orientation"; type: "int"; value: "1"; } + + } + + ItemLibraryEntry { + name: "ScrollBar (vertical)" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/sliderh.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "height"; type: "int"; value: 180; } + Property { name: "orientation"; type: "int"; value: "2"; } + } + } + + Type { + name: "QtDesktop.TabFrame" + icon: ":/desktopplugin//images/window16.png" + + ItemLibraryEntry { + name: "Tab Frame" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/window.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 360; } + Property { name: "height"; type: "int"; value: 200; } + } + } + + Type { + name: "QtDesktop.ScrollArea" + icon: ":/desktopplugin//images/window16.png" + + ItemLibraryEntry { + name: "Scroll Area" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/window.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 360; } + Property { name: "height"; type: "int"; value: 300; } + } + } + + Type { + name: "QtDesktop.GroupBox" + icon: ":/desktopplugin//images/window16.png" + + ItemLibraryEntry { + name: "Group Box" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/window.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 360; } + Property { name: "height"; type: "int"; value: 300; } + } + } + + Type { + name: "QtDesktop.Frame" + icon: ":/desktopplugin//images/window16.png" + + ItemLibraryEntry { + name: "Frame" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/window.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 360; } + Property { name: "height"; type: "int"; value: 300; } + } + } + + Type { + name: "QtDesktop.ToolBar" + icon: ":/desktopplugin/images/toolbar16.png" + + ItemLibraryEntry { + name: "Tool Bar" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/toolbar.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 360; } + Property { name: "height"; type: "int"; value: 50; } + } + } + + Type { + name: "QtDesktop.Switch" + icon: ":/desktopplugin/images/switchbutton16.png" + + ItemLibraryEntry { + name: "Switch" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/switchbutton.png" + version: "0.1" + requiredImport: "QtDesktop" + } + } + + Type { + name: "QtDesktop.TextField" + icon: ":/desktopplugin/images/textfield16.png" + + ItemLibraryEntry { + name: "Text Field" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/textfield.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "width"; type: "int"; value: 180; } + Property { name: "text"; type: "QString"; value: "Text Field"; } + } + } + + Type { + name: "QtDesktop.Label" + icon: ":/desktopplugin/images/window16.png.png" + + ItemLibraryEntry { + name: "Label" + category: "Components Desktop" + libraryIcon: ":/desktopplugin/images/window.png" + version: "0.1" + requiredImport: "QtDesktop" + + Property { name: "text"; type: "QString"; value: "Text Field"; } + } + } +} diff --git a/src/plugins/qmldesigner/extrasplugin/extras.metainfo b/src/plugins/qmldesigner/extrasplugin/extras.metainfo deleted file mode 100644 index d074cefe05..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/extras.metainfo +++ /dev/null @@ -1,54 +0,0 @@ -<metainfo> - <node name="CountBubble" icon=":/extrasplugin/images/count-bubble-16.png"> - <itemlibraryentry name="CountBubble" category="Components Extras" libraryIcon=":/extrasplugin/images/count-bubble-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="DatePickerDialog" icon=":/extrasplugin/images/date-picker-16.png"> - <itemlibraryentry name="DatePickerDialog" category="Components Extras" libraryIcon=":/extrasplugin/images/date-picker-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="InfoBanner" icon=":/extrasplugin/images/info-banner-16.png"> - <itemlibraryentry name="InfoBanner" category="Components Extras" libraryIcon=":/extrasplugin/images/info-banner-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="ListButton" icon=":/extrasplugin/images/list-button-16.png"> - <itemlibraryentry name="ListButton" category="Components Extras" libraryIcon=":/extrasplugin/images/list-button-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="ListDelegate" icon=":/extrasplugin/images/list-delegate-16.png"> - <itemlibraryentry name="ListDelegate" category="Components Extras" libraryIcon=":/extrasplugin/images/list-delegate-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="MoreIndicator" icon=":/extrasplugin/images/more-indicator-16.png"> - <itemlibraryentry name="MoreIndicator" category="Components Extras" libraryIcon=":/extrasplugin/images/more-indicator-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="PageIndicator" icon=":/extrasplugin/images/page-indicator-16.png"> - <itemlibraryentry name="PageIndicator" category="Components Extras" libraryIcon=":/extrasplugin/images/page-indicator-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="RatingIndicator" icon=":/extrasplugin/images/rating-indicator-16.png"> - <itemlibraryentry name="RatingIndicator" category="Components Extras" libraryIcon=":/extrasplugin/images/rating-indicator-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="TimePickerDialog" icon=":/extrasplugin/images/time-picker-16.png"> - <itemlibraryentry name="TimePickerDialog" category="Components Extras" libraryIcon=":/extrasplugin/images/time-picker-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="Tumbler" icon=":/extrasplugin/images/tumbler-16.png"> - <itemlibraryentry name="Tumbler" category="Components Extras" libraryIcon=":/extrasplugin/images/tumbler-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="TumblerButton" icon=":/extrasplugin/images/tumbler-button-16.png"> - <itemlibraryentry name="TumblerButton" category="Components Extras" libraryIcon=":/extrasplugin/images/tumbler-button-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="TumblerColumn" icon=":/extrasplugin/images/tumbler-column-16.png"> - <itemlibraryentry name="TumblerColumn" category="Components Extras" libraryIcon=":/extrasplugin/images/tumbler-column-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> - <node name="TumblerDialog" icon=":/extrasplugin/images/tumbler-dialog-16.png"> - <itemlibraryentry name="TumblerDialog" category="Components Extras" libraryIcon=":/extrasplugin/images/tumbler-dialog-24.png" version="1.0" requiredImport="com.nokia.extras"> - </itemlibraryentry> - </node> -</metainfo> diff --git a/src/plugins/qmldesigner/extrasplugin/extrasplugin.json b/src/plugins/qmldesigner/extrasplugin/extrasplugin.json deleted file mode 100644 index 62ea9d2cfb..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/extrasplugin.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - - -"Vendor" : "Digia Plc", - - - - -"Category" : "Qt Quick", - - -"Description" : "Plugin for Extra Items.", - - -"Url" : "http://www.qt-project.org" - - - -} diff --git a/src/plugins/qmldesigner/extrasplugin/extrasplugin.pri b/src/plugins/qmldesigner/extrasplugin/extrasplugin.pri deleted file mode 100644 index f7967d7769..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/extrasplugin.pri +++ /dev/null @@ -1,13 +0,0 @@ -TARGET = extrasplugin -TEMPLATE = lib -CONFIG += plugin - -include (../designercore/iwidgetplugin.pri) - -SOURCES += $$PWD/extrasplugin.cpp - -HEADERS += $$PWD/extrasplugin.h $$PWD/../designercore/include/iwidgetplugin.h - -RESOURCES += $$PWD/extrasplugin.qrc - -OTHER_FILES += $$PWD/extras.metainfo diff --git a/src/plugins/qmldesigner/extrasplugin/extrasplugin.pro b/src/plugins/qmldesigner/extrasplugin/extrasplugin.pro deleted file mode 100644 index af910266b4..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/extrasplugin.pro +++ /dev/null @@ -1,4 +0,0 @@ -include(../../../../qtcreator.pri) -include(../../../private_headers.pri) -include(extrasplugin.pri) -include(../plugindestdir.pri) diff --git a/src/plugins/qmldesigner/extrasplugin/extrasplugin.qrc b/src/plugins/qmldesigner/extrasplugin/extrasplugin.qrc deleted file mode 100644 index ae97ba05e9..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/extrasplugin.qrc +++ /dev/null @@ -1,31 +0,0 @@ -<RCC> - <qresource prefix="/extrasplugin"> - <file>extras.metainfo</file> - <file>images/count-bubble-16.png</file> - <file>images/count-bubble-24.png</file> - <file>images/date-picker-16.png</file> - <file>images/date-picker-24.png</file> - <file>images/info-banner-16.png</file> - <file>images/info-banner-24.png</file> - <file>images/list-button-16.png</file> - <file>images/list-button-24.png</file> - <file>images/list-delegate-16.png</file> - <file>images/list-delegate-24.png</file> - <file>images/more-indicator-16.png</file> - <file>images/more-indicator-24.png</file> - <file>images/page-indicator-16.png</file> - <file>images/page-indicator-24.png</file> - <file>images/rating-indicator-16.png</file> - <file>images/rating-indicator-24.png</file> - <file>images/time-picker-16.png</file> - <file>images/time-picker-24.png</file> - <file>images/tumbler-16.png</file> - <file>images/tumbler-24.png</file> - <file>images/tumbler-button-16.png</file> - <file>images/tumbler-button-24.png</file> - <file>images/tumbler-column-16.png</file> - <file>images/tumbler-column-24.png</file> - <file>images/tumbler-dialog-16.png</file> - <file>images/tumbler-dialog-24.png</file> - </qresource> -</RCC> diff --git a/src/plugins/qmldesigner/extrasplugin/images/count-bubble-16.png b/src/plugins/qmldesigner/extrasplugin/images/count-bubble-16.png Binary files differdeleted file mode 100644 index 2ac1430602..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/count-bubble-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/count-bubble-24.png b/src/plugins/qmldesigner/extrasplugin/images/count-bubble-24.png Binary files differdeleted file mode 100644 index ba444822d5..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/count-bubble-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/date-picker-16.png b/src/plugins/qmldesigner/extrasplugin/images/date-picker-16.png Binary files differdeleted file mode 100644 index b8eb95b737..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/date-picker-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/date-picker-24.png b/src/plugins/qmldesigner/extrasplugin/images/date-picker-24.png Binary files differdeleted file mode 100644 index a8ee7e0847..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/date-picker-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/info-banner-16.png b/src/plugins/qmldesigner/extrasplugin/images/info-banner-16.png Binary files differdeleted file mode 100644 index 379413808b..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/info-banner-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/info-banner-24.png b/src/plugins/qmldesigner/extrasplugin/images/info-banner-24.png Binary files differdeleted file mode 100644 index bf8aa614d0..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/info-banner-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/list-button-16.png b/src/plugins/qmldesigner/extrasplugin/images/list-button-16.png Binary files differdeleted file mode 100644 index 2b1ce900b8..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/list-button-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/list-button-24.png b/src/plugins/qmldesigner/extrasplugin/images/list-button-24.png Binary files differdeleted file mode 100644 index d432090f9c..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/list-button-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/list-delegate-16.png b/src/plugins/qmldesigner/extrasplugin/images/list-delegate-16.png Binary files differdeleted file mode 100644 index 3c97433f08..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/list-delegate-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/list-delegate-24.png b/src/plugins/qmldesigner/extrasplugin/images/list-delegate-24.png Binary files differdeleted file mode 100644 index c4d9886920..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/list-delegate-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/more-indicator-16.png b/src/plugins/qmldesigner/extrasplugin/images/more-indicator-16.png Binary files differdeleted file mode 100644 index 81eff7306c..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/more-indicator-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/more-indicator-24.png b/src/plugins/qmldesigner/extrasplugin/images/more-indicator-24.png Binary files differdeleted file mode 100644 index f5d8dedbfb..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/more-indicator-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/page-indicator-16.png b/src/plugins/qmldesigner/extrasplugin/images/page-indicator-16.png Binary files differdeleted file mode 100644 index 29a8933751..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/page-indicator-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/page-indicator-24.png b/src/plugins/qmldesigner/extrasplugin/images/page-indicator-24.png Binary files differdeleted file mode 100644 index 60dda334fc..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/page-indicator-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/rating-indicator-16.png b/src/plugins/qmldesigner/extrasplugin/images/rating-indicator-16.png Binary files differdeleted file mode 100644 index 2df5418a84..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/rating-indicator-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/rating-indicator-24.png b/src/plugins/qmldesigner/extrasplugin/images/rating-indicator-24.png Binary files differdeleted file mode 100644 index 393b2ffa69..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/rating-indicator-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/time-picker-16.png b/src/plugins/qmldesigner/extrasplugin/images/time-picker-16.png Binary files differdeleted file mode 100644 index 1ee49cafbd..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/time-picker-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/time-picker-24.png b/src/plugins/qmldesigner/extrasplugin/images/time-picker-24.png Binary files differdeleted file mode 100644 index 979981bd31..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/time-picker-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/tumbler-16.png b/src/plugins/qmldesigner/extrasplugin/images/tumbler-16.png Binary files differdeleted file mode 100644 index afcf864744..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/tumbler-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/tumbler-24.png b/src/plugins/qmldesigner/extrasplugin/images/tumbler-24.png Binary files differdeleted file mode 100644 index 43783e6ee2..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/tumbler-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/tumbler-button-16.png b/src/plugins/qmldesigner/extrasplugin/images/tumbler-button-16.png Binary files differdeleted file mode 100644 index 4368493c3e..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/tumbler-button-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/tumbler-button-24.png b/src/plugins/qmldesigner/extrasplugin/images/tumbler-button-24.png Binary files differdeleted file mode 100644 index 6b0b71a65a..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/tumbler-button-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/tumbler-column-16.png b/src/plugins/qmldesigner/extrasplugin/images/tumbler-column-16.png Binary files differdeleted file mode 100644 index 36e2d27608..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/tumbler-column-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/tumbler-column-24.png b/src/plugins/qmldesigner/extrasplugin/images/tumbler-column-24.png Binary files differdeleted file mode 100644 index 8a043798f1..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/tumbler-column-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/tumbler-dialog-16.png b/src/plugins/qmldesigner/extrasplugin/images/tumbler-dialog-16.png Binary files differdeleted file mode 100644 index 5a105a76db..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/tumbler-dialog-16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/extrasplugin/images/tumbler-dialog-24.png b/src/plugins/qmldesigner/extrasplugin/images/tumbler-dialog-24.png Binary files differdeleted file mode 100644 index a6bbc2d795..0000000000 --- a/src/plugins/qmldesigner/extrasplugin/images/tumbler-dialog-24.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/Untitled-2.png b/src/plugins/qmldesigner/meegoplugin/images/Untitled-2.png Binary files differdeleted file mode 100644 index 2e0bf73a26..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/Untitled-2.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/busyindicator.png b/src/plugins/qmldesigner/meegoplugin/images/busyindicator.png Binary files differdeleted file mode 100644 index 89d0283f26..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/busyindicator.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/busyindicator16.png b/src/plugins/qmldesigner/meegoplugin/images/busyindicator16.png Binary files differdeleted file mode 100644 index 7e3b2d3158..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/busyindicator16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/busyindicatora.png b/src/plugins/qmldesigner/meegoplugin/images/busyindicatora.png Binary files differdeleted file mode 100644 index 433f4d426b..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/busyindicatora.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/busyindicatora16.png b/src/plugins/qmldesigner/meegoplugin/images/busyindicatora16.png Binary files differdeleted file mode 100644 index 82de5b0a1b..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/busyindicatora16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/button.png b/src/plugins/qmldesigner/meegoplugin/images/button.png Binary files differdeleted file mode 100644 index 828af210ac..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/button.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/button16.png b/src/plugins/qmldesigner/meegoplugin/images/button16.png Binary files differdeleted file mode 100644 index 8d95760b27..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/button16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/buttoncolumn.png b/src/plugins/qmldesigner/meegoplugin/images/buttoncolumn.png Binary files differdeleted file mode 100644 index 46db8f6ab5..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/buttoncolumn.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/buttoncolumn16.png b/src/plugins/qmldesigner/meegoplugin/images/buttoncolumn16.png Binary files differdeleted file mode 100644 index 883258048f..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/buttoncolumn16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/buttonrow.png b/src/plugins/qmldesigner/meegoplugin/images/buttonrow.png Binary files differdeleted file mode 100644 index 9727749de9..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/buttonrow.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/buttonrow16.png b/src/plugins/qmldesigner/meegoplugin/images/buttonrow16.png Binary files differdeleted file mode 100644 index 420de41860..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/buttonrow16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/checkbox.png b/src/plugins/qmldesigner/meegoplugin/images/checkbox.png Binary files differdeleted file mode 100644 index 0f4a826f4d..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/checkbox.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/checkbox16.png b/src/plugins/qmldesigner/meegoplugin/images/checkbox16.png Binary files differdeleted file mode 100644 index 01f09e3515..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/checkbox16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/choicelist.png b/src/plugins/qmldesigner/meegoplugin/images/choicelist.png Binary files differdeleted file mode 100644 index 3fd9876ada..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/choicelist.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/choicelist16.png b/src/plugins/qmldesigner/meegoplugin/images/choicelist16.png Binary files differdeleted file mode 100644 index 602b28229e..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/choicelist16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/item-icon.png b/src/plugins/qmldesigner/meegoplugin/images/item-icon.png Binary files differdeleted file mode 100644 index fc53d38ae7..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/item-icon.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/item-icon16.png b/src/plugins/qmldesigner/meegoplugin/images/item-icon16.png Binary files differdeleted file mode 100644 index 7d2d7a5050..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/item-icon16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/label.png b/src/plugins/qmldesigner/meegoplugin/images/label.png Binary files differdeleted file mode 100644 index e622f68687..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/label.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/label16.png b/src/plugins/qmldesigner/meegoplugin/images/label16.png Binary files differdeleted file mode 100644 index 0478d429f6..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/label16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/lineedit.png b/src/plugins/qmldesigner/meegoplugin/images/lineedit.png Binary files differdeleted file mode 100644 index f521cd513e..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/lineedit.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/lineedit16.png b/src/plugins/qmldesigner/meegoplugin/images/lineedit16.png Binary files differdeleted file mode 100644 index 549803910d..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/lineedit16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/progressbar.png b/src/plugins/qmldesigner/meegoplugin/images/progressbar.png Binary files differdeleted file mode 100644 index 040f5bac03..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/progressbar.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/progressbar16.png b/src/plugins/qmldesigner/meegoplugin/images/progressbar16.png Binary files differdeleted file mode 100644 index e2432475d5..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/progressbar16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/radiobutton.png b/src/plugins/qmldesigner/meegoplugin/images/radiobutton.png Binary files differdeleted file mode 100644 index 143b6a99f4..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/radiobutton.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/radiobutton16.png b/src/plugins/qmldesigner/meegoplugin/images/radiobutton16.png Binary files differdeleted file mode 100644 index 94912c2034..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/radiobutton16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/slider.png b/src/plugins/qmldesigner/meegoplugin/images/slider.png Binary files differdeleted file mode 100644 index 746ed51932..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/slider.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/slider16.png b/src/plugins/qmldesigner/meegoplugin/images/slider16.png Binary files differdeleted file mode 100644 index 10c4928b3c..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/slider16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/sliderh.png b/src/plugins/qmldesigner/meegoplugin/images/sliderh.png Binary files differdeleted file mode 100644 index 87cd55678f..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/sliderh.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/sliderh16.png b/src/plugins/qmldesigner/meegoplugin/images/sliderh16.png Binary files differdeleted file mode 100644 index c419911336..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/sliderh16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/switchbutton.png b/src/plugins/qmldesigner/meegoplugin/images/switchbutton.png Binary files differdeleted file mode 100644 index 48bf247cb8..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/switchbutton.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/switchbutton16.png b/src/plugins/qmldesigner/meegoplugin/images/switchbutton16.png Binary files differdeleted file mode 100644 index 238a1be632..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/switchbutton16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/tabbutton.png b/src/plugins/qmldesigner/meegoplugin/images/tabbutton.png Binary files differdeleted file mode 100644 index d9f5fdb3f9..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/tabbutton.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/tabbutton16.png b/src/plugins/qmldesigner/meegoplugin/images/tabbutton16.png Binary files differdeleted file mode 100644 index 8e279cff65..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/tabbutton16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/textarea.png b/src/plugins/qmldesigner/meegoplugin/images/textarea.png Binary files differdeleted file mode 100644 index 86f2969d00..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/textarea.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/textarea16.png b/src/plugins/qmldesigner/meegoplugin/images/textarea16.png Binary files differdeleted file mode 100644 index 899a4bca2e..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/textarea16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/textfield.png b/src/plugins/qmldesigner/meegoplugin/images/textfield.png Binary files differdeleted file mode 100644 index b0f13da50d..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/textfield.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/textfield16.png b/src/plugins/qmldesigner/meegoplugin/images/textfield16.png Binary files differdeleted file mode 100644 index 7feb8c7158..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/textfield16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/toolbar.png b/src/plugins/qmldesigner/meegoplugin/images/toolbar.png Binary files differdeleted file mode 100644 index e67c042422..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/toolbar.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/toolbar16.png b/src/plugins/qmldesigner/meegoplugin/images/toolbar16.png Binary files differdeleted file mode 100644 index f4a0c5ef69..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/toolbar16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/window.png b/src/plugins/qmldesigner/meegoplugin/images/window.png Binary files differdeleted file mode 100644 index fc53d38ae7..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/window.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/images/window16.png b/src/plugins/qmldesigner/meegoplugin/images/window16.png Binary files differdeleted file mode 100644 index 7d2d7a5050..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/images/window16.png +++ /dev/null diff --git a/src/plugins/qmldesigner/meegoplugin/meego.metainfo b/src/plugins/qmldesigner/meegoplugin/meego.metainfo deleted file mode 100644 index 8f5a6d6bf2..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/meego.metainfo +++ /dev/null @@ -1,110 +0,0 @@ -<metainfo> - <node name="com.nokia.meego.Label" icon=":/meegoplugin/images/label16.png"> - <itemlibraryentry name="Label" category="Components MeeGo" libraryIcon=":/meegoplugin/images/label.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="text" type="QString" value="Label"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.BusyIndicator" icon=":/meegoplugin/images/busyindicator16.png"> - <itemlibraryentry name="BusyIndicator" category="Components MeeGo" libraryIcon=":/meegoplugin/images/busyindicator.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="180"/> - <property name="height" type="int" value="30"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.Button" icon=":/meegoplugin/images/button16.png"> - <itemlibraryentry name="Button" category="Components MeeGo" libraryIcon=":/meegoplugin/images/button.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.ToolButton" icon=":/meegoplugin/images/button16.png"> - <itemlibraryentry name="ToolButton" category="Components MeeGo" libraryIcon=":/meegoplugin/images/button.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.TabButton" icon=":/meegoplugin/images/tabbutton16.png"> - <itemlibraryentry name="TabButton" category="Components MeeGo" libraryIcon=":/meegoplugin/images/tabbutton.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.SheetButton" icon=":/meegoplugin/images/button16.png"> - <itemlibraryentry name="SheetButton" category="Components MeeGo" libraryIcon=":/meegoplugin/images/button.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.Slider" icon=":/meegoplugin/images/slider16.png"> - <itemlibraryentry name="Slider" category="Components MeeGo" libraryIcon=":/meegoplugin/images/slider.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.CheckBox" icon=":/meegoplugin/images/checkbox16.png"> - <itemlibraryentry name="CheckBox" category="Components MeeGo" libraryIcon=":/meegoplugin/images/checkbox.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.RadioButton" icon=":/meegoplugin/images/radiobutton16.png"> - <itemlibraryentry name="RadioButton" category="Components MeeGo" libraryIcon=":/meegoplugin/images/radiobutton.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.Spinner" icon=":/meegoplugin/images/item-icon16.png"> - <itemlibraryentry name="Spinner" category="Components MeeGo" libraryIcon=":/meegoplugin/images/item-icon.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.TextField" icon=":/meegoplugin/images/textfield16.png"> - <itemlibraryentry name="TextField" category="Components MeeGo" libraryIcon=":/meegoplugin/images/textfield.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.ProgressBar" icon=":/meegoplugin/images/progressbar16.png"> - <itemlibraryentry name="ProgressBar" category="Components MeeGo" libraryIcon=":/meegoplugin/images/progressbar.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.Switch" icon=":/meegoplugin/images/switchbutton16.png"> - <itemlibraryentry name="Switch" category="Components MeeGo" libraryIcon=":/meegoplugin/images/switchbutton.png" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.ToolItem"> - <itemlibraryentry name="ToolItem" category="Components MeeGo" version="1.0" requiredImport="com.nokia.meego"> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.TextArea" icon=":/meegoplugin/images/textarea16.png"> - <itemlibraryentry name="TextArea" category="Components MeeGo" libraryIcon=":/meegoplugin/images/textarea.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="100"/> - <property name="text" type="QString" value="TextArea"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.Window" icon=":/meegoplugin/images/window16.png"> - <itemlibraryentry name="Window" category="Components MeeGo" libraryIcon=":/meegoplugin/images/window.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="360"/> - <property name="height" type="int" value="640"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.Page" icon=":/meegoplugin/images/window16.png"> - <itemlibraryentry name="Page" category="Components MeeGo" libraryIcon=":/meegoplugin/images/window.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="360"/> - <property name="height" type="int" value="640"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.Sheet" icon=":/meegoplugin/images/window16.png"> - <itemlibraryentry name="Sheet" category="Components MeeGo" libraryIcon=":/meegoplugin/images/window.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="360"/> - <property name="height" type="int" value="640"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.ToolBar" icon=":/meegoplugin/images/toolbar16.png"> - <itemlibraryentry name="ToolBar" category="Components MeeGo" libraryIcon=":/meegoplugin/images/toolbar.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="360"/> - <property name="height" type="int" value="140"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.ButtonColumn" icon=":/meegoplugin/images/buttoncolumn16.png"> - <itemlibraryentry name="ButtonColumn" category="Components MeeGo" libraryIcon=":/meegoplugin/images/buttoncolumn.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="100"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.ButtonRow" icon=":/meegoplugin/images/buttonrow16.png"> - <itemlibraryentry name=" ButtonRow" category="Components MeeGo" libraryIcon=":/meegoplugin/images/buttonrow.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="100"/> - </itemlibraryentry> - </node> - <node name="com.nokia.meego.ToolButtonRow" icon=":/meegoplugin/images/window16.png"> - <itemlibraryentry name=" ToolButtonRow" category="Components MeeGo" libraryIcon=":/meegoplugin/images/window.png" version="1.0" requiredImport="com.nokia.meego"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="100"/> - </itemlibraryentry> - </node> -</metainfo> diff --git a/src/plugins/qmldesigner/meegoplugin/meegoplugin.json b/src/plugins/qmldesigner/meegoplugin/meegoplugin.json deleted file mode 100644 index c9f0944388..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/meegoplugin.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - - -"Vendor" : "Digia Plc", - - - - -"Category" : "Qt Quick", - - -"Description" : "Plugin for Meego Items.", - - -"Url" : "http://www.qt-project.org" - - - -} diff --git a/src/plugins/qmldesigner/meegoplugin/meegoplugin.pri b/src/plugins/qmldesigner/meegoplugin/meegoplugin.pri deleted file mode 100644 index 99e5519579..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/meegoplugin.pri +++ /dev/null @@ -1,13 +0,0 @@ -TARGET = meegoplugin -TEMPLATE = lib -CONFIG += plugin - -include (../designercore/iwidgetplugin.pri) - -SOURCES += $$PWD/meegoplugin.cpp - -HEADERS += $$PWD/meegoplugin.h $$PWD/../designercore/include/iwidgetplugin.h - -RESOURCES += $$PWD/meegoplugin.qrc - -OTHER_FILES += $$PWD/meego.metainfo diff --git a/src/plugins/qmldesigner/meegoplugin/meegoplugin.pro b/src/plugins/qmldesigner/meegoplugin/meegoplugin.pro deleted file mode 100644 index c7cfce0689..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/meegoplugin.pro +++ /dev/null @@ -1,4 +0,0 @@ -include(../../../../qtcreator.pri) -include(../../../private_headers.pri) -include(meegoplugin.pri) -include(../plugindestdir.pri) diff --git a/src/plugins/qmldesigner/meegoplugin/meegoplugin.qrc b/src/plugins/qmldesigner/meegoplugin/meegoplugin.qrc deleted file mode 100644 index 34752a2fba..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/meegoplugin.qrc +++ /dev/null @@ -1,45 +0,0 @@ -<RCC> - <qresource prefix="/meegoplugin"> - <file>meego.metainfo</file> - <file>images/button.png</file> - <file>images/button16.png</file> - <file>images/checkbox.png</file> - <file>images/checkbox16.png</file> - <file>images/radiobutton.png</file> - <file>images/radiobutton16.png</file> - <file>images/window.png</file> - <file>images/window16.png</file> - <file>images/busyindicator.png</file> - <file>images/busyindicator16.png</file> - <file>images/busyindicatora.png</file> - <file>images/busyindicatora16.png</file> - <file>images/buttoncolumn.png</file> - <file>images/buttoncolumn16.png</file> - <file>images/buttonrow.png</file> - <file>images/buttonrow16.png</file> - <file>images/choicelist.png</file> - <file>images/choicelist16.png</file> - <file>images/item-icon.png</file> - <file>images/item-icon16.png</file> - <file>images/label.png</file> - <file>images/label16.png</file> - <file>images/lineedit.png</file> - <file>images/lineedit16.png</file> - <file>images/progressbar.png</file> - <file>images/progressbar16.png</file> - <file>images/slider.png</file> - <file>images/slider16.png</file> - <file>images/sliderh.png</file> - <file>images/sliderh16.png</file> - <file>images/switchbutton.png</file> - <file>images/switchbutton16.png</file> - <file>images/tabbutton.png</file> - <file>images/tabbutton16.png</file> - <file>images/textarea.png</file> - <file>images/textarea16.png</file> - <file>images/textfield.png</file> - <file>images/textfield16.png</file> - <file>images/toolbar.png</file> - <file>images/toolbar16.png</file> - </qresource> -</RCC> diff --git a/src/plugins/qmldesigner/meegoplugin/qtquickplugin.json b/src/plugins/qmldesigner/meegoplugin/qtquickplugin.json deleted file mode 100644 index 97bcd69622..0000000000 --- a/src/plugins/qmldesigner/meegoplugin/qtquickplugin.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - - -"Vendor" : "Digia Plc", - - - - -"Category" : "Qt Quick", - - -"Description" : "Plugin for Qt Quick Items.", - - -"Url" : "http://www.qt-project.org" - - - -} diff --git a/src/plugins/qmldesigner/qmldesigner.pro b/src/plugins/qmldesigner/qmldesigner.pro index 35d3d36990..d8ef6fd563 100644 --- a/src/plugins/qmldesigner/qmldesigner.pro +++ b/src/plugins/qmldesigner/qmldesigner.pro @@ -1,3 +1,3 @@ TEMPLATE = subdirs -SUBDIRS = qmldesignerplugin.pro qtquickplugin meegoplugin extrasplugin desktopplugin customstyleplugin +SUBDIRS = qmldesignerplugin.pro qtquickplugin desktopplugin diff --git a/src/plugins/qmldesigner/qmldesigner.qbs b/src/plugins/qmldesigner/qmldesigner.qbs index 2db903d19d..1063d5f424 100644 --- a/src/plugins/qmldesigner/qmldesigner.qbs +++ b/src/plugins/qmldesigner/qmldesigner.qbs @@ -20,440 +20,458 @@ QtcPlugin { Depends { name: "QtSupport" } Depends { name: "cpp" } - cpp.defines: base.concat(project.additionalCppDefines.concat(["QWEAKPOINTER_ENABLE_ARROW"])) - cpp.includePaths: [ - ".", + cpp.defines: base.concat(["QWEAKPOINTER_ENABLE_ARROW"]) + cpp.includePaths: base.concat([ "designercore", "designercore/include", "../../../share/qtcreator/qml/qmlpuppet/interfaces", "../../../share/qtcreator/qml/qmlpuppet/container", "../../../share/qtcreator/qml/qmlpuppet/commands", + "components/componentcore", "components/integration", "components/propertyeditor", "components/formeditor", "components/itemlibrary", "components/navigator", "components/pluginmanager", - "components/stateseditor", - "..", - "../../libs", - buildDirectory - ] + "components/stateseditor" + ]) + + Group { + prefix: "designercore/filemanager/" + files: [ + "addarraymembervisitor.cpp", + "addarraymembervisitor.h", + "addobjectvisitor.cpp", + "addobjectvisitor.h", + "addpropertyvisitor.cpp", + "addpropertyvisitor.h", + "astobjecttextextractor.cpp", + "astobjecttextextractor.h", + "changeimportsvisitor.cpp", + "changeimportsvisitor.h", + "changeobjecttypevisitor.cpp", + "changeobjecttypevisitor.h", + "changepropertyvisitor.cpp", + "changepropertyvisitor.h", + "firstdefinitionfinder.cpp", + "firstdefinitionfinder.h", + "moveobjectbeforeobjectvisitor.cpp", + "moveobjectbeforeobjectvisitor.h", + "moveobjectvisitor.cpp", + "moveobjectvisitor.h", + "objectlengthcalculator.cpp", + "objectlengthcalculator.h", + "qmlrefactoring.cpp", + "qmlrefactoring.h", + "qmlrewriter.cpp", + "qmlrewriter.h", + "removepropertyvisitor.cpp", + "removepropertyvisitor.h", + "removeuiobjectmembervisitor.cpp", + "removeuiobjectmembervisitor.h", + ] + } + + Group { + prefix: "../../../share/qtcreator/qml/qmlpuppet/" + files: [ + "commands/changeauxiliarycommand.cpp", + "commands/changeauxiliarycommand.h", + "commands/changebindingscommand.cpp", + "commands/changebindingscommand.h", + "commands/changefileurlcommand.cpp", + "commands/changefileurlcommand.h", + "commands/changeidscommand.cpp", + "commands/changeidscommand.h", + "commands/changenodesourcecommand.cpp", + "commands/changenodesourcecommand.h", + "commands/changestatecommand.cpp", + "commands/changestatecommand.h", + "commands/changevaluescommand.cpp", + "commands/changevaluescommand.h", + "commands/childrenchangedcommand.cpp", + "commands/childrenchangedcommand.h", + "commands/clearscenecommand.cpp", + "commands/clearscenecommand.h", + "commands/completecomponentcommand.cpp", + "commands/completecomponentcommand.h", + "commands/componentcompletedcommand.cpp", + "commands/componentcompletedcommand.h", + "commands/createinstancescommand.cpp", + "commands/createinstancescommand.h", + "commands/createscenecommand.cpp", + "commands/createscenecommand.h", + "commands/informationchangedcommand.cpp", + "commands/informationchangedcommand.h", + "commands/pixmapchangedcommand.cpp", + "commands/pixmapchangedcommand.h", + "commands/removeinstancescommand.cpp", + "commands/removeinstancescommand.h", + "commands/removepropertiescommand.cpp", + "commands/removepropertiescommand.h", + "commands/reparentinstancescommand.cpp", + "commands/reparentinstancescommand.h", + "commands/statepreviewimagechangedcommand.cpp", + "commands/statepreviewimagechangedcommand.h", + "commands/synchronizecommand.cpp", + "commands/synchronizecommand.h", + "commands/tokencommand.cpp", + "commands/tokencommand.h", + "commands/valueschangedcommand.cpp", + "commands/valueschangedcommand.h", + "container/addimportcontainer.cpp", + "container/addimportcontainer.h", + "container/idcontainer.cpp", + "container/idcontainer.h", + "container/imagecontainer.cpp", + "container/imagecontainer.h", + "container/informationcontainer.cpp", + "container/informationcontainer.h", + "container/instancecontainer.cpp", + "container/instancecontainer.h", + "container/propertyabstractcontainer.cpp", + "container/propertyabstractcontainer.h", + "container/propertybindingcontainer.cpp", + "container/propertybindingcontainer.h", + "container/propertyvaluecontainer.cpp", + "container/propertyvaluecontainer.h", + "container/reparentcontainer.cpp", + "container/reparentcontainer.h", + "interfaces/commondefines.h", + "interfaces/nodeinstanceclientinterface.h", + "interfaces/nodeinstanceserverinterface.cpp", + "interfaces/nodeinstanceserverinterface.h", + ] + } + + Group { + prefix: "designercore/" + files: [ + "rewritertransaction.cpp", + "rewritertransaction.h", + "exceptions/exception.cpp", + "exceptions/invalidargumentexception.cpp", + "exceptions/invalididexception.cpp", + "exceptions/invalidmetainfoexception.cpp", + "exceptions/invalidmodelnodeexception.cpp", + "exceptions/invalidmodelstateexception.cpp", + "exceptions/invalidpropertyexception.cpp", + "exceptions/invalidqmlsourceexception.cpp", + "exceptions/invalidreparentingexception.cpp", + "exceptions/invalidslideindexexception.cpp", + "exceptions/notimplementedexception.cpp", + "exceptions/removebasestateexception.cpp", + "exceptions/rewritingexception.cpp", + "include/abstractproperty.h", + "include/abstractview.h", + "include/basetexteditmodifier.h", + "include/basetexteditmodifier.h", + "include/bindingproperty.h", + "include/componenttextmodifier.h", + "include/corelib_global.h", + "include/customnotifications.h", + "include/exception.h", + "include/forwardview.h", + "include/import.h", + "include/invalidargumentexception.h", + "include/invalididexception.h", + "include/invalidmetainfoexception.h", + "include/invalidmodelstateexception.h", + "include/invalidpropertyexception.h", + "include/invalidqmlsourceexception.h", + "include/invalidreparentingexception.h", + "include/invalidslideindexexception.h", + "include/itemlibraryinfo.h", + "include/mathutils.h", + "include/metainfo.h", + "include/metainfoparser.h", + "include/model.h", + "include/modelmerger.h", + "include/modelnode.h", + "include/modelnodepositionstorage.h", + "include/nodeabstractproperty.h", + "include/nodeinstance.h", + "include/nodeinstanceview.h", + "include/nodelistproperty.h", + "include/nodemetainfo.h", + "include/nodeproperty.h", + "include/notimplementedexception.h", + "include/plaintexteditmodifier.h", + "include/propertycontainer.h", + "include/propertynode.h", + "include/propertyparser.h", + "include/qmlanchors.h", + "include/qmlchangeset.h", + "include/qmlitemnode.h", + "include/qmlmodelnodefacade.h", + "include/qmlmodelview.h", + "include/qmlobjectnode.h", + "include/qmlstate.h", + "include/removebasestateexception.h", + "include/rewriterview.h", + "include/rewritingexception.h", + "include/subcomponentmanager.h", + "include/textmodifier.h", + "include/variantproperty.h", + "instances/nodeinstance.cpp", + "instances/nodeinstanceserverproxy.cpp", + "instances/nodeinstanceserverproxy.h", + "instances/nodeinstanceview.cpp", + "metainfo/itemlibraryinfo.cpp", + "metainfo/metainfo.cpp", + "metainfo/metainfoparser.cpp", + "metainfo/nodemetainfo.cpp", + "metainfo/subcomponentmanager.cpp", + "model/abstractproperty.cpp", + "model/abstractview.cpp", + "model/basetexteditmodifier.cpp", + "model/bindingproperty.cpp", + "model/componenttextmodifier.cpp", + "model/import.cpp", + "model/internalbindingproperty.cpp", + "model/internalbindingproperty.h", + "model/internalnode.cpp", + "model/internalnode_p.h", + "model/internalnodeabstractproperty.cpp", + "model/internalnodeabstractproperty.h", + "model/internalnodelistproperty.cpp", + "model/internalnodelistproperty.h", + "model/internalnodeproperty.cpp", + "model/internalnodeproperty.h", + "model/internalproperty.cpp", + "model/internalproperty.h", + "model/internalvariantproperty.cpp", + "model/internalvariantproperty.h", + "model/model.cpp", + "model/model_p.h", + "model/modelmerger.cpp", + "model/modelnode.cpp", + "model/modelnodepositionrecalculator.cpp", + "model/modelnodepositionrecalculator.h", + "model/modelnodepositionstorage.cpp", + "model/modeltotextmerger.cpp", + "model/modeltotextmerger.h", + "model/nodeabstractproperty.cpp", + "model/nodelistproperty.cpp", + "model/nodeproperty.cpp", + "model/painteventfilter.cpp", + "model/painteventfilter_p.h", + "model/plaintexteditmodifier.cpp", + "model/propertycontainer.cpp", + "model/propertynode.cpp", + "model/propertyparser.cpp", + "model/qmlanchors.cpp", + "model/qmlchangeset.cpp", + "model/qmlitemnode.cpp", + "model/qmlmodelnodefacade.cpp", + "model/qmlmodelview.cpp", + "model/qmlobjectnode.cpp", + "model/qmlstate.cpp", + "model/qmltextgenerator.cpp", + "model/qmltextgenerator.h", + "model/rewriteaction.cpp", + "model/rewriteaction.h", + "model/rewriteactioncompressor.cpp", + "model/rewriteactioncompressor.h", + "model/rewriterview.cpp", + "model/textmodifier.cpp", + "model/texttomodelmerger.cpp", + "model/texttomodelmerger.h", + "model/variantproperty.cpp", + "model/viewlogger.cpp", + "model/viewlogger.h", + "pluginmanager/widgetpluginmanager.cpp", + "pluginmanager/widgetpluginmanager.h", + "pluginmanager/widgetpluginpath.cpp", + "pluginmanager/widgetpluginpath.h", + ] + } + + Group { + prefix: "components/" + files: [ + "componentcore/modelnodecontextmenu.cpp", + "componentcore/modelnodecontextmenu.h", + "formeditor/abstractformeditortool.cpp", + "formeditor/abstractformeditortool.h", + "formeditor/controlelement.cpp", + "formeditor/controlelement.h", + "formeditor/dragtool.cpp", + "formeditor/dragtool.h", + "formeditor/formeditor.qrc", + "formeditor/formeditorgraphicsview.cpp", + "formeditor/formeditorgraphicsview.h", + "formeditor/formeditoritem.cpp", + "formeditor/formeditoritem.h", + "formeditor/formeditorscene.cpp", + "formeditor/formeditorscene.h", + "formeditor/formeditorview.cpp", + "formeditor/formeditorview.h", + "formeditor/formeditorwidget.cpp", + "formeditor/formeditorwidget.h", + "formeditor/itemutilfunctions.cpp", + "formeditor/itemutilfunctions.h", + "formeditor/layeritem.cpp", + "formeditor/layeritem.h", + "formeditor/lineeditaction.cpp", + "formeditor/lineeditaction.h", + "formeditor/movemanipulator.cpp", + "formeditor/movemanipulator.h", + "formeditor/movetool.cpp", + "formeditor/movetool.h", + "formeditor/numberseriesaction.cpp", + "formeditor/numberseriesaction.h", + "formeditor/onedimensionalcluster.cpp", + "formeditor/onedimensionalcluster.h", + "formeditor/resizecontroller.cpp", + "formeditor/resizecontroller.h", + "formeditor/resizehandleitem.cpp", + "formeditor/resizehandleitem.h", + "formeditor/resizeindicator.cpp", + "formeditor/resizeindicator.h", + "formeditor/resizemanipulator.cpp", + "formeditor/resizemanipulator.h", + "formeditor/resizetool.cpp", + "formeditor/resizetool.h", + "formeditor/rubberbandselectionmanipulator.cpp", + "formeditor/rubberbandselectionmanipulator.h", + "formeditor/scaleitem.cpp", + "formeditor/scaleitem.h", + "formeditor/scalemanipulator.cpp", + "formeditor/scalemanipulator.h", + "formeditor/selectionindicator.cpp", + "formeditor/selectionindicator.h", + "formeditor/selectionrectangle.cpp", + "formeditor/selectionrectangle.h", + "formeditor/selectiontool.cpp", + "formeditor/selectiontool.h", + "formeditor/singleselectionmanipulator.cpp", + "formeditor/singleselectionmanipulator.h", + "formeditor/snapper.cpp", + "formeditor/snapper.h", + "formeditor/snappinglinecreator.cpp", + "formeditor/snappinglinecreator.h", + "formeditor/toolbox.cpp", + "formeditor/toolbox.h", + "formeditor/zoomaction.cpp", + "formeditor/zoomaction.h", + "integration/componentaction.cpp", + "integration/componentaction.h", + "integration/componentview.cpp", + "integration/componentview.h", + "integration/designdocumentcontroller.cpp", + "integration/designdocumentcontroller.h", + "integration/designdocumentcontrollerview.cpp", + "integration/designdocumentcontrollerview.h", + "integration/stackedutilitypanelcontroller.cpp", + "integration/stackedutilitypanelcontroller.h", + "integration/utilitypanelcontroller.cpp", + "integration/utilitypanelcontroller.h", + "integration/xuifiledialog.cpp", + "integration/xuifiledialog.h", + "itemlibrary/customdraganddrop.cpp", + "itemlibrary/customdraganddrop.h", + "itemlibrary/itemlibrary.qrc", + "itemlibrary/itemlibrarycomponents.cpp", + "itemlibrary/itemlibrarycomponents.h", + "itemlibrary/itemlibraryimageprovider.cpp", + "itemlibrary/itemlibraryimageprovider.h", + "itemlibrary/itemlibrarymodel.cpp", + "itemlibrary/itemlibrarymodel.h", + "itemlibrary/itemlibraryview.cpp", + "itemlibrary/itemlibraryview.h", + "itemlibrary/itemlibrarywidget.cpp", + "itemlibrary/itemlibrarywidget.h", + "itemlibrary/qml/ItemView.qml", + "itemlibrary/qml/ItemsView.qml", + "itemlibrary/qml/ItemsViewStyle.qml", + "itemlibrary/qml/Scrollbar.qml", + "itemlibrary/qml/SectionView.qml", + "itemlibrary/qml/Selector.qml", + "navigator/navigator.qrc", + "navigator/navigatortreemodel.cpp", + "navigator/navigatortreemodel.h", + "navigator/navigatortreeview.cpp", + "navigator/navigatortreeview.h", + "navigator/navigatorview.cpp", + "navigator/navigatorview.h", + "navigator/navigatorwidget.cpp", + "navigator/navigatorwidget.h", + "pluginmanager/iplugin.cpp", + "pluginmanager/iplugin.h", + "pluginmanager/pluginmanager.cpp", + "pluginmanager/pluginmanager.h", + "pluginmanager/pluginpath.cpp", + "pluginmanager/pluginpath.h", + "propertyeditor/basiclayouts.cpp", + "propertyeditor/basiclayouts.h", + "propertyeditor/basicwidgets.cpp", + "propertyeditor/basicwidgets.h", + "propertyeditor/behaviordialog.cpp", + "propertyeditor/behaviordialog.h", + "propertyeditor/behaviordialog.ui", + "propertyeditor/declarativewidgetview.cpp", + "propertyeditor/declarativewidgetview.h", + "propertyeditor/designerpropertymap.h", + "propertyeditor/filewidget.cpp", + "propertyeditor/filewidget.h", + "propertyeditor/fontwidget.cpp", + "propertyeditor/fontwidget.h", + "propertyeditor/gradientlineqmladaptor.cpp", + "propertyeditor/gradientlineqmladaptor.h", + "propertyeditor/layoutwidget.cpp", + "propertyeditor/layoutwidget.h", + "propertyeditor/originwidget.cpp", + "propertyeditor/originwidget.h", + "propertyeditor/propertyeditor.cpp", + "propertyeditor/propertyeditor.h", + "propertyeditor/propertyeditor.qrc", + "propertyeditor/propertyeditorcontextobject.cpp", + "propertyeditor/propertyeditorcontextobject.h", + "propertyeditor/propertyeditortransaction.cpp", + "propertyeditor/propertyeditortransaction.h", + "propertyeditor/propertyeditorvalue.cpp", + "propertyeditor/propertyeditorvalue.h", + "propertyeditor/qlayoutobject.cpp", + "propertyeditor/qlayoutobject.h", + "propertyeditor/qmlanchorbindingproxy.cpp", + "propertyeditor/qmlanchorbindingproxy.h", + "propertyeditor/qproxylayoutitem.cpp", + "propertyeditor/qproxylayoutitem.h", + "propertyeditor/resetwidget.cpp", + "propertyeditor/resetwidget.h", + "propertyeditor/siblingcombobox.cpp", + "propertyeditor/siblingcombobox.h", + "resources/resources.qrc", + "stateseditor/HorizontalScrollBar.qml", + "stateseditor/stateseditor.qrc", + "stateseditor/stateseditorimageprovider.cpp", + "stateseditor/stateseditorimageprovider.cpp", + "stateseditor/stateseditormodel.cpp", + "stateseditor/stateseditormodel.h", + "stateseditor/stateseditorview.cpp", + "stateseditor/stateseditorview.h", + "stateseditor/stateseditorwidget.cpp", + "stateseditor/stateseditorwidget.h", + "stateseditor/stateslist.qml", + ] + } files: [ - "designercore/filemanager/qmlrewriter.h", - "designercore/filemanager/qmlrefactoring.h", - "designercore/filemanager/changeobjecttypevisitor.h", - "designercore/filemanager/changepropertyvisitor.h", - "designercore/filemanager/removeuiobjectmembervisitor.h", - "designercore/filemanager/removepropertyvisitor.h", - "designercore/filemanager/addpropertyvisitor.h", - "designercore/filemanager/moveobjectvisitor.h", - "designercore/filemanager/addobjectvisitor.h", - "designercore/filemanager/addarraymembervisitor.h", - "designercore/filemanager/astobjecttextextractor.h", - "designercore/filemanager/objectlengthcalculator.h", - "designercore/filemanager/firstdefinitionfinder.h", - "designercore/filemanager/moveobjectbeforeobjectvisitor.h", - "designercore/filemanager/changeimportsvisitor.h", - "designercore/include/nodeinstance.h", - "designercore/instances/nodeinstanceserverproxy.h", - "../../../share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h", - "../../../share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h", - "../../../share/qtcreator/qml/qmlpuppet/interfaces/commondefines.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/synchronizecommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/tokencommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/componentcompletedcommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/completecomponentcommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/statepreviewimagechangedcommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/childrenchangedcommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/changebindingscommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/changefileurlcommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/changeidscommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/changestatecommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/changevaluescommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/createscenecommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/clearscenecommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/createinstancescommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/informationchangedcommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/pixmapchangedcommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/removeinstancescommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/removepropertiescommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/reparentinstancescommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h", - "../../../share/qtcreator/qml/qmlpuppet/commands/changeauxiliarycommand.h", - "../../../share/qtcreator/qml/qmlpuppet/container/addimportcontainer.h", - "../../../share/qtcreator/qml/qmlpuppet/container/imagecontainer.h", - "../../../share/qtcreator/qml/qmlpuppet/container/idcontainer.h", - "../../../share/qtcreator/qml/qmlpuppet/container/informationcontainer.h", - "../../../share/qtcreator/qml/qmlpuppet/container/instancecontainer.h", - "../../../share/qtcreator/qml/qmlpuppet/container/reparentcontainer.h", - "../../../share/qtcreator/qml/qmlpuppet/container/propertyabstractcontainer.h", - "../../../share/qtcreator/qml/qmlpuppet/container/propertybindingcontainer.h", - "../../../share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.h", - "designercore/include/corelib_global.h", - "designercore/include/abstractview.h", - "designercore/include/nodeinstanceview.h", - "designercore/include/rewriterview.h", - "designercore/include/metainfo.h", - "designercore/include/metainfoparser.h", - "designercore/include/nodemetainfo.h", - "designercore/include/itemlibraryinfo.h", - "designercore/model/internalproperty.h", - "designercore/include/modelnode.h", - "designercore/include/model.h", - "designercore/include/nodeproperty.h", - "designercore/include/subcomponentmanager.h", - "designercore/include/propertycontainer.h", - "designercore/model/internalnode_p.h", - "designercore/model/model_p.h", - "designercore/model/painteventfilter_p.h", - "designercore/include/propertyparser.h", - "designercore/pluginmanager/widgetpluginmanager.h", - "designercore/pluginmanager/widgetpluginpath.h", - "designercore/include/exception.h", - "designercore/include/invalidreparentingexception.h", - "designercore/include/invalidmetainfoexception.h", - "designercore/include/invalidargumentexception.h", - "designercore/include/notimplementedexception.h", - "designercore/include/invalidpropertyexception.h", - "designercore/include/invalidmodelstateexception.h", - "designercore/include/removebasestateexception.h", - "designercore/include/invalididexception.h", - "designercore/include/propertynode.h", - "designercore/include/invalidslideindexexception.h", - "designercore/include/import.h", - "designercore/include/invalidqmlsourceexception.h", - "designercore/model/viewlogger.h", - "designercore/model/internalvariantproperty.h", - "designercore/model/internalnodelistproperty.h", - "designercore/include/variantproperty.h", - "designercore/include/nodelistproperty.h", - "designercore/include/abstractproperty.h", - "designercore/model/internalbindingproperty.h", - "designercore/include/bindingproperty.h", - "designercore/model/internalnodeproperty.h", - "designercore/model/internalnodeabstractproperty.h", - "designercore/include/nodeabstractproperty.h", - "designercore/include/plaintexteditmodifier.h", - "designercore/include/basetexteditmodifier.h", - "designercore/include/componenttextmodifier.h", - "designercore/include/textmodifier.h", - "designercore/model/modeltotextmerger.h", - "designercore/model/texttomodelmerger.h", - "designercore/include/qmlmodelview.h", - "designercore/include/qmlitemnode.h", - "designercore/include/qmlstate.h", - "designercore/include/qmlchangeset.h", - "designercore/include/qmlmodelnodefacade.h", - "designercore/include/forwardview.h", - "designercore/include/qmlobjectnode.h", - "designercore/include/qmlanchors.h", - "designercore/rewritertransaction.h", - "designercore/model/rewriteaction.h", - "designercore/include/modelnodepositionstorage.h", - "designercore/model/modelnodepositionrecalculator.h", - "designercore/model/rewriteactioncompressor.h", - "designercore/model/qmltextgenerator.h", - "designercore/include/modelmerger.h", - "designercore/include/mathutils.h", - "designercore/include/customnotifications.h", - "designercore/include/rewritingexception.h", - "designercore/model/modelnodecontextmenu.h", - "designercore/include/basetexteditmodifier.h", - "components/integration/integrationcore.h", - "components/integration/designdocumentcontrollerview.h", - "components/integration/designdocumentcontroller.h", - "components/integration/utilitypanelcontroller.h", - "components/integration/stackedutilitypanelcontroller.h", - "components/integration/componentaction.h", - "components/integration/componentview.h", - "components/integration/xuifiledialog.h", - "components/integration/integrationcore.cpp", - "components/integration/designdocumentcontroller.cpp", - "components/integration/designdocumentcontrollerview.cpp", - "components/integration/utilitypanelcontroller.cpp", - "components/integration/stackedutilitypanelcontroller.cpp", - "components/integration/componentaction.cpp", - "components/integration/componentview.cpp", - "components/integration/xuifiledialog.cpp", - "components/propertyeditor/propertyeditor.h", - "components/propertyeditor/qmlanchorbindingproxy.h", - "components/propertyeditor/resetwidget.h", - "components/propertyeditor/qlayoutobject.h", - "components/propertyeditor/basiclayouts.h", - "components/propertyeditor/basicwidgets.h", - "components/propertyeditor/behaviordialog.h", - "components/propertyeditor/qproxylayoutitem.h", - "components/propertyeditor/layoutwidget.h", - "components/propertyeditor/filewidget.h", - "components/propertyeditor/propertyeditorvalue.h", - "components/propertyeditor/fontwidget.h", - "components/propertyeditor/originwidget.h", - "components/propertyeditor/siblingcombobox.h", - "components/propertyeditor/propertyeditortransaction.h", - "components/propertyeditor/designerpropertymap.h", - "components/propertyeditor/propertyeditorcontextobject.h", - "components/propertyeditor/declarativewidgetview.h", - "components/propertyeditor/gradientlineqmladaptor.h", - "components/propertyeditor/propertyeditor.cpp", - "components/propertyeditor/qmlanchorbindingproxy.cpp", - "components/propertyeditor/resetwidget.cpp", - "components/propertyeditor/qlayoutobject.cpp", - "components/propertyeditor/basiclayouts.cpp", - "components/propertyeditor/basicwidgets.cpp", - "components/propertyeditor/behaviordialog.cpp", - "components/propertyeditor/qproxylayoutitem.cpp", - "components/propertyeditor/layoutwidget.cpp", - "components/propertyeditor/filewidget.cpp", - "components/propertyeditor/propertyeditorvalue.cpp", - "components/propertyeditor/fontwidget.cpp", - "components/propertyeditor/originwidget.cpp", - "components/propertyeditor/siblingcombobox.cpp", - "components/propertyeditor/propertyeditortransaction.cpp", - "components/propertyeditor/propertyeditorcontextobject.cpp", - "components/propertyeditor/declarativewidgetview.cpp", - "components/propertyeditor/gradientlineqmladaptor.cpp", - "components/propertyeditor/propertyeditor.qrc", - "components/formeditor/formeditorscene.h", - "components/formeditor/formeditorwidget.h", - "components/formeditor/formeditoritem.h", - "components/formeditor/formeditorview.h", - "components/formeditor/selectiontool.h", - "components/formeditor/abstractformeditortool.h", - "components/formeditor/controlelement.h", - "components/formeditor/resizemanipulator.h", - "components/formeditor/movemanipulator.h", - "components/formeditor/layeritem.h", - "components/formeditor/itemutilfunctions.h", - "components/formeditor/selectionrectangle.h", - "components/formeditor/rubberbandselectionmanipulator.h", - "components/formeditor/movetool.h", - "components/formeditor/selectionindicator.h", - "components/formeditor/snappinglinecreator.h", - "components/formeditor/snapper.h", - "components/formeditor/onedimensionalcluster.h", - "components/formeditor/singleselectionmanipulator.h", - "components/formeditor/scalemanipulator.h", - "components/formeditor/resizetool.h", - "components/formeditor/resizeindicator.h", - "components/formeditor/scaleitem.h", - "components/formeditor/resizecontroller.h", - "components/formeditor/resizehandleitem.h", - "components/formeditor/dragtool.h", - "components/formeditor/toolbox.h", - "components/formeditor/zoomaction.h", - "components/formeditor/formeditorgraphicsview.h", - "components/formeditor/numberseriesaction.h", - "components/formeditor/lineeditaction.h", - "components/formeditor/formeditoritem.cpp", - "components/formeditor/formeditorview.cpp", - "components/formeditor/formeditorscene.cpp", - "components/formeditor/formeditorwidget.cpp", - "components/formeditor/selectiontool.cpp", - "components/formeditor/abstractformeditortool.cpp", - "components/formeditor/controlelement.cpp", - "components/formeditor/resizemanipulator.cpp", - "components/formeditor/movemanipulator.cpp", - "components/formeditor/layeritem.cpp", - "components/formeditor/itemutilfunctions.cpp", - "components/formeditor/selectionrectangle.cpp", - "components/formeditor/rubberbandselectionmanipulator.cpp", - "components/formeditor/movetool.cpp", - "components/formeditor/selectionindicator.cpp", - "components/formeditor/snappinglinecreator.cpp", - "components/formeditor/snapper.cpp", - "components/formeditor/onedimensionalcluster.cpp", - "components/formeditor/singleselectionmanipulator.cpp", - "components/formeditor/scalemanipulator.cpp", - "components/formeditor/resizetool.cpp", - "components/formeditor/resizeindicator.cpp", - "components/formeditor/scaleitem.cpp", - "components/formeditor/resizecontroller.cpp", - "components/formeditor/resizehandleitem.cpp", - "components/formeditor/dragtool.cpp", - "components/formeditor/toolbox.cpp", - "components/formeditor/zoomaction.cpp", - "components/formeditor/formeditorgraphicsview.cpp", - "components/formeditor/numberseriesaction.cpp", - "components/formeditor/lineeditaction.cpp", - "components/formeditor/formeditor.qrc", - "qmldesignerconstants.h", - "qmldesignerplugin.h", - "designmodewidget.h", + "designersettings.cpp", "designersettings.h", - "settingspage.h", + "designmodecontext.cpp", "designmodecontext.h", - "styledoutputpaneplaceholder.h", - "designercore/filemanager/qmlrewriter.cpp", - "designercore/filemanager/qmlrefactoring.cpp", - "designercore/filemanager/changeobjecttypevisitor.cpp", - "designercore/filemanager/changepropertyvisitor.cpp", - "designercore/filemanager/removeuiobjectmembervisitor.cpp", - "designercore/filemanager/removepropertyvisitor.cpp", - "designercore/filemanager/addpropertyvisitor.cpp", - "designercore/filemanager/moveobjectvisitor.cpp", - "designercore/filemanager/addobjectvisitor.cpp", - "designercore/filemanager/addarraymembervisitor.cpp", - "designercore/filemanager/astobjecttextextractor.cpp", - "designercore/filemanager/objectlengthcalculator.cpp", - "designercore/filemanager/firstdefinitionfinder.cpp", - "designercore/filemanager/moveobjectbeforeobjectvisitor.cpp", - "designercore/filemanager/changeimportsvisitor.cpp", - "designercore/instances/nodeinstanceserverproxy.cpp", - "designercore/instances/nodeinstance.cpp", - "designercore/instances/nodeinstanceview.cpp", - "../../../share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/synchronizecommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/tokencommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/componentcompletedcommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/completecomponentcommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/statepreviewimagechangedcommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/childrenchangedcommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/changebindingscommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/changefileurlcommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/changeidscommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/changenodesourcecommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/changestatecommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/changevaluescommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/informationchangedcommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/removeinstancescommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/removepropertiescommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/reparentinstancescommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/clearscenecommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/createinstancescommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/createscenecommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/pixmapchangedcommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/commands/changeauxiliarycommand.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/addimportcontainer.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/idcontainer.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/informationcontainer.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/instancecontainer.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/reparentcontainer.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/propertyabstractcontainer.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/propertybindingcontainer.cpp", - "../../../share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.cpp", - "designercore/model/abstractview.cpp", - "designercore/model/rewriterview.cpp", - "designercore/metainfo/metainfo.cpp", - "designercore/metainfo/metainfoparser.cpp", - "designercore/metainfo/nodemetainfo.cpp", - "designercore/metainfo/itemlibraryinfo.cpp", - "designercore/metainfo/subcomponentmanager.cpp", - "designercore/model/internalproperty.cpp", - "designercore/model/model.cpp", - "designercore/model/modelnode.cpp", - "designercore/model/painteventfilter.cpp", - "designercore/model/internalnode.cpp", - "designercore/model/propertyparser.cpp", - "designercore/model/propertycontainer.cpp", - "designercore/pluginmanager/widgetpluginmanager.cpp", - "designercore/pluginmanager/widgetpluginpath.cpp", - "designercore/exceptions/exception.cpp", - "designercore/exceptions/invalidpropertyexception.cpp", - "designercore/exceptions/invalidmodelnodeexception.cpp", - "designercore/exceptions/invalidreparentingexception.cpp", - "designercore/exceptions/invalidmetainfoexception.cpp", - "designercore/exceptions/invalidargumentexception.cpp", - "designercore/exceptions/notimplementedexception.cpp", - "designercore/exceptions/invalidmodelstateexception.cpp", - "designercore/exceptions/removebasestateexception.cpp", - "designercore/exceptions/invalididexception.cpp", - "designercore/model/propertynode.cpp", - "designercore/exceptions/invalidslideindexexception.cpp", - "designercore/model/import.cpp", - "designercore/exceptions/invalidqmlsourceexception.cpp", - "designercore/model/viewlogger.cpp", - "designercore/model/internalvariantproperty.cpp", - "designercore/model/internalnodelistproperty.cpp", - "designercore/model/variantproperty.cpp", - "designercore/model/nodelistproperty.cpp", - "designercore/model/abstractproperty.cpp", - "designercore/model/internalbindingproperty.cpp", - "designercore/model/bindingproperty.cpp", - "designercore/model/internalnodeproperty.cpp", - "designercore/model/internalnodeabstractproperty.cpp", - "designercore/model/nodeabstractproperty.cpp", - "designercore/model/nodeproperty.cpp", - "designercore/model/modeltotextmerger.cpp", - "designercore/model/texttomodelmerger.cpp", - "designercore/model/plaintexteditmodifier.cpp", - "designercore/model/componenttextmodifier.cpp", - "designercore/model/textmodifier.cpp", - "designercore/model/qmlmodelview.cpp", - "designercore/model/qmlitemnode.cpp", - "designercore/model/qmlstate.cpp", - "designercore/model/qmlchangeset.cpp", - "designercore/model/qmlmodelnodefacade.cpp", - "designercore/model/qmlobjectnode.cpp", - "designercore/model/qmlanchors.cpp", - "designercore/rewritertransaction.cpp", - "designercore/model/rewriteaction.cpp", - "designercore/model/modelnodepositionstorage.cpp", - "designercore/model/modelnodepositionrecalculator.cpp", - "designercore/model/rewriteactioncompressor.cpp", - "designercore/model/qmltextgenerator.cpp", - "designercore/model/modelmerger.cpp", - "designercore/exceptions/rewritingexception.cpp", - "designercore/model/modelnodecontextmenu.cpp", - "designercore/model/basetexteditmodifier.cpp", - "components/propertyeditor/behaviordialog.ui", - "components/itemlibrary/itemlibraryview.cpp", - "components/itemlibrary/itemlibrarywidget.cpp", - "components/itemlibrary/customdraganddrop.cpp", - "components/itemlibrary/itemlibrarymodel.cpp", - "components/itemlibrary/itemlibrarycomponents.cpp", - "components/itemlibrary/itemlibraryimageprovider.cpp", - "components/itemlibrary/itemlibraryview.h", - "components/itemlibrary/itemlibrarywidget.h", - "components/itemlibrary/customdraganddrop.h", - "components/itemlibrary/itemlibrarymodel.h", - "components/itemlibrary/itemlibrarycomponents.h", - "components/itemlibrary/itemlibraryimageprovider.h", - "components/itemlibrary/itemlibrary.qrc", - "components/navigator/navigatorview.h", - "components/navigator/navigatortreemodel.h", - "components/navigator/navigatorwidget.h", - "components/navigator/navigatortreeview.h", - "components/navigator/navigatorview.cpp", - "components/navigator/navigatortreemodel.cpp", - "components/navigator/navigatorwidget.cpp", - "components/navigator/navigatortreeview.cpp", - "components/navigator/navigator.qrc", - "components/pluginmanager/pluginmanager.cpp", - "components/pluginmanager/pluginpath.cpp", - "components/pluginmanager/iplugin.cpp", - "components/pluginmanager/pluginmanager.h", - "components/pluginmanager/pluginpath.h", - "components/pluginmanager/iplugin.h", - "components/stateseditor/stateseditorwidget.h", - "components/stateseditor/stateseditormodel.h", - "components/stateseditor/stateseditorview.h", - "components/stateseditor/stateseditorimageprovider.cpp", - "components/stateseditor/stateseditorwidget.cpp", - "components/stateseditor/stateseditormodel.cpp", - "components/stateseditor/stateseditorview.cpp", - "components/stateseditor/stateseditorimageprovider.cpp", - "components/stateseditor/stateseditor.qrc", - "components/stateseditor/stateslist.qml", - "components/stateseditor/HorizontalScrollBar.qml", - "qmldesignerplugin.cpp", "designmodewidget.cpp", - "designersettings.cpp", + "designmodewidget.h", + "qmldesignerconstants.h", + "qmldesignerplugin.cpp", + "qmldesignerplugin.h", "settingspage.cpp", - "designmodecontext.cpp", - "styledoutputpaneplaceholder.cpp", + "settingspage.h", "settingspage.ui", - "components/resources/resources.qrc", - "components/itemlibrary/qml/Selector.qml", - "components/itemlibrary/qml/SectionView.qml", - "components/itemlibrary/qml/Scrollbar.qml", - "components/itemlibrary/qml/ItemView.qml", - "components/itemlibrary/qml/ItemsViewStyle.qml", - "components/itemlibrary/qml/ItemsView.qml" + "styledoutputpaneplaceholder.cpp", + "styledoutputpaneplaceholder.h", ] } - diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 091c8feaed..5b781dfbbe 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -60,6 +60,8 @@ const char QML_CANVASWIDTH_KEY[] = "CanvasWidth"; const char QML_CANVASHEIGHT_KEY[] = "CanvasHeight"; const char QML_CONTEXTPANE_KEY[] = "ContextPaneEnabled"; const char QML_CONTEXTPANEPIN_KEY[] = "ContextPanePinned"; +const char QML_WARNIN_FOR_FEATURES_IN_DESIGNER_KEY[] = "WarnAboutQtQuickFeaturesInDesigner"; +const char QML_WARNIN_FOR_DESIGNER_FEATURES_IN_EDITOR_KEY[] = "WarnAboutQtQuickDesignerFeaturesInCodeEditor"; enum { QML_OPENDESIGNMODE_DEFAULT = 0 }; // 0 for text mode, 1 for design mode const char SETTINGS_CATEGORY_QML_ICON[] = ":/core/images/category_qml.png"; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 0da7a35312..a716f00703 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -54,10 +54,9 @@ #include <extensionsystem/pluginmanager.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> -#include <integrationcore.h> - #include <QAction> #include <QFileInfo> @@ -78,7 +77,6 @@ bool shouldAssertInException() } BauhausPlugin::BauhausPlugin() : - m_designerCore(0), m_designMode(0), m_isActive(false), m_revertToSavedAction(new QAction(this)), @@ -105,7 +103,6 @@ BauhausPlugin::BauhausPlugin() : BauhausPlugin::~BauhausPlugin() { - delete m_designerCore; Core::ICore::removeContextObject(m_context); } @@ -124,17 +121,13 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error switchAction, QmlDesigner::Constants::SWITCH_TEXT_DESIGN, switchContext); command->setDefaultKeySequence(QKeySequence(Qt::Key_F4)); - m_designerCore = new QmlDesigner::IntegrationCore; m_pluginInstance = this; -#ifdef Q_OS_MAC - const QString pluginPath = QCoreApplication::applicationDirPath() + "/../PlugIns/QmlDesigner"; -#else - const QString pluginPath = QCoreApplication::applicationDirPath() + "/../" - + QLatin1String(IDE_LIBRARY_BASENAME) + "/qtcreator/qmldesigner"; -#endif - - m_designerCore->pluginManager()->setPluginPaths(QStringList() << pluginPath); + const QString pluginPath = Utils::HostOsInfo::isMacHost() + ? QString(QCoreApplication::applicationDirPath() + "/../PlugIns/QmlDesigner") + : QString(QCoreApplication::applicationDirPath() + "/../" + + QLatin1String(IDE_LIBRARY_BASENAME) + "/qtcreator/qmldesigner"); + m_pluginManager.setPluginPaths(QStringList() << pluginPath); createDesignModeWidget(); connect(switchAction, SIGNAL(triggered()), this, SLOT(switchTextDesign())); @@ -259,15 +252,14 @@ void BauhausPlugin::createDesignModeWidget() command = Core::ActionManager::registerAction(m_mainWidget->hideSidebarsAction(), Core::Constants::TOGGLE_SIDEBAR, qmlDesignerMainContext); -#ifdef Q_OS_MACX - // add second shortcut to trigger delete - QAction *deleteAction = new QAction(m_mainWidget); - deleteAction->setShortcut(QKeySequence(QLatin1String("Backspace"))); - connect(deleteAction, SIGNAL(triggered()), m_mainWidget->deleteAction(), - SIGNAL(triggered())); - - m_mainWidget->addAction(deleteAction); -#endif // Q_OS_MACX + if (Utils::HostOsInfo::isMacHost()) { + // add second shortcut to trigger delete + QAction *deleteAction = new QAction(m_mainWidget); + deleteAction->setShortcut(QKeySequence(QLatin1String("Backspace"))); + connect(deleteAction, SIGNAL(triggered()), m_mainWidget->deleteAction(), + SIGNAL(triggered())); + m_mainWidget->addAction(deleteAction); + } connect(m_editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)), this, SLOT(updateEditor(Core::IEditor*))); @@ -377,8 +369,9 @@ void BauhausPlugin::switchTextDesign() } } -DesignerSettings BauhausPlugin::settings() const +DesignerSettings BauhausPlugin::settings() { + m_settings.fromSettings(Core::ICore::settings()); return m_settings; } diff --git a/src/plugins/qmldesigner/qmldesignerplugin.h b/src/plugins/qmldesigner/qmldesignerplugin.h index 7464d42cc6..09c34db59a 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.h +++ b/src/plugins/qmldesigner/qmldesignerplugin.h @@ -34,6 +34,8 @@ #include <extensionsystem/iplugin.h> +#include <pluginmanager.h> + #include <QWeakPointer> #include <QStringList> @@ -50,10 +52,6 @@ namespace Core { } namespace QmlDesigner { - class IntegrationCore; -} - -namespace QmlDesigner { namespace Internal { class DesignModeWidget; @@ -74,7 +72,7 @@ public: static BauhausPlugin *pluginInstance(); - DesignerSettings settings() const; + DesignerSettings settings(); void setSettings(const DesignerSettings &s); private slots: @@ -91,7 +89,7 @@ private: QStringList m_mimeTypes; DesignModeWidget *m_mainWidget; - QmlDesigner::IntegrationCore *m_designerCore; + QmlDesigner::PluginManager m_pluginManager; static BauhausPlugin *m_pluginInstance; DesignerSettings m_settings; DesignModeContext *m_context; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pri b/src/plugins/qmldesigner/qmldesignerplugin.pri new file mode 100644 index 0000000000..efe34c0bff --- /dev/null +++ b/src/plugins/qmldesigner/qmldesignerplugin.pri @@ -0,0 +1,16 @@ +HEADERS += $$PWD/qmldesignerconstants.h \ + $$PWD/qmldesignerplugin.h \ + $$PWD/designmodewidget.h \ + $$PWD/designersettings.h \ + $$PWD/settingspage.h \ + $$PWD/designmodecontext.h \ + $$PWD/styledoutputpaneplaceholder.h + +SOURCES += $$PWD/qmldesignerplugin.cpp \ + $$PWD/designmodewidget.cpp \ + $$PWD/designersettings.cpp \ + $$PWD/settingspage.cpp \ + $$PWD/designmodecontext.cpp \ + $$PWD/styledoutputpaneplaceholder.cpp + +FORMS += $$PWD/settingspage.ui diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pro b/src/plugins/qmldesigner/qmldesignerplugin.pro index d042701c19..6935895dcc 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pro +++ b/src/plugins/qmldesigner/qmldesignerplugin.pro @@ -9,7 +9,8 @@ include(../../qtcreatorplugin.pri) include(../../private_headers.pri) include(qmldesigner_dependencies.pri) -include(designercore/designercore.pri) +include(designercore/designercore-lib.pri) +include(components/componentcore/componentcore.pri) include(components/integration/integration.pri) include(components/propertyeditor/propertyeditor.pri) include(components/formeditor/formeditor.pri) @@ -18,20 +19,4 @@ include(components/navigator/navigator.pri) include(components/pluginmanager/pluginmanager.pri) include(components/stateseditor/stateseditor.pri) include(components/resources/resources.pri) - -HEADERS += qmldesignerconstants.h \ - qmldesignerplugin.h \ - designmodewidget.h \ - designersettings.h \ - settingspage.h \ - designmodecontext.h \ - styledoutputpaneplaceholder.h - -SOURCES += qmldesignerplugin.cpp \ - designmodewidget.cpp \ - designersettings.cpp \ - settingspage.cpp \ - designmodecontext.cpp \ - styledoutputpaneplaceholder.cpp - -FORMS += settingspage.ui +include(qmldesignerplugin.pri) diff --git a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc index 3293af8962..b2dcfce06a 100644 --- a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc +++ b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc @@ -32,10 +32,16 @@ <file>images/text-input-icon16.png</file> <file>images/webview-icon16.png</file> <file>source/listview.qml</file> + <file>source/listviewv2.qml</file> <file>source/gridview.qml</file> + <file>source/gridviewv2.qml</file> <file>source/pathview.qml</file> + <file>source/pathviewv2.qml</file> <file>source/text.qml</file> + <file>source/textv2.qml</file> <file>source/textedit.qml</file> + <file>source/texteditv2.qml</file> <file>source/textinput.qml</file> + <file>source/textinputv2.qml</file> </qresource> </RCC> diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index be74404a75..a891ed2117 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -1,117 +1,454 @@ -<metainfo> - <node name="QtQuick.Item" icon=":/qtquickplugin/images/item-icon16.png"> - <itemlibraryentry name="Item" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/item-icon.png" version="1.0"> - <property name="width" type="int" value="200"/> - <property name="height" type="int" value="200"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Rectangle" icon=":/qtquickplugin/images/rect-icon16.png"> - <itemlibraryentry name="Rectangle" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/rect-icon.png" version="1.0"> - <property name="color" type="QColor" value="#ffffff"/> - <property name="width" type="int" value="200"/> - <property name="height" type="int" value="200"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Text" icon=":/qtquickplugin/images/text-icon16.png"> - <itemlibraryentry name="Text" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/text-icon.png" version="1.0"> - <qml source=":/qtquickplugin/source/text.qml"/> - </itemlibraryentry> - </node> - <node name="QtQuick.TextEdit" icon=":/qtquickplugin/images/text-edit-icon16.png"> - <itemlibraryentry name="Text Edit" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/text-edit-icon.png" version="1.0"> - <qml source=":/qtquickplugin/source/textedit.qml"/> - </itemlibraryentry> - </node> - <node name="QtQuick.TextInput" icon=":/qtquickplugin/images/text-input-icon16.png"> - <itemlibraryentry name="Text Input" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/text-input-icon.png" version="1.0"> - <qml source=":/qtquickplugin/source/textinput.qml"/> - </itemlibraryentry> - </node> - <node name="QtQuick.MouseArea" icon=":/qtquickplugin/images/mouse-area-icon16.png"> - <itemlibraryentry name="Mouse Area" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/mouse-area-icon.png" version="1.0"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="100"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Image" icon=":/qtquickplugin/images/image-icon16.png"> - <itemlibraryentry name="Image" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/image-icon.png" version="1.0"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="100"/> - <property name="source" type="QUrl" value="qrc:/qtquickplugin/images/template_image.png"/> - </itemlibraryentry> - </node> - <node name="QtQuick.BorderImage" icon=":/qtquickplugin/images/border-image-icon16.png"> - <itemlibraryentry name="Border Image" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/border-image-icon.png" version="1.0"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="100"/> - <property name="source" type="QUrl" value="qrc:/qtquickplugin/images/template_image.png"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Flickable" icon=":/qtquickplugin/images/flickable-icon16.png"> - <itemlibraryentry name="Flickable" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/flickable-icon.png" version="1.0"> - <property name="width" type="int" value="300"/> - <property name="height" type="int" value="300"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Flipable" icon=":/qtquickplugin/images/flipable-icon16.png"> - <itemlibraryentry name="Flipable" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/flipable-icon.png" version="1.0"> - <property name="width" type="int" value="300"/> - <property name="height" type="int" value="300"/> - </itemlibraryentry> - </node> - <node name="QtQuick.GridView" icon=":/qtquickplugin/images/gridview-icon16.png"> - <itemlibraryentry name="Grid View" category="Qt Quick - Views" libraryIcon=":/qtquickplugin/images/gridview-icon.png" version="1.0"> - <qml source=":/qtquickplugin/source/gridview.qml"/> - </itemlibraryentry> - </node> - - <node name="QtQuick.ListView" icon=":/qtquickplugin/images/listview-icon16.png"> - <itemlibraryentry name="List View" category="Qt Quick - Views" libraryIcon=":/qtquickplugin/images/listview-icon.png" version="1.0"> - <qml source=":/qtquickplugin/source/listview.qml"/> - </itemlibraryentry> - </node> - - <node name="QtQuick.PathView" icon=":/qtquickplugin/images/pathview-icon16.png"> - <itemlibraryentry name="Path View" category="Qt Quick - Views" libraryIcon=":/qtquickplugin/images/pathview-icon.png" version="1.0"> - <qml source=":/qtquickplugin/source/pathview.qml"/> - </itemlibraryentry> - </node> - - <node name="QtQuick.FocusScope" icon=":/qtquickplugin/images/focusscope-icon16.png"> - <itemlibraryentry name="Focus Scope" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/focusscope-icon.png" version="1.0"> - <property name="width" type="int" value="100"/> - <property name="height" type="int" value="100"/> - </itemlibraryentry> - </node> - <node name="QtWebKit.WebView" icon=":/qtquickplugin/images/webview-icon16.png"> - <itemlibraryentry name="Web View" category="Qt Quick - Basic" libraryIcon=":/qtquickplugin/images/webview-icon.png" version="1.0" requiredImport="QtWebKit" forceImport="true"> - <property name="width" type="int" value="300"/> - <property name="height" type="int" value="300"/> - <property name="url" type="QString" value="qrc:/qtquickplugin/html/welcome.html"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Row" icon=":/qtquickplugin/images/item-icon16.png"> - <itemlibraryentry name="Row" category="Qt Quick - Positioner" libraryIcon=":/qtquickplugin/images/item-icon.png" version="1.0"> - <property name="width" type="int" value="400"/> - <property name="height" type="int" value="200"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Column" icon=":/qtquickplugin/images/item-icon16.png"> - <itemlibraryentry name="Column" category="Qt Quick - Positioner" libraryIcon=":/qtquickplugin/images/item-icon.png" version="1.0"> - <property name="width" type="int" value="200"/> - <property name="height" type="int" value="400"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Grid" icon=":/qtquickplugin/images/item-icon16.png"> - <itemlibraryentry name="Grid" category="Qt Quick - Positioner" libraryIcon=":/qtquickplugin/images/item-icon.png" version="1.0"> - <property name="width" type="int" value="400"/> - <property name="height" type="int" value="400"/> - </itemlibraryentry> - </node> - <node name="QtQuick.Flow" icon=":/qtquickplugin/images/item-icon16.png"> - <itemlibraryentry name="Flow" category="Qt Quick - Positioner" libraryIcon=":/qtquickplugin/images/item-icon.png" version="1.0"> - <property name="width" type="int" value="400"/> - <property name="height" type="int" value="400"/> - </itemlibraryentry> - </node> - </metainfo> +MetaInfo { + + Type { + name: "QtQuick.Item" + icon: ":/qtquickplugin/images/item-icon16.png" + + ItemLibraryEntry { + name: "Item" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 200; } + } + + ItemLibraryEntry { + name: "Item" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 200; } + } + } + + Type { + name: "QtQuick.Rectangle" + icon: ":/qtquickplugin/images/rect-icon16.png" + + ItemLibraryEntry { + name: "Rectangle" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/rect-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 200; } + Property { name: "color"; type: "QColor"; value: "#ffffff"; } + + } + + ItemLibraryEntry { + name: "Rectangle" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/rect-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 200; } + Property { name: "color"; type: "QColor"; value: "#ffffff"; } + } + } + + Type { + name: "QtQuick.Text" + icon: ":/qtquickplugin/images/text-icon16.png" + + ItemLibraryEntry { + name: "Text" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/text-icon.png" + version: "1.0" + + QmlSource { source: ":/qtquickplugin/source/text.qml" } + } + + ItemLibraryEntry { + name: "Text" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/text-icon.png" + version: "2.0" + + QmlSource { source: ":/qtquickplugin/source/textv2.qml" } + } + } + + Type { + name: "QtQuick.TextEdit" + icon: ":/qtquickplugin/images/text-edit-icon16.png" + + ItemLibraryEntry { + name: "Text Edit" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/text-edit-icon.png" + version: "1.0" + + QmlSource { source: ":/qtquickplugin/source/textedit.qml" } + } + + ItemLibraryEntry { + name: "Text Edit" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/text-edit-icon.png" + version: "2.0" + + QmlSource { source: ":/qtquickplugin/source/texteditv2.qml" } + } + } + + Type { + name: "QtQuick.TextInput" + icon: ":/qtquickplugin/images/text-input-icon16.png" + + ItemLibraryEntry { + name: "Text Input" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/text-edit-icon.png" + version: "1.0" + + QmlSource { source: ":/qtquickplugin/source/textinput.qml" } + } + + ItemLibraryEntry { + name: "Text Input" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/text-input-icon.png" + version: "2.0" + + QmlSource { source: ":/qtquickplugin/source/textinput.qml" } + } + } + + Type { + name: "QtQuick.MouseArea" + icon: ":/qtquickplugin/images/mouse-area-icon16.png" + + ItemLibraryEntry { + name: "MouseArea" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/mouse-area-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "height"; type: "int"; value: 100; } + + } + + ItemLibraryEntry { + name: "MouseArea" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/mouse-area-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "height"; type: "int"; value: 100; } + } + } + + Type { + name: "QtQuick.Image" + icon: ":/qtquickplugin/images/image-icon16.png" + + ItemLibraryEntry { + name: "Image" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/image-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "height"; type: "int"; value: 100; } + Property { name: "source"; type: "QUrl"; value:"qrc:/qtquickplugin/images/template_image.png"; } + } + + ItemLibraryEntry { + name: "Image" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/image-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "height"; type: "int"; value: 100; } + Property { name: "source"; type: "QUrl"; value:"qrc:/qtquickplugin/images/template_image.png"; } + } + } + + Type { + name: "QtQuick.BorderImage" + icon: ":/qtquickplugin/images/border-image-icon16.png" + + ItemLibraryEntry { + name: "Border Image" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/border-image-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "height"; type: "int"; value: 100; } + Property { name: "source"; type: "QUrl"; value:"qrc:/qtquickplugin/images/template_image.png"; } + } + + ItemLibraryEntry { + name: "Border Image" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/border-image-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "height"; type: "int"; value: 100; } + Property { name: "source"; type: "QUrl"; value:"qrc:/qtquickplugin/images/template_image.png"; } + } + } + + Type { + name: "QtQuick.Flickable" + icon: ":/qtquickplugin/images/flickable-icon16.png" + + ItemLibraryEntry { + name: "Flickable" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/flickable-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 300; } + Property { name: "height"; type: "int"; value: 300; } + } + + ItemLibraryEntry { + name: "Flickable" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/flickable-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 300; } + Property { name: "height"; type: "int"; value: 300; } + } + } + + Type { + name: "QtQuick.Flipable" + icon: ":/qtquickplugin/images/flipable-icon16.png" + + ItemLibraryEntry { + name: "Flipable" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/flipable-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 200; } + } + + ItemLibraryEntry { + name: "Flipable" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/flipable-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 200; } + } + } + + Type { + name: "QtQuick.GridView" + icon: ":/qtquickplugin/images/gridview-icon16.png" + + ItemLibraryEntry { + name: "Grid View" + category: "Qt Quick - Views" + libraryIcon: ":/qtquickplugin/images/gridview-icon.png" + version: "1.0" + + QmlSource { source: ":/qtquickplugin/source/gridview.qml" } + } + + ItemLibraryEntry { + name: "Grid View" + category: "Qt Quick - Views" + libraryIcon: ":/qtquickplugin/images/gridview-icon.png" + version: "2.0" + + QmlSource { source: ":/qtquickplugin/source/gridviewv2.qml" } + } + } + + Type { + name: "QtQuick.ListView" + icon: ":/qtquickplugin/images/listview-icon16.png" + + ItemLibraryEntry { + name: "List View" + category: "Qt Quick - Views" + libraryIcon: ":/qtquickplugin/images/pathview-icon.png" + version: "1.0" + + QmlSource { source: ":/qtquickplugin/source/listview.qml" } + } + + ItemLibraryEntry { + name: "List View" + category: "Qt Quick - Views" + libraryIcon: ":/qtquickplugin/images/pathview-icon.png" + version: "2.0" + + QmlSource { source: ":/qtquickplugin/source/listviewv2.qml" } + } + } + + Type { + name: "QtQuick.PathView" + icon: ":/qtquickplugin/images/pathview-icon16.png" + + ItemLibraryEntry { + name: "Path View" + category: "Qt Quick - Views" + libraryIcon: ":/qtquickplugin/images/pathview-icon.png" + version: "1.0" + + QmlSource { source: ":/qtquickplugin/source/pathview.qml" } + } + + ItemLibraryEntry { + name: "Path View" + category: "Qt Quick - Views" + libraryIcon: ":/qtquickplugin/images/pathview-icon.png" + version: "2.0" + + QmlSource { source: ":/qtquickplugin/source/pathviewv2.qml" } + } + } + + Type { + name: "QtQuick.FocusScope" + icon: ":/qtquickplugin/images/focusscope-icon16.png" + + ItemLibraryEntry { + name: "Focus Scope" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/focusscope-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "height"; type: "int"; value: 100; } + } + + ItemLibraryEntry { + name: "Focus Scope" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/focusscope-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 100; } + Property { name: "height"; type: "int"; value: 100; } + } + } + + Type { + name: "QtWebKit.WebView" + icon: ":/qtquickplugin/images/webview-icon16.png" + + ItemLibraryEntry { + name: "Web View" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/webview-icon.png" + version: "1.0" + requiredImport: "QtWebKit" + forceImport: "true" + + Property { name: "width"; type: "int"; value: 300; } + Property { name: "height"; type: "int"; value: 300; } + Property { name: "url"; type: "QString"; value: "qrc:/qtquickplugin/html/welcome.html" } + } + + ItemLibraryEntry { + name: "Web View" + category: "Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/webview-icon.png" + version: "2.0" + requiredImport: "QtWebKit" + forceImport: "true" + + Property { name: "width"; type: "int"; value: 300; } + Property { name: "height"; type: "int"; value: 300; } + Property { name: "url"; type: "QString"; value: "qrc:/qtquickplugin/html/welcome.html" } + } + } + + Type { + name: "QtQuick.Column" + icon: ":/qtquickplugin/images/item-icon16.png" + + ItemLibraryEntry { + name: "Column" + category: "Qt Quick - Positioner" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 400; } + } + + ItemLibraryEntry { + name: "Column" + category: "Qt Quick - Positioner" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 200; } + Property { name: "height"; type: "int"; value: 400; } + } + } + + Type { + name: "QtQuick.Grid" + icon: ":/qtquickplugin/images/item-icon16.png" + + ItemLibraryEntry { + name: "Grid" + category: "Qt Quick - Positioner" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 400; } + Property { name: "height"; type: "int"; value: 400; } + } + + ItemLibraryEntry { + name: "Grid" + category: "Qt Quick - Positioner" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 400; } + Property { name: "height"; type: "int"; value: 400; } + } + } + + Type { + name: "QtQuick.Flow" + icon: ":/qtquickplugin/images/item-icon16.png" + + ItemLibraryEntry { + name: "Flow" + category: "Qt Quick - Positioner" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "1.0" + + Property { name: "width"; type: "int"; value: 400; } + Property { name: "height"; type: "int"; value: 400; } + } + + ItemLibraryEntry { + name: "Flow" + category: "Qt Quick - Positioner" + libraryIcon: ":/qtquickplugin/images/item-icon.png" + version: "2.0" + + Property { name: "width"; type: "int"; value: 400; } + Property { name: "height"; type: "int"; value: 400; } + } + } +} diff --git a/src/plugins/qmldesigner/qtquickplugin/source/gridviewv2.qml b/src/plugins/qmldesigner/qtquickplugin/source/gridviewv2.qml new file mode 100644 index 0000000000..9532a65daf --- /dev/null +++ b/src/plugins/qmldesigner/qtquickplugin/source/gridviewv2.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import QtQuick 2.0 + +GridView { + width: 140 + height: 140 + cellWidth: 70 + cellHeight: 70 + + model: ListModel { + + ListElement { + name: "Grey" + colorCode: "grey" + + } + + ListElement { + name: "Red" + colorCode: "red" + + } + + ListElement { + name: "Blue" + colorCode: "blue" + + } + + ListElement { + name: "Green" + colorCode: "green" + + } + } + + delegate: Item { + height: 50 + x: 5 + + Column { + spacing: 5 + Rectangle { + width: 40 + height: 40 + color: colorCode + anchors.horizontalCenter: parent.horizontalCenter + } + + Text { + x: 5 + text: name + anchors.horizontalCenter: parent.horizontalCenter + font.bold: true + } + + } + } +} diff --git a/src/plugins/qmldesigner/qtquickplugin/source/listviewv2.qml b/src/plugins/qmldesigner/qtquickplugin/source/listviewv2.qml new file mode 100644 index 0000000000..70338dfde1 --- /dev/null +++ b/src/plugins/qmldesigner/qtquickplugin/source/listviewv2.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import QtQuick 2.0 + +ListView { + width: 110 + height: 160 + model: ListModel { + ListElement { + name: "Grey" + colorCode: "grey" + } + ListElement { + name: "Red" + colorCode: "red" + } + ListElement { + name: "Blue" + colorCode: "blue" + } + ListElement { + name: "Green" + colorCode: "green" + } + } + + delegate: Item { + height: 40 + x: 5 + Row { + id: row1 + spacing: 10 + Rectangle { width: 40; height: 40; color: colorCode; } + Text { + text: name + anchors.verticalCenter: parent.verticalCenter + font.bold: true + } + } + } +} diff --git a/src/plugins/qmldesigner/qtquickplugin/source/pathviewv2.qml b/src/plugins/qmldesigner/qtquickplugin/source/pathviewv2.qml new file mode 100644 index 0000000000..97fbf887a5 --- /dev/null +++ b/src/plugins/qmldesigner/qtquickplugin/source/pathviewv2.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import QtQuick 2.0 + +PathView { + width: 250 + height: 130 + + path: Path { + startX: 120 + startY: 100 + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 } + } + model: ListModel { + ListElement { + name: "Grey" + colorCode: "grey" + } + ListElement { + name: "Red" + colorCode: "red" + } + ListElement { + name: "Blue" + colorCode: "blue" + } + ListElement { + name: "Green" + colorCode: "green" + } + } + delegate: Component { + Column { + spacing: 5 + Rectangle { + width: 40 + height: 40 + color: colorCode + anchors.horizontalCenter: parent.horizontalCenter + } + Text { + x: 5 + text: name + anchors.horizontalCenter: parent.horizontalCenter + font.bold: true + } + } + } +} + diff --git a/src/plugins/qmldesigner/qtquickplugin/source/texteditv2.qml b/src/plugins/qmldesigner/qtquickplugin/source/texteditv2.qml new file mode 100644 index 0000000000..6c72cb2e7b --- /dev/null +++ b/src/plugins/qmldesigner/qtquickplugin/source/texteditv2.qml @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import QtQuick 2.0 + +TextEdit { + width: 80 + height: 20 + text: qsTr("text edit") + font.pixelSize: 12 +} diff --git a/src/plugins/qmldesigner/qtquickplugin/source/textinputv2.qml b/src/plugins/qmldesigner/qtquickplugin/source/textinputv2.qml new file mode 100644 index 0000000000..0a4772bc88 --- /dev/null +++ b/src/plugins/qmldesigner/qtquickplugin/source/textinputv2.qml @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import QtQuick 2.0 + +TextInput { + width: 80 + height: 20 + text: qsTr("text") + font.pixelSize: 12 +} diff --git a/src/plugins/qmldesigner/qtquickplugin/source/textv2.qml b/src/plugins/qmldesigner/qtquickplugin/source/textv2.qml new file mode 100644 index 0000000000..40d59d7145 --- /dev/null +++ b/src/plugins/qmldesigner/qtquickplugin/source/textv2.qml @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import QtQuick 2.0 + +Text { + text: qsTr("text") + font.pixelSize: 12 +} diff --git a/src/plugins/qmldesigner/settingspage.cpp b/src/plugins/qmldesigner/settingspage.cpp index 475b664662..f84b84c16c 100644 --- a/src/plugins/qmldesigner/settingspage.cpp +++ b/src/plugins/qmldesigner/settingspage.cpp @@ -53,6 +53,9 @@ DesignerSettings SettingsPageWidget::settings() const ds.snapMargin = m_ui.spinSnapMargin->value(); ds.canvasWidth = m_ui.spinCanvasWidth->value(); ds.canvasHeight = m_ui.spinCanvasHeight->value(); + ds.warningsInDesigner = m_ui.designerWarningsCheckBox->isChecked(); + ds.designerWarningsInEditor = m_ui.designerWarningsInEditorCheckBox->isChecked(); + return ds; } @@ -62,6 +65,8 @@ void SettingsPageWidget::setSettings(const DesignerSettings &s) m_ui.spinSnapMargin->setValue(s.snapMargin); m_ui.spinCanvasWidth->setValue(s.canvasWidth); m_ui.spinCanvasHeight->setValue(s.canvasHeight); + m_ui.designerWarningsCheckBox->setChecked(s.warningsInDesigner); + m_ui.designerWarningsInEditorCheckBox->setChecked(s.designerWarningsInEditor); } QString SettingsPageWidget::searchKeywords() const diff --git a/src/plugins/qmldesigner/settingspage.ui b/src/plugins/qmldesigner/settingspage.ui index a98006ba46..3bbf633e01 100644 --- a/src/plugins/qmldesigner/settingspage.ui +++ b/src/plugins/qmldesigner/settingspage.ui @@ -6,15 +6,15 @@ <rect> <x>0</x> <y>0</y> - <width>275</width> - <height>275</height> + <width>574</width> + <height>472</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> <widget class="QGroupBox" name="groupBox_3"> <property name="title"> <string>Snapping</string> @@ -67,7 +67,7 @@ </layout> </widget> </item> - <item> + <item row="1" column="0"> <widget class="QGroupBox" name="groupBox"> <property name="title"> <string>Canvas</string> @@ -132,7 +132,40 @@ </layout> </widget> </item> - <item> + <item row="2" column="0"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Warnings</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <layout class="QFormLayout" name="formLayout_3"> + <item row="0" column="1"> + <widget class="QCheckBox" name="designerWarningsCheckBox"> + <property name="toolTip"> + <string>Warn about QML features which are not properly supported by the Qt Quick Designer</string> + </property> + <property name="text"> + <string>Warn about unsupported features in the Qt Quick Designer</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QCheckBox" name="designerWarningsInEditorCheckBox"> + <property name="toolTip"> + <string>Also warn in the code editor about QML features which are not properly supported by the Qt Quick Designer</string> + </property> + <property name="text"> + <string>Warn about unsupported features of Qt Quick Designer in the code editor</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item row="3" column="1"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp index 13132a137e..1b97214f45 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp @@ -122,8 +122,7 @@ public: } QString replacement = componentName + QLatin1String(" {\n"); if (!m_idName.isEmpty()) - replacement += QLatin1String("id: ") + m_idName - + QLatin1Char('\n'); + replacement += QLatin1String("id: ") + m_idName + QLatin1Char('\n'); Utils::ChangeSet changes; changes.replace(start, end, replacement); @@ -136,8 +135,7 @@ public: } // end of anonymous namespace -QList<QmlJSQuickFixOperation::Ptr> ComponentFromObjectDef::match( - const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface) +void ComponentFromObjectDef::match(const QmlJSQuickFixInterface &interface, QuickFixOperations &result) { const int pos = interface->currentFile()->cursor().position(); @@ -146,13 +144,12 @@ QList<QmlJSQuickFixOperation::Ptr> ComponentFromObjectDef::match( Node *node = path.at(i); if (UiObjectDefinition *objDef = cast<UiObjectDefinition *>(node)) { if (!interface->currentFile()->isCursorOn(objDef->qualifiedTypeNameId)) - return noResult(); + return; // check that the node is not the root node if (i > 0 && !cast<UiProgram*>(path.at(i - 1))) { - return singleResult(new Operation(interface, objDef)); + result.append(QuickFixOperation::Ptr(new Operation(interface, objDef))); + return; } } } - - return noResult(); } diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.h b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.h index 6bbe68d51e..c9378d490b 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.h +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.h @@ -38,8 +38,7 @@ namespace Internal { class ComponentFromObjectDef: public QmlJSQuickFixFactory { public: - virtual QList<QmlJSQuickFixOperation::Ptr> match( - const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface); + void match(const QmlJSQuickFixInterface &interface, QuickFixOperations &result); }; } // namespace Internal diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index b7784c42bf..9e8a6513d3 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -580,7 +580,7 @@ Core::IEditor *QmlJSEditorEditable::duplicate(QWidget *parent) Core::Id QmlJSEditorEditable::id() const { - return QmlJSEditor::Constants::C_QMLJSEDITOR_ID; + return Core::Id(QmlJSEditor::Constants::C_QMLJSEDITOR_ID); } bool QmlJSEditorEditable::open(QString *errorString, const QString &fileName, const QString &realFileName) diff --git a/src/plugins/qmljseditor/qmljseditor.qbs b/src/plugins/qmljseditor/qmljseditor.qbs index b78578ca99..9e81ca3ca3 100644 --- a/src/plugins/qmljseditor/qmljseditor.qbs +++ b/src/plugins/qmljseditor/qmljseditor.qbs @@ -18,16 +18,8 @@ QtcPlugin { Depends { name: "cpp" } cpp.defines: base.concat(["QT_CREATOR"]) - cpp.includePaths: [ - ".", - "..", - "../../libs", - buildDirectory - ] files: [ - "qmljseditor.qrc", - "quicktoolbarsettingspage.ui", "QmlJSEditor.mimetypes.xml", "jsfilewizard.cpp", "jsfilewizard.h", @@ -46,6 +38,7 @@ QtcPlugin { "qmljscomponentnamedialog.ui", "qmljseditor.cpp", "qmljseditor.h", + "qmljseditor.qrc", "qmljseditor_global.h", "qmljseditoractionhandler.cpp", "qmljseditoractionhandler.h", @@ -82,6 +75,7 @@ QtcPlugin { "qmljssnippetprovider.cpp", "qmljssnippetprovider.h", "qmljswrapinloader.cpp", + "qmljswrapinloader.h", "qmloutlinemodel.cpp", "qmloutlinemodel.h", "qmltaskmanager.cpp", @@ -90,12 +84,11 @@ QtcPlugin { "quicktoolbar.h", "quicktoolbarsettingspage.cpp", "quicktoolbarsettingspage.h", - "qmljswrapinloader.h", - "images/qmlfile.png" + "quicktoolbarsettingspage.ui", + "images/qmlfile.png", ] ProductModule { Depends { name: "QmlJSTools" } } } - diff --git a/src/plugins/qmljseditor/qmljseditoreditable.cpp b/src/plugins/qmljseditor/qmljseditoreditable.cpp index 5a60f5c91a..e80ee04b12 100644 --- a/src/plugins/qmljseditor/qmljseditoreditable.cpp +++ b/src/plugins/qmljseditor/qmljseditoreditable.cpp @@ -85,7 +85,7 @@ Core::Id QmlJSEditorEditable::preferredModeType() const // have the user also access to this failsafe setting. if (editorWidget()->mimeType() == QLatin1String(QmlJSTools::Constants::QML_MIMETYPE) && openInDesignMode()) - return Core::Constants::MODE_DESIGN_TYPE; + return Core::Id(Core::Constants::MODE_DESIGN_TYPE); return Core::Id(); } diff --git a/src/plugins/qmljseditor/qmljseditorfactory.cpp b/src/plugins/qmljseditor/qmljseditorfactory.cpp index c42ce5ff81..17a9841b5f 100644 --- a/src/plugins/qmljseditor/qmljseditorfactory.cpp +++ b/src/plugins/qmljseditor/qmljseditorfactory.cpp @@ -66,7 +66,7 @@ QmlJSEditorFactory::QmlJSEditorFactory(QObject *parent) Core::Id QmlJSEditorFactory::id() const { - return C_QMLJSEDITOR_ID; + return Core::Id(C_QMLJSEDITOR_ID); } QString QmlJSEditorFactory::displayName() const diff --git a/src/plugins/qmljseditor/qmljspreviewrunner.cpp b/src/plugins/qmljseditor/qmljspreviewrunner.cpp index 5fb75a77ef..07e2a044f3 100644 --- a/src/plugins/qmljseditor/qmljspreviewrunner.cpp +++ b/src/plugins/qmljseditor/qmljspreviewrunner.cpp @@ -30,6 +30,7 @@ #include "qmljspreviewrunner.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <utils/qtcprocess.h> #include <utils/synchronousprocess.h> @@ -46,7 +47,7 @@ QmlJSPreviewRunner::QmlJSPreviewRunner(QObject *parent) : { // prepend creator/bin dir to search path (only useful for special creator-qml package) const QString searchPath = QCoreApplication::applicationDirPath() - + Utils::SynchronousProcess::pathSeparator() + + Utils::HostOsInfo::pathListSeparator() + QString(qgetenv("PATH")); m_qmlViewerDefaultPath = Utils::SynchronousProcess::locateBinary(searchPath, QLatin1String("qmlviewer")); diff --git a/src/plugins/qmljseditor/qmljsquickfix.cpp b/src/plugins/qmljseditor/qmljsquickfix.cpp index 063bf7ce2d..6952c24e91 100644 --- a/src/plugins/qmljseditor/qmljsquickfix.cpp +++ b/src/plugins/qmljseditor/qmljsquickfix.cpp @@ -45,21 +45,15 @@ using namespace QmlJS::AST; using namespace QmlJSEditor; using namespace QmlJSEditor::Internal; using namespace QmlJSTools; -using namespace TextEditor; using TextEditor::RefactoringChanges; -QmlJSQuickFixOperation::QmlJSQuickFixOperation( - const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface, - int priority) +QmlJSQuickFixOperation::QmlJSQuickFixOperation(const QmlJSQuickFixInterface &interface, + int priority) : QuickFixOperation(priority) , m_interface(interface) { } -QmlJSQuickFixOperation::~QmlJSQuickFixOperation() -{ -} - void QmlJSQuickFixOperation::perform() { QmlJSRefactoringChanges refactoring(QmlJS::ModelManagerInterface::instance(), @@ -79,28 +73,9 @@ QString QmlJSQuickFixOperation::fileName() const return m_interface->semanticInfo().document->fileName(); } -QmlJSQuickFixFactory::QmlJSQuickFixFactory() -{ -} - -QmlJSQuickFixFactory::~QmlJSQuickFixFactory() -{ -} - -QList<QuickFixOperation::Ptr> QmlJSQuickFixFactory::matchingOperations( - const QSharedPointer<const TextEditor::IAssistInterface> &interface) -{ - return match(interface.staticCast<const QmlJSQuickFixAssistInterface>()); -} - -QList<QmlJSQuickFixOperation::Ptr> QmlJSQuickFixFactory::noResult() -{ - return QList<QmlJSQuickFixOperation::Ptr>(); -} -QList<QmlJSQuickFixOperation::Ptr> QmlJSQuickFixFactory::singleResult(QmlJSQuickFixOperation *operation) +void QmlJSQuickFixFactory::matchingOperations(const QuickFixInterface &interface, + QuickFixOperations &result) { - QList<QmlJSQuickFixOperation::Ptr> result; - result.append(QmlJSQuickFixOperation::Ptr(operation)); - return result; + match(interface.staticCast<const QmlJSQuickFixAssistInterface>(), result); } diff --git a/src/plugins/qmljseditor/qmljsquickfix.h b/src/plugins/qmljseditor/qmljsquickfix.h index b0e7e0f3dc..83c7fa6f3a 100644 --- a/src/plugins/qmljseditor/qmljsquickfix.h +++ b/src/plugins/qmljseditor/qmljsquickfix.h @@ -39,20 +39,16 @@ #include <QSharedPointer> -namespace ExtensionSystem { -class IPlugin; -} - -namespace QmlJS { - class ModelManagerInterface; -} +namespace QmlJS { class ModelManagerInterface; } namespace QmlJSEditor { -namespace Internal { -class QmlJSQuickFixAssistInterface; -} // namespace Internal +namespace Internal { class QmlJSQuickFixAssistInterface; } +typedef QSharedPointer<const Internal::QmlJSQuickFixAssistInterface> QmlJSQuickFixInterface; +typedef TextEditor::QuickFixOperation QuickFixOperation; +typedef TextEditor::QuickFixOperations QuickFixOperations; +typedef TextEditor::QuickFixInterface QuickFixInterface; /*! A quick-fix operation for the QML/JavaScript editor. @@ -66,10 +62,7 @@ public: \param interface The interface on which the operation is performed. \param priority The priority for this operation. */ - explicit QmlJSQuickFixOperation( - const QSharedPointer<const Internal::QmlJSQuickFixAssistInterface> &interface, - int priority = -1); - virtual ~QmlJSQuickFixOperation(); + explicit QmlJSQuickFixOperation(const QmlJSQuickFixInterface &interface, int priority = -1); virtual void perform(); @@ -85,29 +78,23 @@ protected: QString fileName() const; private: - QSharedPointer<const Internal::QmlJSQuickFixAssistInterface> m_interface; + QmlJSQuickFixInterface m_interface; }; class QmlJSQuickFixFactory: public TextEditor::QuickFixFactory { Q_OBJECT -public: - QmlJSQuickFixFactory(); - virtual ~QmlJSQuickFixFactory(); +protected: + QmlJSQuickFixFactory() {} - virtual QList<TextEditor::QuickFixOperation::Ptr> - matchingOperations(const QSharedPointer<const TextEditor::IAssistInterface> &interface); + void matchingOperations(const QuickFixInterface &interface, QuickFixOperations &result); /*! Implement this method to match and create the appropriate QmlJSQuickFixOperation objects. */ - virtual QList<QmlJSQuickFixOperation::Ptr> match( - const QSharedPointer<const Internal::QmlJSQuickFixAssistInterface> &interface) = 0; - - static QList<QmlJSQuickFixOperation::Ptr> noResult(); - static QList<QmlJSQuickFixOperation::Ptr> singleResult(QmlJSQuickFixOperation *operation); + virtual void match(const QmlJSQuickFixInterface &interface, TextEditor::QuickFixOperations &result) = 0; }; } // namespace QmlJSEditor diff --git a/src/plugins/qmljseditor/qmljsquickfixes.cpp b/src/plugins/qmljseditor/qmljsquickfixes.cpp index 9806109fba..9583331be7 100644 --- a/src/plugins/qmljseditor/qmljsquickfixes.cpp +++ b/src/plugins/qmljseditor/qmljsquickfixes.cpp @@ -45,7 +45,6 @@ using namespace QmlJS::AST; using namespace QmlJSEditor; using namespace QmlJSEditor::Internal; using namespace QmlJSTools; -using namespace TextEditor; using TextEditor::RefactoringChanges; namespace { @@ -62,9 +61,7 @@ namespace { */ class SplitInitializerOp: public QmlJSQuickFixFactory { -public: - virtual QList<QmlJSQuickFixOperation::Ptr> match( - const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface) + void match(const QmlJSQuickFixInterface &interface, QuickFixOperations &result) { UiObjectInitializer *objectInitializer = 0; @@ -82,12 +79,9 @@ public: } if (objectInitializer) - return singleResult(new Operation(interface, objectInitializer)); - else - return noResult(); + result.append(TextEditor::QuickFixOperation::Ptr(new Operation(interface, objectInitializer))); } -private: class Operation: public QmlJSQuickFixOperation { UiObjectInitializer *_objectInitializer; @@ -102,7 +96,7 @@ private: "Split Initializer")); } - virtual void performChanges(QmlJSRefactoringFilePtr currentFile, + void performChanges(QmlJSRefactoringFilePtr currentFile, const QmlJSRefactoringChanges &) { Q_ASSERT(_objectInitializer != 0); @@ -137,18 +131,16 @@ class AddAnalysisMessageSuppressionComment: public QmlJSQuickFixFactory { Q_DECLARE_TR_FUNCTIONS(QmlJSEditor::AddAnalysisMessageSuppressionComment) public: - virtual QList<QmlJSQuickFixOperation::Ptr> match( - const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface) + void match(const QmlJSQuickFixInterface &interface, QuickFixOperations &result) { const QList<StaticAnalysis::Message> &messages = interface->semanticInfo().staticAnalysisMessages; foreach (const StaticAnalysis::Message &message, messages) { if (interface->currentFile()->isCursorOn(message.location)) { - return singleResult(new Operation(interface, message)); + result.append(QuickFixOperation::Ptr(new Operation(interface, message))); + return; } } - - return noResult(); } private: diff --git a/src/plugins/qmljseditor/qmljswrapinloader.cpp b/src/plugins/qmljseditor/qmljswrapinloader.cpp index f5495ded27..87b2f003a9 100644 --- a/src/plugins/qmljseditor/qmljswrapinloader.cpp +++ b/src/plugins/qmljseditor/qmljswrapinloader.cpp @@ -173,8 +173,7 @@ public: } // end of anonymous namespace -QList<QmlJSQuickFixOperation::Ptr> WrapInLoader::match( - const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface) +void WrapInLoader::match(const QmlJSQuickFixInterface &interface, QuickFixOperations &result) { const int pos = interface->currentFile()->cursor().position(); @@ -183,13 +182,12 @@ QList<QmlJSQuickFixOperation::Ptr> WrapInLoader::match( Node *node = path.at(i); if (UiObjectDefinition *objDef = cast<UiObjectDefinition *>(node)) { if (!interface->currentFile()->isCursorOn(objDef->qualifiedTypeNameId)) - return noResult(); + return; // check that the node is not the root node if (i > 0 && !cast<UiProgram*>(path.at(i - 1))) { - return singleResult(new Operation(interface, objDef)); + result.append(QuickFixOperation::Ptr(new Operation(interface, objDef))); + return; } } } - - return noResult(); } diff --git a/src/plugins/qmljseditor/qmljswrapinloader.h b/src/plugins/qmljseditor/qmljswrapinloader.h index aaff910c44..ea2c28fa24 100644 --- a/src/plugins/qmljseditor/qmljswrapinloader.h +++ b/src/plugins/qmljseditor/qmljswrapinloader.h @@ -37,9 +37,7 @@ namespace Internal { class WrapInLoader: public QmlJSQuickFixFactory { -public: - virtual QList<QmlJSQuickFixOperation::Ptr> match( - const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface); + void match(const QmlJSQuickFixInterface &interface, QuickFixOperations &result); }; } // namespace Internal diff --git a/src/plugins/qmljseditor/quicktoolbar.cpp b/src/plugins/qmljseditor/quicktoolbar.cpp index 028587c7db..79a5323221 100644 --- a/src/plugins/qmljseditor/quicktoolbar.cpp +++ b/src/plugins/qmljseditor/quicktoolbar.cpp @@ -28,10 +28,11 @@ ****************************************************************************/ #include "quicktoolbar.h" -#include <contextpanewidget.h> -#include <quicktoolbarsettingspage.h> +#include "quicktoolbarsettingspage.h" #include <utils/changeset.h> +#include <qmleditorwidgets/contextpanewidget.h> +#include <qmleditorwidgets/customcolordialog.h> #include <qmljs/parser/qmljsast_p.h> #include <qmljs/qmljsdocument.h> #include <qmljs/qmljspropertyreader.h> @@ -45,7 +46,6 @@ #include <texteditor/basetexteditor.h> #include <texteditor/tabsettings.h> #include <coreplugin/icore.h> -#include <customcolordialog.h> #include <QDebug> @@ -122,7 +122,7 @@ QuickToolBar::~QuickToolBar() //if the pane was never activated the widget is not in a widget tree if (!m_widget.isNull()) delete m_widget.data(); - m_widget.clear(); + m_widget = 0; } void QuickToolBar::apply(TextEditor::BaseTextEditor *editor, Document::Ptr document, const ScopeChain *scopeChain, AST::Node *node, bool update, bool force) @@ -213,7 +213,7 @@ void QuickToolBar::apply(TextEditor::BaseTextEditor *editor, Document::Ptr docum rect.setHeight(widget()->height() + 10); rect.setWidth(reg.boundingRect().width() - reg.boundingRect().left()); rect.moveTo(reg.boundingRect().topLeft()); - reg = reg.intersect(rect); + reg = reg.intersected(rect); if (contextWidget()->acceptsType(m_prototypes)) { m_node = 0; diff --git a/src/plugins/qmljseditor/quicktoolbar.h b/src/plugins/qmljseditor/quicktoolbar.h index 76d4bb58c7..acd6e7ab45 100644 --- a/src/plugins/qmljseditor/quicktoolbar.h +++ b/src/plugins/qmljseditor/quicktoolbar.h @@ -32,6 +32,8 @@ #include <qmljs/qmljsicontextpane.h> +#include <QPointer> + namespace TextEditor { class BaseTextEditor; } @@ -65,7 +67,7 @@ public slots: private: QmlEditorWidgets::ContextPaneWidget* contextWidget(); - QWeakPointer<QmlEditorWidgets::ContextPaneWidget> m_widget; + QPointer<QmlEditorWidgets::ContextPaneWidget> m_widget; QmlJS::Document::Ptr m_doc; QmlJS::AST::Node *m_node; TextEditor::BaseTextEditor *m_editor; diff --git a/src/plugins/debugger/images/collapse.png b/src/plugins/qmljstools/images/collapse.png Binary files differindex 64ae3720c1..64ae3720c1 100644 --- a/src/plugins/debugger/images/collapse.png +++ b/src/plugins/qmljstools/images/collapse.png diff --git a/src/plugins/debugger/images/error.png b/src/plugins/qmljstools/images/error.png Binary files differindex 39768b9f39..39768b9f39 100644 --- a/src/plugins/debugger/images/error.png +++ b/src/plugins/qmljstools/images/error.png diff --git a/src/plugins/debugger/images/expand.png b/src/plugins/qmljstools/images/expand.png Binary files differindex 7959bfc97e..7959bfc97e 100644 --- a/src/plugins/debugger/images/expand.png +++ b/src/plugins/qmljstools/images/expand.png diff --git a/src/plugins/debugger/images/log.png b/src/plugins/qmljstools/images/log.png Binary files differindex e4766f228b..e4766f228b 100644 --- a/src/plugins/debugger/images/log.png +++ b/src/plugins/qmljstools/images/log.png diff --git a/src/plugins/debugger/images/prompt.png b/src/plugins/qmljstools/images/prompt.png Binary files differindex a333a87198..a333a87198 100644 --- a/src/plugins/debugger/images/prompt.png +++ b/src/plugins/qmljstools/images/prompt.png diff --git a/src/plugins/debugger/images/warning.png b/src/plugins/qmljstools/images/warning.png Binary files differindex 3200efc4fd..3200efc4fd 100644 --- a/src/plugins/debugger/images/warning.png +++ b/src/plugins/qmljstools/images/warning.png diff --git a/src/plugins/debugger/qtmessagelogeditor.cpp b/src/plugins/qmljstools/qmlconsoleedit.cpp index 07043259e4..e53297b8c3 100644 --- a/src/plugins/debugger/qtmessagelogeditor.cpp +++ b/src/plugins/qmljstools/qmlconsoleedit.cpp @@ -27,11 +27,9 @@ ** ****************************************************************************/ -#include "qtmessagelogeditor.h" -#include "qtmessageloghandler.h" -#include "debuggerstringutils.h" -#include "debuggercore.h" -#include "debuggerengine.h" +#include "qmlconsoleedit.h" +#include "qmlconsoleitemmodel.h" +#include "qmlconsolemanager.h" #include <utils/qtcassert.h> @@ -39,54 +37,58 @@ #include <QMenu> #include <QKeyEvent> -namespace Debugger { +using namespace QmlJS; + +namespace QmlJSTools { namespace Internal { /////////////////////////////////////////////////////////////////////// // -// QtMessageLogEditor +// QmlConsoleEdit // /////////////////////////////////////////////////////////////////////// -QtMessageLogEditor::QtMessageLogEditor(const QModelIndex &index, - QWidget *parent) : +QmlConsoleEdit::QmlConsoleEdit(const QModelIndex &index, QWidget *parent) : QTextEdit(parent), m_historyIndex(index), - m_prompt(_(":/debugger/images/prompt.png")), + m_prompt(QLatin1String(":/qmljstools/images/prompt.png")), m_startOfEditableArea(0) { setFrameStyle(QFrame::NoFrame); setUndoRedoEnabled(false); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - document()->addResource(QTextDocument::ImageResource, - QUrl(_("prompt")), m_prompt); + document()->addResource(QTextDocument::ImageResource, QUrl(QLatin1String("prompt")), m_prompt); QTextImageFormat format; - format.setName(_("prompt")); + format.setName(QLatin1String("prompt")); format.setHeight(9); format.setWidth(9); - textCursor().insertText(_(" ")); + textCursor().insertText(QLatin1String(" ")); textCursor().insertImage(format); - textCursor().insertText(_(" ")); + textCursor().insertText(QLatin1String(" ")); m_startOfEditableArea = textCursor().position(); ensureCursorVisible(); setTextInteractionFlags(Qt::TextEditorInteraction); } -void QtMessageLogEditor::keyPressEvent(QKeyEvent *e) +void QmlConsoleEdit::keyPressEvent(QKeyEvent *e) { bool keyConsumed = false; switch (e->key()) { case Qt::Key_Return: case Qt::Key_Enter: { - keyConsumed = debuggerCore()->evaluateScriptExpression(getCurrentScript()); - if (keyConsumed) { + m_interpreter.clearText(); + QString currentScript = getCurrentScript(); + m_interpreter.appendText(currentScript); + if (currentScript.isEmpty()) { + emit editingFinished(); + } else if (m_interpreter.canEvaluate()) { + QmlConsoleModel::evaluate(currentScript); emit editingFinished(); - debuggerCore()->currentEngine()->qtMessageLogHandler()->appendEditableRow(); } - } break; + } case Qt::Key_Backspace: if (textCursor().selectionStart() <= m_startOfEditableArea) @@ -98,14 +100,13 @@ void QtMessageLogEditor::keyPressEvent(QKeyEvent *e) keyConsumed = true; break; - case Qt::Key_Home: - { + case Qt::Key_Home: { QTextCursor c(textCursor()); c.setPosition(m_startOfEditableArea); setTextCursor(c); keyConsumed = true; - } break; + } case Qt::Key_Up: handleUpKey(); @@ -160,10 +161,9 @@ void QtMessageLogEditor::keyPressEvent(QKeyEvent *e) QTextEdit::keyPressEvent(e); } -void QtMessageLogEditor::contextMenuEvent(QContextMenuEvent *event) +void QmlConsoleEdit::contextMenuEvent(QContextMenuEvent *event) { - //TODO:: on right click the editor closes - //FIXIT + // TODO:: on right click the editor closes return QTextEdit::contextMenuEvent(event); QTextCursor cursor = textCursor(); @@ -192,12 +192,12 @@ void QtMessageLogEditor::contextMenuEvent(QContextMenuEvent *event) delete menu; } -void QtMessageLogEditor::focusOutEvent(QFocusEvent * /*e*/) +void QmlConsoleEdit::focusOutEvent(QFocusEvent * /*e*/) { emit editingFinished(); } -void QtMessageLogEditor::handleUpKey() +void QmlConsoleEdit::handleUpKey() { QTC_ASSERT(m_historyIndex.isValid(), return); int currentRow = m_historyIndex.row(); @@ -209,19 +209,17 @@ void QtMessageLogEditor::handleUpKey() currentRow--; if (model->hasIndex(currentRow, 0)) { QModelIndex index = model->index(currentRow, 0); - if (QtMessageLogHandler::InputType == (QtMessageLogHandler::ItemType)model->data( - index, QtMessageLogHandler::TypeRole).toInt()) { + if (ConsoleItem::InputType == (ConsoleItem::ItemType)model->data( + index, QmlConsoleItemModel::TypeRole).toInt()) { m_historyIndex = index; - replaceCurrentScript(model->data( - index, Qt::DisplayRole). - toString()); + replaceCurrentScript(model->data(index, Qt::DisplayRole).toString()); break; } } } } -void QtMessageLogEditor::handleDownKey() +void QmlConsoleEdit::handleDownKey() { QTC_ASSERT(m_historyIndex.isValid(), return); int currentRow = m_historyIndex.row(); @@ -230,32 +228,29 @@ void QtMessageLogEditor::handleDownKey() currentRow++; if (model->hasIndex(currentRow, 0)) { QModelIndex index = model->index(currentRow, 0); - if (QtMessageLogHandler::InputType == (QtMessageLogHandler::ItemType)model->data( - index, QtMessageLogHandler::TypeRole).toInt()) { + if (ConsoleItem::InputType == (ConsoleItem::ItemType)model->data( + index, QmlConsoleItemModel::TypeRole).toInt()) { m_historyIndex = index; if (currentRow == model->rowCount() - 1) replaceCurrentScript(m_cachedScript); else - replaceCurrentScript(model->data( - index, Qt::DisplayRole). - toString()); + replaceCurrentScript(model->data(index, Qt::DisplayRole).toString()); break; } } } } -QString QtMessageLogEditor::getCurrentScript() const +QString QmlConsoleEdit::getCurrentScript() const { QTextCursor cursor = textCursor(); cursor.setPosition(m_startOfEditableArea); cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); QString script = cursor.selectedText(); - //remove WS return script.trimmed(); } -void QtMessageLogEditor::replaceCurrentScript(const QString &script) +void QmlConsoleEdit::replaceCurrentScript(const QString &script) { QTextCursor cursor = textCursor(); cursor.setPosition(m_startOfEditableArea); @@ -265,5 +260,5 @@ void QtMessageLogEditor::replaceCurrentScript(const QString &script) setTextCursor(cursor); } -} //Internal -} //Debugger +} // Internal +} // QmlJSTools diff --git a/src/plugins/debugger/qtmessagelogeditor.h b/src/plugins/qmljstools/qmlconsoleedit.h index 798017b096..00c7259080 100644 --- a/src/plugins/debugger/qtmessagelogeditor.h +++ b/src/plugins/qmljstools/qmlconsoleedit.h @@ -27,21 +27,22 @@ ** ****************************************************************************/ -#ifndef QTMESSAGELOGEDITOR_H -#define QTMESSAGELOGEDITOR_H +#ifndef QMLCONSOLEEDIT_H +#define QMLCONSOLEEDIT_H + +#include "qmljsinterpreter.h" -#include <QModelIndex> #include <QTextEdit> +#include <QModelIndex> -namespace Debugger { +namespace QmlJSTools { namespace Internal { -class QtMessageLogEditor : public QTextEdit +class QmlConsoleEdit : public QTextEdit { Q_OBJECT public: - explicit QtMessageLogEditor(const QModelIndex &index, - QWidget *parent = 0); + QmlConsoleEdit(const QModelIndex &index, QWidget *parent); QString getCurrentScript() const; @@ -64,9 +65,10 @@ private: QString m_cachedScript; QImage m_prompt; int m_startOfEditableArea; + QmlJSInterpreter m_interpreter; }; -} //Internal -} //Debugger +} // QmlJSTools +} // Internal -#endif // QTMESSAGELOGEDITOR_H +#endif // QMLCONSOLEEDIT_H diff --git a/src/plugins/debugger/qtmessagelogitemdelegate.cpp b/src/plugins/qmljstools/qmlconsoleitemdelegate.cpp index 7dbd885c83..e82a4a8d95 100644 --- a/src/plugins/debugger/qtmessagelogitemdelegate.cpp +++ b/src/plugins/qmljstools/qmlconsoleitemdelegate.cpp @@ -27,8 +27,8 @@ ** ****************************************************************************/ -#include "qtmessagelogitemdelegate.h" -#include "qtmessagelogeditor.h" +#include "qmlconsoleitemdelegate.h" +#include "qmlconsoleedit.h" #include <QPainter> #include <QTreeView> @@ -53,55 +53,56 @@ const char CONSOLE_BORDER_COLOR[] = "#C9C9C9"; const int ELLIPSIS_GRADIENT_WIDTH = 16; -namespace Debugger { +using namespace QmlJS; + +namespace QmlJSTools { namespace Internal { /////////////////////////////////////////////////////////////////////// // -// QtMessageLogItemDelegate +// QmlConsoleItemDelegate // /////////////////////////////////////////////////////////////////////// -QtMessageLogItemDelegate::QtMessageLogItemDelegate(QObject *parent) : +QmlConsoleItemDelegate::QmlConsoleItemDelegate(QObject *parent) : QStyledItemDelegate(parent), - m_logIcon(QLatin1String(":/debugger/images/log.png")), - m_warningIcon(QLatin1String(":/debugger/images/warning.png")), - m_errorIcon(QLatin1String(":/debugger/images/error.png")), - m_expandIcon(QLatin1String(":/debugger/images/expand.png")), - m_collapseIcon(QLatin1String(":/debugger/images/collapse.png")), - m_prompt(QLatin1String(":/debugger/images/prompt.png")), - m_itemModel(0), + m_logIcon(QLatin1String(":/qmljstools/images/log.png")), + m_warningIcon(QLatin1String(":/qmljstools/images/warning.png")), + m_errorIcon(QLatin1String(":/qmljstools/images/error.png")), + m_expandIcon(QLatin1String(":/qmljstools/images/expand.png")), + m_collapseIcon(QLatin1String(":/qmljstools/images/collapse.png")), + m_prompt(QLatin1String(":/qmljstools/images/prompt.png")), m_cachedHeight(0) { } -void QtMessageLogItemDelegate::emitSizeHintChanged(const QModelIndex &index) +void QmlConsoleItemDelegate::emitSizeHintChanged(const QModelIndex &index) { emit sizeHintChanged(index); } -QColor QtMessageLogItemDelegate::drawBackground(QPainter *painter, const QRect &rect, - const QModelIndex &index, - bool selected) const +QColor QmlConsoleItemDelegate::drawBackground(QPainter *painter, const QRect &rect, + const QModelIndex &index, + bool selected) const { painter->save(); - QtMessageLogHandler::ItemType itemType = (QtMessageLogHandler::ItemType)index.data( - QtMessageLogHandler::TypeRole).toInt(); + ConsoleItem::ItemType itemType = (ConsoleItem::ItemType)index.data( + QmlConsoleItemModel::TypeRole).toInt(); QColor backgroundColor; switch (itemType) { - case QtMessageLogHandler::DebugType: + case ConsoleItem::DebugType: backgroundColor = selected ? QColor(CONSOLE_LOG_BACKGROUND_SELECTED_COLOR) : QColor(CONSOLE_LOG_BACKGROUND_COLOR); break; - case QtMessageLogHandler::WarningType: + case ConsoleItem::WarningType: backgroundColor = selected ? QColor(CONSOLE_WARNING_BACKGROUND_SELECTED_COLOR) : QColor(CONSOLE_WARNING_BACKGROUND_COLOR); break; - case QtMessageLogHandler::ErrorType: + case ConsoleItem::ErrorType: backgroundColor = selected ? QColor(CONSOLE_ERROR_BACKGROUND_SELECTED_COLOR) : QColor(CONSOLE_ERROR_BACKGROUND_COLOR); break; - case QtMessageLogHandler::InputType: + case ConsoleItem::InputType: default: backgroundColor = selected ? QColor(CONSOLE_EDITOR_BACKGROUND_SELECTED_COLOR) : QColor(CONSOLE_EDITOR_BACKGROUND_COLOR); @@ -116,37 +117,37 @@ QColor QtMessageLogItemDelegate::drawBackground(QPainter *painter, const QRect & painter->setPen(QColor(CONSOLE_BORDER_COLOR)); if (!(index.flags() & Qt::ItemIsEditable)) painter->drawLine(0, rect.bottom(), rect.right(), - rect.bottom()); + rect.bottom()); painter->restore(); return backgroundColor; } -void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const +void QmlConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const { QStyleOptionViewItemV4 opt = option; initStyleOption(&opt, index); painter->save(); - //Set Colors + // Set Colors QColor textColor; QIcon taskIcon; - QtMessageLogHandler::ItemType type = (QtMessageLogHandler::ItemType)index.data( - QtMessageLogHandler::TypeRole).toInt(); + ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data( + QmlConsoleItemModel::TypeRole).toInt(); switch (type) { - case QtMessageLogHandler::DebugType: + case ConsoleItem::DebugType: textColor = QColor(CONSOLE_LOG_TEXT_COLOR); taskIcon = m_logIcon; break; - case QtMessageLogHandler::WarningType: + case ConsoleItem::WarningType: textColor = QColor(CONSOLE_WARNING_TEXT_COLOR); taskIcon = m_warningIcon; break; - case QtMessageLogHandler::ErrorType: + case ConsoleItem::ErrorType: textColor = QColor(CONSOLE_ERROR_TEXT_COLOR); taskIcon = m_errorIcon; break; - case QtMessageLogHandler::InputType: + case ConsoleItem::InputType: textColor = QColor(CONSOLE_EDITOR_TEXT_COLOR); taskIcon = m_prompt; break; @@ -155,11 +156,11 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt break; } - //Paint background + // Paint background QColor backgroundColor = drawBackground(painter, opt.rect, index, - bool(opt.state & QStyle::State_Selected)); + bool(opt.state & QStyle::State_Selected)); - //Calculate positions + // Calculate positions const QTreeView *view = qobject_cast<const QTreeView *>(opt.widget); int level = 0; QModelIndex idx(index); @@ -167,14 +168,12 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt idx = idx.parent(); level++; } - int width = view->width() - level * view->indentation() - - view->verticalScrollBar()->width(); + int width = view->width() - level * view->indentation() - view->verticalScrollBar()->width(); bool showTypeIcon = index.parent() == QModelIndex(); - bool showExpandableIcon = type == QtMessageLogHandler::UndefinedType; + bool showExpandableIcon = type == ConsoleItem::UndefinedType; QRect rect(opt.rect.x(), opt.rect.top(), width, opt.rect.height()); - ConsoleItemPositions positions(rect, opt.font, showTypeIcon, - showExpandableIcon, m_itemModel); + ConsoleItemPositions positions(rect, opt.font, showTypeIcon, showExpandableIcon); // Paint TaskIconArea: if (showTypeIcon) @@ -195,11 +194,10 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt tl.draw(painter, QPoint(positions.textAreaLeft(), positions.adjustedTop())); } else { QFontMetrics fm(opt.font); - painter->drawText(positions.textArea(), - fm.elidedText(str, Qt::ElideRight, - positions.textAreaWidth())); + painter->drawText(positions.textArea(), fm.elidedText(str, Qt::ElideRight, + positions.textAreaWidth())); } - //skip if area is editable + // skip if area is editable if (showExpandableIcon) { // Paint ExpandableIconArea: QIcon expandCollapseIcon; @@ -209,16 +207,14 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt else expandCollapseIcon = m_expandIcon; } - painter->drawPixmap(positions.expandCollapseIconLeft(), - positions.adjustedTop(), - expandCollapseIcon.pixmap( - positions.expandCollapseIconWidth(), - positions.expandCollapseIconHeight())); + painter->drawPixmap(positions.expandCollapseIconLeft(), positions.adjustedTop(), + expandCollapseIcon.pixmap(positions.expandCollapseIconWidth(), + positions.expandCollapseIconHeight())); } if (showFileLineInfo) { - //Check for file info - QString file = index.data(QtMessageLogHandler::FileRole).toString(); + // Check for file info + QString file = index.data(QmlConsoleItemModel::FileRole).toString(); if (!file.isEmpty()) { QFontMetrics fm(option.font); // Paint FileArea @@ -227,22 +223,20 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt file = file.mid(pos +1); const int realFileWidth = fm.width(file); painter->setClipRect(positions.fileArea()); - painter->drawText(positions.fileAreaLeft(), - positions.adjustedTop() + fm.ascent(), file); + painter->drawText(positions.fileAreaLeft(), positions.adjustedTop() + fm.ascent(), + file); if (realFileWidth > positions.fileAreaWidth()) { // draw a gradient to mask the text int gradientStart = positions.fileAreaLeft() - 1; - QLinearGradient lg(gradientStart + - ELLIPSIS_GRADIENT_WIDTH, 0, gradientStart, 0); + QLinearGradient lg(gradientStart + ELLIPSIS_GRADIENT_WIDTH, 0, gradientStart, 0); lg.setColorAt(0, Qt::transparent); lg.setColorAt(1, backgroundColor); painter->fillRect(gradientStart, positions.adjustedTop(), - ELLIPSIS_GRADIENT_WIDTH, positions.lineHeight(), - lg); + ELLIPSIS_GRADIENT_WIDTH, positions.lineHeight(), lg); } // Paint LineArea - QString lineText = index.data(QtMessageLogHandler::LineRole).toString(); + QString lineText = index.data(QmlConsoleItemModel::LineRole).toString(); painter->setClipRect(positions.lineArea()); const int realLineWidth = fm.width(lineText); painter->drawText(positions.lineAreaRight() - realLineWidth, @@ -253,8 +247,8 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt painter->restore(); } -QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const +QSize QmlConsoleItemDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const { QStyleOptionViewItemV4 opt = option; initStyleOption(&opt, index); @@ -266,8 +260,7 @@ QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option, idx = idx.parent(); level++; } - int width = view->width() - level * view->indentation() - - view->verticalScrollBar()->width(); + int width = view->width() - level * view->indentation() - view->verticalScrollBar()->width(); if (index.flags() & Qt::ItemIsEditable) return QSize(width, view->height() * 1/2); @@ -275,14 +268,13 @@ QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option, if (!selected && option.font == m_cachedFont && m_cachedHeight > 0) return QSize(width, m_cachedHeight); - QtMessageLogHandler::ItemType type = (QtMessageLogHandler::ItemType)index.data( - QtMessageLogHandler::TypeRole).toInt(); + ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data( + QmlConsoleItemModel::TypeRole).toInt(); bool showTypeIcon = index.parent() == QModelIndex(); - bool showExpandableIcon = type == QtMessageLogHandler::UndefinedType; + bool showExpandableIcon = type == ConsoleItem::UndefinedType; QRect rect(level * view->indentation(), 0, width, 0); - ConsoleItemPositions positions(rect, opt.font, - showTypeIcon, showExpandableIcon, m_itemModel); + ConsoleItemPositions positions(rect, opt.font, showTypeIcon, showExpandableIcon); QFontMetrics fm(option.font); qreal height = fm.height(); @@ -307,58 +299,56 @@ QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option, return QSize(width, height); } -QWidget *QtMessageLogItemDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem &/*option*/, - const QModelIndex &index) const +QWidget *QmlConsoleItemDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &/*option*/, + const QModelIndex &index) const { - QtMessageLogEditor *editor = new QtMessageLogEditor(index, parent); - connect(editor, SIGNAL(editingFinished()), - this, SLOT(commitAndCloseEditor())); + QmlConsoleEdit *editor = new QmlConsoleEdit(index, parent); + connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); return editor; } -void QtMessageLogItemDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const +void QmlConsoleItemDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const { - QtMessageLogEditor *edtr = qobject_cast<QtMessageLogEditor *>(editor); + QmlConsoleEdit *edtr = qobject_cast<QmlConsoleEdit *>(editor); edtr->insertPlainText(index.data(Qt::DisplayRole).toString()); } -void QtMessageLogItemDelegate::setModelData(QWidget *editor, - QAbstractItemModel *model, - const QModelIndex &index) const +void QmlConsoleItemDelegate::setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const { - QtMessageLogEditor *edtr = qobject_cast<QtMessageLogEditor *>(editor); + QmlConsoleEdit *edtr = qobject_cast<QmlConsoleEdit *>(editor); model->setData(index, edtr->getCurrentScript(), Qt::DisplayRole); - model->setData(index, QtMessageLogHandler::InputType, QtMessageLogHandler::TypeRole); + model->setData(index, ConsoleItem::InputType, QmlConsoleItemModel::TypeRole); } -void QtMessageLogItemDelegate::updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, - const QModelIndex &/*index*/) const +void QmlConsoleItemDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &/*index*/) const { QStyleOptionViewItemV4 opt = option; - editor->setGeometry(QRect(opt.rect.x(), opt.rect.top(), - opt.rect.width(), opt.rect.bottom())); + editor->setGeometry(QRect(opt.rect.x(), opt.rect.top(), opt.rect.width(), opt.rect.bottom())); } -void QtMessageLogItemDelegate::currentChanged(const QModelIndex ¤t, - const QModelIndex &previous) +void QmlConsoleItemDelegate::currentChanged(const QModelIndex ¤t, + const QModelIndex &previous) { emit sizeHintChanged(current); emit sizeHintChanged(previous); } -void QtMessageLogItemDelegate::commitAndCloseEditor() +void QmlConsoleItemDelegate::commitAndCloseEditor() { - QtMessageLogEditor *editor = qobject_cast<QtMessageLogEditor *>(sender()); + QmlConsoleEdit *editor = qobject_cast<QmlConsoleEdit *>(sender()); emit commitData(editor); emit closeEditor(editor); } -qreal QtMessageLogItemDelegate::layoutText(QTextLayout &tl, int width, - bool *showFileLineInfo) const +qreal QmlConsoleItemDelegate::layoutText(QTextLayout &tl, int width, + bool *showFileLineInfo) const { qreal height = 0; tl.beginLayout(); @@ -378,10 +368,5 @@ qreal QtMessageLogItemDelegate::layoutText(QTextLayout &tl, int width, return height; } -void QtMessageLogItemDelegate::setItemModel(QtMessageLogHandler *model) -{ - m_itemModel = model; -} - -} //Internal -} //Debugger +} // Internal +} // QmlJSTools diff --git a/src/plugins/debugger/qtmessagelogitemdelegate.h b/src/plugins/qmljstools/qmlconsoleitemdelegate.h index f6a8a707aa..477618b474 100644 --- a/src/plugins/debugger/qtmessagelogitemdelegate.h +++ b/src/plugins/qmljstools/qmlconsoleitemdelegate.h @@ -27,28 +27,27 @@ ** ****************************************************************************/ -#ifndef QTMESSAGELOGITEMDELEGATE_H -#define QTMESSAGELOGITEMDELEGATE_H +#ifndef QMLCONSOLEITEMDELEGATE_H +#define QMLCONSOLEITEMDELEGATE_H -#include "qtmessageloghandler.h" +#include "qmlconsoleitemmodel.h" +#include "qmlconsolemanager.h" -#include <QTextLayout> #include <QStyledItemDelegate> +#include <QTextLayout> -namespace Debugger { +namespace QmlJSTools { namespace Internal { -class QtMessageLogItemDelegate : public QStyledItemDelegate +class QmlConsoleItemDelegate : public QStyledItemDelegate { Q_OBJECT public: - explicit QtMessageLogItemDelegate(QObject *parent = 0); - void emitSizeHintChanged(const QModelIndex &index); - QColor drawBackground(QPainter *painter, const QRect &rect, - const QModelIndex &index, - bool selected) const; + QmlConsoleItemDelegate(QObject *parent); - void setItemModel(QtMessageLogHandler *model); + void emitSizeHintChanged(const QModelIndex &index); + QColor drawBackground(QPainter *painter, const QRect &rect, const QModelIndex &index, + bool selected) const; public slots: void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); @@ -61,11 +60,9 @@ protected: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; - void updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; private slots: @@ -81,7 +78,6 @@ private: const QIcon m_expandIcon; const QIcon m_collapseIcon; const QIcon m_prompt; - QtMessageLogHandler *m_itemModel; mutable int m_cachedHeight; mutable QFont m_cachedFont; }; @@ -101,11 +97,8 @@ private: class ConsoleItemPositions { public: - ConsoleItemPositions(const QRect &rect, - const QFont &font, - bool showTaskIconArea, - bool showExpandableIconArea, - QtMessageLogHandler *model = 0) + ConsoleItemPositions(const QRect &rect, const QFont &font, bool showTaskIconArea, + bool showExpandableIconArea) : m_x(rect.x()), m_width(rect.width()), m_top(rect.top()), @@ -116,10 +109,9 @@ public: m_showExpandableIconArea(showExpandableIconArea) { m_fontHeight = QFontMetrics(font).height(); - if (model) { - m_maxFileLength = model->sizeOfFile(font); - m_maxLineLength = model->sizeOfLineNumber(font); - } + QmlConsoleItemModel *model = QmlConsoleModel::qmlConsoleItemModel(); + m_maxFileLength = model->sizeOfFile(font); + m_maxLineLength = model->sizeOfLineNumber(font); } int adjustedTop() const { return m_top + ITEM_PADDING; } @@ -129,44 +121,41 @@ public: int lineHeight() const { return m_fontHeight + 1; } int minimumHeight() const { return typeIconHeight() + 2 * ITEM_PADDING; } - //PROMPTAREA is same as TYPEICONAREA + // PROMPTAREA is same as TYPEICONAREA int typeIconLeft() const { return adjustedLeft(); } int typeIconWidth() const { return TASK_ICON_SIZE; } int typeIconHeight() const { return TASK_ICON_SIZE; } - int typeIconRight() const { return m_showTaskIconArea ? - typeIconLeft() + typeIconWidth() : adjustedLeft(); } - QRect typeIcon() const { return - QRect(typeIconLeft(), adjustedTop(), - typeIconWidth(), typeIconHeight()); } - - int expandCollapseIconLeft() const { return typeIconRight() + - ITEM_SPACING; } + int typeIconRight() const { return m_showTaskIconArea ? typeIconLeft() + typeIconWidth() + : adjustedLeft(); } + QRect typeIcon() const { return QRect(typeIconLeft(), adjustedTop(), typeIconWidth(), + typeIconHeight()); } + + int expandCollapseIconLeft() const { return typeIconRight() + ITEM_SPACING; } int expandCollapseIconWidth() const { return TASK_ICON_SIZE; } int expandCollapseIconHeight() const { return TASK_ICON_SIZE; } int expandCollapseIconRight() const { return m_showExpandableIconArea ? - expandCollapseIconLeft() + expandCollapseIconWidth() : - typeIconRight(); } - QRect expandCollapseIcon() const { return - QRect(expandCollapseIconLeft(), adjustedTop(), - expandCollapseIconWidth(), expandCollapseIconHeight()); } + expandCollapseIconLeft() + expandCollapseIconWidth() : typeIconRight(); } + QRect expandCollapseIcon() const { return QRect(expandCollapseIconLeft(), adjustedTop(), + expandCollapseIconWidth(), + expandCollapseIconHeight()); } int textAreaLeft() const { return expandCollapseIconRight() + ITEM_SPACING; } int textAreaWidth() const { return textAreaRight() - textAreaLeft(); } int textAreaRight() const { return fileAreaLeft() - ITEM_SPACING; } - QRect textArea() const { return - QRect(textAreaLeft(), adjustedTop(), textAreaWidth(), lineHeight()); } + QRect textArea() const { return QRect(textAreaLeft(), adjustedTop(), textAreaWidth(), + lineHeight()); } int fileAreaLeft() const { return fileAreaRight() - fileAreaWidth(); } int fileAreaWidth() const { return m_maxFileLength; } int fileAreaRight() const { return lineAreaLeft() - ITEM_SPACING; } - QRect fileArea() const { return - QRect(fileAreaLeft(), adjustedTop(), fileAreaWidth(), lineHeight()); } + QRect fileArea() const { return QRect(fileAreaLeft(), adjustedTop(), fileAreaWidth(), + lineHeight()); } int lineAreaLeft() const { return lineAreaRight() - lineAreaWidth(); } int lineAreaWidth() const { return m_maxLineLength; } int lineAreaRight() const { return adjustedRight() - ITEM_SPACING; } - QRect lineArea() const { return - QRect(lineAreaLeft(), adjustedTop(), lineAreaWidth(), lineHeight()); } + QRect lineArea() const { return QRect(lineAreaLeft(), adjustedTop(), lineAreaWidth(), + lineHeight()); } private: int m_x; @@ -185,7 +174,8 @@ public: static const int ITEM_SPACING = 4; }; -} //Internal -} //Debugger -#endif // QTMESSAGELOGITEMDELEGATE_H +} // namespace Internal +} // namespace QmlJSTools + +#endif // QMLCONSOLEITEMDELEGATE_H diff --git a/src/plugins/qmljstools/qmlconsoleitemmodel.cpp b/src/plugins/qmljstools/qmlconsoleitemmodel.cpp new file mode 100644 index 0000000000..aa8b07737d --- /dev/null +++ b/src/plugins/qmljstools/qmlconsoleitemmodel.cpp @@ -0,0 +1,282 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmlconsoleitemmodel.h" + +#include <utils/qtcassert.h> + +#include <QFontMetrics> + +using namespace QmlJS; + +namespace QmlJSTools { +namespace Internal { + +/////////////////////////////////////////////////////////////////////// +// +// QmlConsoleItemModel +// +/////////////////////////////////////////////////////////////////////// + +QmlConsoleItemModel::QmlConsoleItemModel(QObject *parent) : + QAbstractItemModel(parent), + m_hasEditableRow(false), + m_rootItem(new ConsoleItem(0)), + m_maxSizeOfFileName(0) +{ +} + +QmlConsoleItemModel::~QmlConsoleItemModel() +{ + delete m_rootItem; +} + +void QmlConsoleItemModel::clear() +{ + beginResetModel(); + delete m_rootItem; + m_rootItem = new ConsoleItem(0); + endResetModel(); + + if (m_hasEditableRow) + appendEditableRow(); +} + +bool QmlConsoleItemModel::appendItem(ConsoleItem *item, int position) +{ + if (position < 0) + position = m_rootItem->childCount() - 1; + + if (position < 0) + position = 0; + + beginInsertRows(QModelIndex(), position, position); + bool success = m_rootItem->insertChild(position, item); + endInsertRows(); + + return success; +} + +bool QmlConsoleItemModel::appendMessage(ConsoleItem::ItemType itemType, + const QString &message, int position) +{ + return appendItem(new ConsoleItem(m_rootItem, itemType, message), position); +} + +void QmlConsoleItemModel::setHasEditableRow(bool hasEditableRow) +{ + if (m_hasEditableRow && !hasEditableRow) + removeEditableRow(); + + if (!m_hasEditableRow && hasEditableRow) + appendEditableRow(); + + m_hasEditableRow = hasEditableRow; +} + +bool QmlConsoleItemModel::hasEditableRow() const +{ + return m_hasEditableRow; +} + +void QmlConsoleItemModel::appendEditableRow() +{ + int position = m_rootItem->childCount(); + if (appendItem(new ConsoleItem(m_rootItem, ConsoleItem::InputType), position)) + emit selectEditableRow(index(position, 0), QItemSelectionModel::ClearAndSelect); +} + +void QmlConsoleItemModel::removeEditableRow() +{ + if (m_rootItem->child(m_rootItem->childCount() - 1)->itemType == ConsoleItem::InputType) + removeRow(m_rootItem->childCount() - 1); +} + +int QmlConsoleItemModel::sizeOfFile(const QFont &font) +{ + int lastReadOnlyRow = m_rootItem->childCount(); + if (m_hasEditableRow) + lastReadOnlyRow -= 2; + else + lastReadOnlyRow -= 1; + if (lastReadOnlyRow < 0) + return 0; + QString filename = m_rootItem->child(lastReadOnlyRow)->file; + const int pos = filename.lastIndexOf(QLatin1Char('/')); + if (pos != -1) + filename = filename.mid(pos + 1); + + QFontMetrics fm(font); + m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename)); + + return m_maxSizeOfFileName; +} + +int QmlConsoleItemModel::sizeOfLineNumber(const QFont &font) +{ + QFontMetrics fm(font); + return fm.width(QLatin1String("88888")); +} + +QVariant QmlConsoleItemModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + ConsoleItem *item = getItem(index); + + if (role == Qt::DisplayRole ) + return item->text(); + else if (role == QmlConsoleItemModel::TypeRole) + return int(item->itemType); + else if (role == QmlConsoleItemModel::FileRole) + return item->file; + else if (role == QmlConsoleItemModel::LineRole) + return item->line; + else + return QVariant(); +} + +QModelIndex QmlConsoleItemModel::index(int row, int column, const QModelIndex &parent) const +{ + if (parent.isValid() && parent.column() != 0) + return QModelIndex(); + + if (column > 0) + return QModelIndex(); + + ConsoleItem *parentItem = getItem(parent); + + ConsoleItem *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex QmlConsoleItemModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + ConsoleItem *childItem = getItem(index); + ConsoleItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + return QModelIndex(); + + if (!parentItem) + return QModelIndex(); + return createIndex(parentItem->childNumber(), 0, parentItem); +} + +int QmlConsoleItemModel::rowCount(const QModelIndex &parent) const +{ + ConsoleItem *parentItem = getItem(parent); + + return parentItem->childCount(); +} + +int QmlConsoleItemModel::columnCount(const QModelIndex & /* parent */) const +{ + return 1; +} + +Qt::ItemFlags QmlConsoleItemModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + + ConsoleItem *item = getItem(index); + if (m_hasEditableRow && item->parent() == m_rootItem + && index.row() == m_rootItem->childCount() - 1) + return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +bool QmlConsoleItemModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + ConsoleItem *item = getItem(index); + bool result = false; + if (role == Qt::DisplayRole) { + item->setText(value.toString()); + result = true; + } else if (role == QmlConsoleItemModel::TypeRole) { + item->itemType = (ConsoleItem::ItemType)value.toInt(); + result = true; + } else if (role == QmlConsoleItemModel::FileRole) { + item->file = value.toString(); + result = true; + } else if (role == QmlConsoleItemModel::LineRole) { + item->line = value.toInt(); + result = true; + } + + if (result) + emit dataChanged(index, index); + + return result; +} + +bool QmlConsoleItemModel::insertRows(int position, int rows, const QModelIndex &parent) +{ + ConsoleItem *parentItem = getItem(parent); + bool success; + + beginInsertRows(parent, position, position + rows - 1); + success = parentItem->insertChildren(position, rows); + endInsertRows(); + + return success; +} + +bool QmlConsoleItemModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + ConsoleItem *parentItem = getItem(parent); + bool success = true; + + beginRemoveRows(parent, position, position + rows - 1); + success = parentItem->removeChildren(position, rows); + endRemoveRows(); + + return success; +} + +ConsoleItem *QmlConsoleItemModel::getItem(const QModelIndex &index) const +{ + if (index.isValid()) { + ConsoleItem *item = static_cast<ConsoleItem*>(index.internalPointer()); + if (item) + return item; + } + return m_rootItem; +} + +} // Internal +} // QmlJSTools diff --git a/src/plugins/debugger/qtmessageloghandler.h b/src/plugins/qmljstools/qmlconsoleitemmodel.h index 4452823b0a..02216311fe 100644 --- a/src/plugins/debugger/qtmessageloghandler.h +++ b/src/plugins/qmljstools/qmlconsoleitemmodel.h @@ -1,4 +1,4 @@ -/**************************************************************************** +/************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal @@ -27,46 +27,35 @@ ** ****************************************************************************/ -#ifndef QTMESSAGELOGHANDLER_H -#define QTMESSAGELOGHANDLER_H +#ifndef QMLCONSOLEITEMMODEL_H +#define QMLCONSOLEITEMMODEL_H + +#include <qmljs/consoleitem.h> #include <QAbstractItemModel> #include <QItemSelectionModel> #include <QFont> -namespace Debugger { +namespace QmlJSTools { namespace Internal { -class QtMessageLogItem; -class QtMessageLogHandler : public QAbstractItemModel +class QmlConsoleItemModel : public QAbstractItemModel { Q_OBJECT - public: - enum ItemType - { - InputType = 0x01, - DebugType = 0x02, - WarningType = 0x04, - ErrorType = 0x08, - UndefinedType = 0x10, //Can be used for unknown and for Return values - DefaultTypes = InputType | UndefinedType - }; - Q_DECLARE_FLAGS(ItemTypes, ItemType) - enum Roles { TypeRole = Qt::UserRole, FileRole, LineRole }; - explicit QtMessageLogHandler(QObject *parent = 0); - ~QtMessageLogHandler(); + explicit QmlConsoleItemModel(QObject *parent = 0); + ~QmlConsoleItemModel(); void setHasEditableRow(bool hasEditableRow); bool hasEditableRow() const; void appendEditableRow(); void removeEditableRow(); - bool appendItem(QtMessageLogItem *item, int position = -1); - bool appendMessage(QtMessageLogHandler::ItemType itemType, - const QString &message, int position = -1); + bool appendItem(QmlJS::ConsoleItem *item, int position = -1); + bool appendMessage(QmlJS::ConsoleItem::ItemType itemType, const QString &message, + int position = -1); QAbstractItemModel *model() { return this; } @@ -75,75 +64,39 @@ public: int sizeOfFile(const QFont &font); int sizeOfLineNumber(const QFont &font); - QtMessageLogItem *root() const { return m_rootItem; } + QmlJS::ConsoleItem *root() const { return m_rootItem; } public slots: void clear(); signals: - void selectEditableRow(const QModelIndex &index, - QItemSelectionModel::SelectionFlags flags); + void selectEditableRow(const QModelIndex &index, QItemSelectionModel::SelectionFlags flags); void rowInserted(const QModelIndex &index); protected: QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; Qt::ItemFlags flags(const QModelIndex &index) const; - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole); + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - bool insertRows(int position, int rows, - const QModelIndex &parent = QModelIndex()); - bool removeRows(int position, int rows, - const QModelIndex &parent = QModelIndex()); + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); - QtMessageLogItem *getItem(const QModelIndex &index) const; + QmlJS::ConsoleItem *getItem(const QModelIndex &index) const; private: bool m_hasEditableRow; - QtMessageLogItem *m_rootItem; + QmlJS::ConsoleItem *m_rootItem; int m_maxSizeOfFileName; }; -class QtMessageLogItem -{ -public: - QtMessageLogItem(QtMessageLogItem *parent, - QtMessageLogHandler::ItemType type = QtMessageLogHandler::UndefinedType, - const QString &data = QString()); - ~QtMessageLogItem(); - - QtMessageLogItem *child(int number); - int childCount() const; - bool insertChildren(int position, int count); - void insertChild(QtMessageLogItem *item); - bool insertChild(int position, QtMessageLogItem *item); - QtMessageLogItem *parent(); - bool removeChildren(int position, int count); - bool detachChild(int position); - int childNumber() const; - void setText(const QString &text); - const QString &text() const; - -private: - QtMessageLogItem *m_parentItem; - QList<QtMessageLogItem *> m_childItems; - QString m_text; - -public: - QtMessageLogHandler::ItemType itemType; - QString file; - int line; -}; - -} //Internal -} //Debugger +} // Internal +} // QmlJSTools -#endif // QTMESSAGELOGHANDLER_H +#endif // QMLCONSOLEITEMMODEL_H diff --git a/src/plugins/qmljstools/qmlconsolemanager.cpp b/src/plugins/qmljstools/qmlconsolemanager.cpp new file mode 100644 index 0000000000..714192c3f8 --- /dev/null +++ b/src/plugins/qmljstools/qmlconsolemanager.cpp @@ -0,0 +1,190 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmlconsolemanager.h" +#include "qmlconsolepane.h" +#include "qmlconsoleitemmodel.h" + +#include <extensionsystem/pluginmanager.h> + +#include <qmljs/iscriptevaluator.h> + +#include <QScriptEngine> +#include <QVariant> + +using namespace QmlJS; + +namespace QmlJSTools { + +class QmlConsoleManagerPrivate +{ +public: + QScriptEngine *scriptEngine; + Internal::QmlConsoleItemModel *qmlConsoleItemModel; + Internal::QmlConsolePane *qmlConsolePane; + QmlJS::IScriptEvaluator *scriptEvaluator; +}; + +QmlConsoleManager::QmlConsoleManager(QObject *parent) + : ConsoleManagerInterface(parent), + d(new QmlConsoleManagerPrivate) +{ + d->scriptEngine = new QScriptEngine(this); + d->qmlConsoleItemModel = new Internal::QmlConsoleItemModel(this); + d->qmlConsoleItemModel->setHasEditableRow(true); + d->qmlConsolePane = new Internal::QmlConsolePane(this); + d->scriptEvaluator = 0; + ExtensionSystem::PluginManager::addObject(d->qmlConsolePane); +} + +QmlConsoleManager::~QmlConsoleManager() +{ + if (d->qmlConsolePane) + ExtensionSystem::PluginManager::removeObject(d->qmlConsolePane); + delete d; +} + +void QmlConsoleManager::showConsolePane() +{ + if (d->qmlConsolePane) + d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch); +} + +ConsoleItem *QmlConsoleManager::rootItem() const +{ + return d->qmlConsoleItemModel->root(); +} + +void QmlConsoleManager::setScriptEvaluator(QmlJS::IScriptEvaluator *scriptEvaluator) +{ + d->scriptEvaluator = scriptEvaluator; + if (!scriptEvaluator) + setContext(QString()); +} + +void QmlConsoleManager::setContext(const QString &context) +{ + d->qmlConsolePane->setContext(context); +} + +void QmlConsoleManager::printToConsolePane(ConsoleItem::ItemType itemType, + const QString &text, bool bringToForeground) +{ + if (!d->qmlConsolePane) + return; + if (itemType == ConsoleItem::ErrorType) + bringToForeground = true; + if (bringToForeground) + d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch); + d->qmlConsoleItemModel->appendMessage(itemType, text); +} + +void QmlConsoleManager::printToConsolePane(ConsoleItem *item, bool bringToForeground) +{ + if (!d->qmlConsolePane) + return; + if (item->itemType == ConsoleItem::ErrorType) + bringToForeground = true; + if (bringToForeground) + d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch); + d->qmlConsoleItemModel->appendItem(item); +} + +namespace Internal { + +ConsoleItem *constructLogItemTree(ConsoleItem *parent, const QVariant &result, + const QString &key = QString()) +{ + if (!result.isValid()) + return 0; + + ConsoleItem *item = new ConsoleItem(parent); + if (result.type() == QVariant::Map) { + if (key.isEmpty()) + item->setText(QLatin1String("Object")); + else + item->setText(key + QLatin1String(" : Object")); + + QMapIterator<QString, QVariant> i(result.toMap()); + while (i.hasNext()) { + i.next(); + ConsoleItem *child = constructLogItemTree(item, i.value(), i.key()); + if (child) + item->insertChild(child, true); + } + } else if (result.type() == QVariant::List) { + if (key.isEmpty()) + item->setText(QLatin1String("List")); + else + item->setText(QString(QLatin1String("[%1] : List")).arg(key)); + QVariantList resultList = result.toList(); + for (int i = 0; i < resultList.count(); i++) { + ConsoleItem *child = constructLogItemTree(item, resultList.at(i), + QString::number(i)); + if (child) + item->insertChild(child, true); + } + } else if (result.canConvert(QVariant::String)) { + item->setText(result.toString()); + } else { + item->setText(QLatin1String("Unknown Value")); + } + + return item; +} + +QmlConsoleItemModel *QmlConsoleModel::qmlConsoleItemModel() +{ + QmlConsoleManager *manager = qobject_cast<QmlConsoleManager *>(QmlConsoleManager::instance()); + if (manager) + return manager->d->qmlConsoleItemModel; + return 0; +} + +void QmlConsoleModel::evaluate(const QString &expression) +{ + QmlConsoleManager *manager = qobject_cast<QmlConsoleManager *>(QmlConsoleManager::instance()); + if (manager) { + if (manager->d->scriptEvaluator) { + QmlConsoleModel::qmlConsoleItemModel()->appendEditableRow(); + manager->d->scriptEvaluator->evaluateScript(expression); + } else { + QVariant result = manager->d->scriptEngine->evaluate(expression).toVariant(); + ConsoleItem *root = manager->rootItem(); + ConsoleItem *item = constructLogItemTree(root, result); + if (item) { + QmlConsoleModel::qmlConsoleItemModel()->appendEditableRow(); + manager->printToConsolePane(item); + } + } + } +} + +} // Internal +} // QmlJSTools diff --git a/src/plugins/qmljstools/qmlconsolemanager.h b/src/plugins/qmljstools/qmlconsolemanager.h new file mode 100644 index 0000000000..57764655f2 --- /dev/null +++ b/src/plugins/qmljstools/qmlconsolemanager.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QMLCONSOLEMANAGER_H +#define QMLCONSOLEMANAGER_H + +#include "qmljstools_global.h" + +#include <qmljs/consolemanagerinterface.h> + +#include <QObject> + +namespace QmlJS { +class IScriptEvaluator; +} +namespace QmlJSTools { + +namespace Internal { +class QmlConsoleItemModel; +class QmlConsoleModel; +} + +class QmlConsoleManagerPrivate; +class QMLJSTOOLS_EXPORT QmlConsoleManager : public QmlJS::ConsoleManagerInterface +{ + Q_OBJECT +public: + QmlConsoleManager(QObject *parent); + ~QmlConsoleManager(); + + void showConsolePane(); + + QmlJS::ConsoleItem *rootItem() const; + + void setScriptEvaluator(QmlJS::IScriptEvaluator *scriptEvaluator); + void setContext(const QString &context); + + void printToConsolePane(QmlJS::ConsoleItem::ItemType itemType, const QString &text, + bool bringToForeground = false); + void printToConsolePane(QmlJS::ConsoleItem *item, bool bringToForeground = false); + +private: + QmlConsoleManagerPrivate *d; + friend class Internal::QmlConsoleModel; +}; + +namespace Internal { + +class QmlConsoleModel +{ +public: + static QmlConsoleItemModel *qmlConsoleItemModel(); + static void evaluate(const QString &expression); +}; + +} + +} // namespace QmlJSTools + +#endif // QMLCONSOLEMANAGER_H diff --git a/src/plugins/qmljstools/qmlconsolepane.cpp b/src/plugins/qmljstools/qmlconsolepane.cpp new file mode 100644 index 0000000000..1a9a7ffbb2 --- /dev/null +++ b/src/plugins/qmljstools/qmlconsolepane.cpp @@ -0,0 +1,244 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmlconsolepane.h" +#include "qmlconsoleview.h" +#include "qmlconsoleproxymodel.h" +#include "qmlconsoleitemmodel.h" +#include "qmlconsolemanager.h" +#include "qmlconsoleitemdelegate.h" + +#include <coreplugin/icore.h> +#include <coreplugin/icontext.h> +#include <coreplugin/findplaceholder.h> +#include <utils/savedaction.h> +#include <aggregation/aggregate.h> +#include <find/treeviewfind.h> + +#include <QToolButton> +#include <QLabel> +#include <QVBoxLayout> + +static const char CONSOLE[] = "Console"; +static const char SHOW_LOG[] = "showLog"; +static const char SHOW_WARNING[] = "showWarning"; +static const char SHOW_ERROR[] = "showError"; + +namespace QmlJSTools { +namespace Internal { + +///////////////////////////////////////////////////////////////////// +// +// QmlConsolePane +// +///////////////////////////////////////////////////////////////////// + +QmlConsolePane::QmlConsolePane(QObject *parent) + : Core::IOutputPane(parent) +{ + m_consoleWidget = new QWidget; + m_consoleWidget->setWindowTitle(displayName()); + m_consoleWidget->setEnabled(true); + + QVBoxLayout *vbox = new QVBoxLayout(m_consoleWidget); + vbox->setMargin(0); + vbox->setSpacing(0); + + m_consoleView = new QmlConsoleView(m_consoleWidget); + m_proxyModel = new QmlConsoleProxyModel(this); + m_proxyModel->setSourceModel(QmlConsoleModel::qmlConsoleItemModel()); + connect(QmlConsoleModel::qmlConsoleItemModel(), + SIGNAL(selectEditableRow(QModelIndex, QItemSelectionModel::SelectionFlags)), + m_proxyModel, + SLOT(selectEditableRow(QModelIndex,QItemSelectionModel::SelectionFlags))); + + //Scroll to bottom when rows matching current filter settings are inserted + //Not connecting rowsRemoved as the only way to remove rows is to clear the + //model which will automatically reset the view. + connect(QmlConsoleModel::qmlConsoleItemModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), + m_proxyModel, SLOT(onRowsInserted(QModelIndex,int,int))); + m_consoleView->setModel(m_proxyModel); + + connect(m_proxyModel, + SIGNAL(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags)), + m_consoleView->selectionModel(), + SLOT(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags))); + connect(m_proxyModel, SIGNAL(scrollToBottom()), m_consoleView, SLOT(onScrollToBottom())); + + m_itemDelegate = new QmlConsoleItemDelegate(this); + connect(m_consoleView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + m_itemDelegate, SLOT(currentChanged(QModelIndex,QModelIndex))); + m_consoleView->setItemDelegate(m_itemDelegate); + + Aggregation::Aggregate *aggregate = new Aggregation::Aggregate(); + aggregate->add(m_consoleView); + aggregate->add(new Find::TreeViewFind(m_consoleView)); + + vbox->addWidget(m_consoleView); + vbox->addWidget(new Core::FindToolBarPlaceHolder(m_consoleWidget)); + + m_showDebugButton = new QToolButton(m_consoleWidget); + m_showDebugButton->setAutoRaise(true); + + m_showDebugButtonAction = new Utils::SavedAction(this); + m_showDebugButtonAction->setDefaultValue(true); + m_showDebugButtonAction->setSettingsKey(QLatin1String(CONSOLE), QLatin1String(SHOW_LOG)); + m_showDebugButtonAction->setToolTip(tr("Show debug, log, and info messages.")); + m_showDebugButtonAction->setCheckable(true); + m_showDebugButtonAction->setIcon(QIcon(QLatin1String(":/qmljstools/images/log.png"))); + connect(m_showDebugButtonAction, SIGNAL(toggled(bool)), m_proxyModel, SLOT(setShowLogs(bool))); + m_showDebugButton->setDefaultAction(m_showDebugButtonAction); + + m_showWarningButton = new QToolButton(m_consoleWidget); + m_showWarningButton->setAutoRaise(true); + + m_showWarningButtonAction = new Utils::SavedAction(this); + m_showWarningButtonAction->setDefaultValue(true); + m_showWarningButtonAction->setSettingsKey(QLatin1String(CONSOLE), QLatin1String(SHOW_WARNING)); + m_showWarningButtonAction->setToolTip(tr("Show debug, log, and info messages.")); + m_showWarningButtonAction->setCheckable(true); + m_showWarningButtonAction->setIcon(QIcon(QLatin1String(":/qmljstools/images/warning.png"))); + connect(m_showWarningButtonAction, SIGNAL(toggled(bool)), m_proxyModel, + SLOT(setShowWarnings(bool))); + m_showWarningButton->setDefaultAction(m_showWarningButtonAction); + + m_showErrorButton = new QToolButton(m_consoleWidget); + m_showErrorButton->setAutoRaise(true); + + m_showErrorButtonAction = new Utils::SavedAction(this); + m_showErrorButtonAction->setDefaultValue(true); + m_showErrorButtonAction->setSettingsKey(QLatin1String(CONSOLE), QLatin1String(SHOW_ERROR)); + m_showErrorButtonAction->setToolTip(tr("Show debug, log, and info messages.")); + m_showErrorButtonAction->setCheckable(true); + m_showErrorButtonAction->setIcon(QIcon(QLatin1String(":/qmljstools/images/error.png"))); + connect(m_showErrorButtonAction, SIGNAL(toggled(bool)), m_proxyModel, + SLOT(setShowErrors(bool))); + m_showErrorButton->setDefaultAction(m_showErrorButtonAction); + + m_spacer = new QWidget(m_consoleWidget); + m_spacer->setMinimumWidth(30); + + m_statusLabel = new QLabel(m_consoleWidget); + + readSettings(); + connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), SLOT(writeSettings())); +} + +QmlConsolePane::~QmlConsolePane() +{ + writeSettings(); + delete m_consoleWidget; +} + +QWidget *QmlConsolePane::outputWidget(QWidget *) +{ + return m_consoleWidget; +} + +QList<QWidget *> QmlConsolePane::toolBarWidgets() const +{ + return QList<QWidget *>() << m_showDebugButton << m_showWarningButton << m_showErrorButton + << m_spacer << m_statusLabel; +} + +int QmlConsolePane::priorityInStatusBar() const +{ + return 20; +} + +void QmlConsolePane::clearContents() +{ + QmlConsoleModel::qmlConsoleItemModel()->clear(); +} + +void QmlConsolePane::visibilityChanged(bool /*visible*/) +{ +} + +bool QmlConsolePane::canFocus() const +{ + return true; +} + +bool QmlConsolePane::hasFocus() const +{ + return m_consoleWidget->hasFocus(); +} + +void QmlConsolePane::setFocus() +{ + m_consoleWidget->setFocus(); +} + +bool QmlConsolePane::canNext() const +{ + return false; +} + +bool QmlConsolePane::canPrevious() const +{ + return false; +} + +void QmlConsolePane::goToNext() +{ +} + +void QmlConsolePane::goToPrev() +{ +} + +bool QmlConsolePane::canNavigate() const +{ + return false; +} + +void QmlConsolePane::readSettings() +{ + QSettings *settings = Core::ICore::settings(); + m_showDebugButtonAction->readSettings(settings); + m_showWarningButtonAction->readSettings(settings); + m_showErrorButtonAction->readSettings(settings); +} + +void QmlConsolePane::setContext(const QString &context) +{ + m_statusLabel->setText(context); +} + +void QmlConsolePane::writeSettings() const +{ + QSettings *settings = Core::ICore::settings(); + m_showDebugButtonAction->writeSettings(settings); + m_showWarningButtonAction->writeSettings(settings); + m_showErrorButtonAction->writeSettings(settings); +} + +} // Internal +} // QmlJSTools diff --git a/src/plugins/qmljstools/qmlconsolepane.h b/src/plugins/qmljstools/qmlconsolepane.h new file mode 100644 index 0000000000..62d6e80755 --- /dev/null +++ b/src/plugins/qmljstools/qmlconsolepane.h @@ -0,0 +1,100 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QMLCONSOLEPANE_H +#define QMLCONSOLEPANE_H + +#include <coreplugin/ioutputpane.h> + +QT_BEGIN_NAMESPACE +class QToolButton; +class QLabel; +QT_END_NAMESPACE + +namespace Utils { +class SavedAction; +} + +namespace QmlJSTools { + +namespace Internal { + +class QmlConsoleView; +class QmlConsoleItemDelegate; +class QmlConsoleProxyModel; +class QmlConsoleItemModel; + +class QmlConsolePane : public Core::IOutputPane +{ + Q_OBJECT +public: + QmlConsolePane(QObject *parent); + ~QmlConsolePane(); + + QWidget *outputWidget(QWidget *); + QList<QWidget *> toolBarWidgets() const; + QString displayName() const { return tr("QML/JS Console"); } + int priorityInStatusBar() const; + void clearContents(); + void visibilityChanged(bool visible); + bool canFocus() const; + bool hasFocus() const; + void setFocus(); + + bool canNext() const; + bool canPrevious() const; + void goToNext(); + void goToPrev(); + bool canNavigate() const; + + void readSettings(); + void setContext(const QString &context); + +public slots: + void writeSettings() const; + +private: + QToolButton *m_showDebugButton; + QToolButton *m_showWarningButton; + QToolButton *m_showErrorButton; + Utils::SavedAction *m_showDebugButtonAction; + Utils::SavedAction *m_showWarningButtonAction; + Utils::SavedAction *m_showErrorButtonAction; + QWidget *m_spacer; + QLabel *m_statusLabel; + QmlConsoleView *m_consoleView; + QmlConsoleItemDelegate *m_itemDelegate; + QmlConsoleProxyModel *m_proxyModel; + QWidget *m_consoleWidget; +}; + +} // namespace Internal +} // namespace QmlJSTools + +#endif // QMLCONSOLEPANE_H diff --git a/src/plugins/debugger/qtmessagelogproxymodel.cpp b/src/plugins/qmljstools/qmlconsoleproxymodel.cpp index 78397711ea..2fbd2ca843 100644 --- a/src/plugins/debugger/qtmessagelogproxymodel.cpp +++ b/src/plugins/qmljstools/qmlconsoleproxymodel.cpp @@ -27,54 +27,54 @@ ** ****************************************************************************/ -#include "qtmessagelogproxymodel.h" +#include "qmlconsoleproxymodel.h" +#include "qmlconsoleitemmodel.h" -namespace Debugger { +using namespace QmlJS; + +namespace QmlJSTools { namespace Internal { -QtMessageLogProxyModel::QtMessageLogProxyModel(QObject *parent) : +QmlConsoleProxyModel::QmlConsoleProxyModel(QObject *parent) : QSortFilterProxyModel(parent), - m_filter(QtMessageLogHandler::DefaultTypes) + m_filter(ConsoleItem::DefaultTypes) { } -void QtMessageLogProxyModel::setShowLogs(bool show) +void QmlConsoleProxyModel::setShowLogs(bool show) { - m_filter = show ? m_filter | QtMessageLogHandler::DebugType : - m_filter & ~QtMessageLogHandler::DebugType; + m_filter = show ? m_filter | ConsoleItem::DebugType : m_filter & ~ConsoleItem::DebugType; setFilterRegExp(QString()); } -void QtMessageLogProxyModel::setShowWarnings(bool show) +void QmlConsoleProxyModel::setShowWarnings(bool show) { - m_filter = show ? m_filter | QtMessageLogHandler::WarningType : - m_filter & ~QtMessageLogHandler::WarningType; + m_filter = show ? m_filter | ConsoleItem::WarningType + : m_filter & ~ConsoleItem::WarningType; setFilterRegExp(QString()); } -void QtMessageLogProxyModel::setShowErrors(bool show) +void QmlConsoleProxyModel::setShowErrors(bool show) { - m_filter = show ? m_filter | QtMessageLogHandler::ErrorType : - m_filter & ~QtMessageLogHandler::ErrorType; + m_filter = show ? m_filter | ConsoleItem::ErrorType : m_filter & ~ConsoleItem::ErrorType; setFilterRegExp(QString()); } -void QtMessageLogProxyModel::selectEditableRow(const QModelIndex &index, +void QmlConsoleProxyModel::selectEditableRow(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) { emit setCurrentIndex(mapFromSource(index), command); } -bool QtMessageLogProxyModel::filterAcceptsRow(int sourceRow, +bool QmlConsoleProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); - return m_filter.testFlag((QtMessageLogHandler::ItemType) - sourceModel()->data( - index, QtMessageLogHandler::TypeRole).toInt()); + return m_filter.testFlag((ConsoleItem::ItemType)sourceModel()->data( + index, QmlConsoleItemModel::TypeRole).toInt()); } -void QtMessageLogProxyModel::onRowsInserted(const QModelIndex &index, int start, int end) +void QmlConsoleProxyModel::onRowsInserted(const QModelIndex &index, int start, int end) { int rowIndex = end; do { @@ -85,5 +85,5 @@ void QtMessageLogProxyModel::onRowsInserted(const QModelIndex &index, int start, } while (--rowIndex >= start); } -} // namespace Internal -} // namespace Debugger +} // Internal +} // QmlJSTools diff --git a/src/plugins/debugger/qtmessagelogproxymodel.h b/src/plugins/qmljstools/qmlconsoleproxymodel.h index 9f30c17590..a96a20020c 100644 --- a/src/plugins/debugger/qtmessagelogproxymodel.h +++ b/src/plugins/qmljstools/qmlconsoleproxymodel.h @@ -27,22 +27,22 @@ ** ****************************************************************************/ -#ifndef QTMESSAGELOGPROXYMODEL_H -#define QTMESSAGELOGPROXYMODEL_H +#ifndef QMLCONSOLEPROXYMODEL_H +#define QMLCONSOLEPROXYMODEL_H -#include "qtmessageloghandler.h" +#include <qmljs/consoleitem.h> #include <QSortFilterProxyModel> #include <QItemSelectionModel> -namespace Debugger { +namespace QmlJSTools { namespace Internal { -class QtMessageLogProxyModel : public QSortFilterProxyModel +class QmlConsoleProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - explicit QtMessageLogProxyModel(QObject *parent = 0); + explicit QmlConsoleProxyModel(QObject *parent); public slots: void setShowLogs(bool show); @@ -61,10 +61,10 @@ protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; private: - QFlags<QtMessageLogHandler::ItemType> m_filter; + QFlags<QmlJS::ConsoleItem::ItemType> m_filter; }; -} // namespace Internal -} // namespace Debugger +} // Internal +} // QmlJSTools -#endif // QTMESSAGELOGPROXYMODEL_H +#endif // QMLCONSOLEPROXYMODEL_H diff --git a/src/plugins/debugger/qtmessagelogview.cpp b/src/plugins/qmljstools/qmlconsoleview.cpp index 65ecdc2784..8d16d9c77f 100644 --- a/src/plugins/debugger/qtmessagelogview.cpp +++ b/src/plugins/qmljstools/qmlconsoleview.cpp @@ -27,12 +27,9 @@ ** ****************************************************************************/ -#include "qtmessagelogview.h" -#include "qtmessagelogitemdelegate.h" -#include "qtmessageloghandler.h" -#include "debuggerstringutils.h" -#include "debuggercore.h" -#include "debuggerengine.h" +#include "qmlconsoleview.h" +#include "qmlconsoleitemdelegate.h" +#include "qmlconsoleitemmodel.h" #include <texteditor/basetexteditor.h> @@ -46,24 +43,22 @@ #include <QUrl> #include <QScrollBar> -namespace Debugger { +using namespace QmlJS; + +namespace QmlJSTools { namespace Internal { -class QtMessageLogViewViewStyle : public QProxyStyle +class QmlConsoleViewStyle : public QProxyStyle { public: - void drawPrimitive(PrimitiveElement element, - const QStyleOption *option, - QPainter *painter, + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const { if (element != QStyle::PE_PanelItemViewRow) QProxyStyle::drawPrimitive(element, option, painter, widget); } - int styleHint(StyleHint hint, - const QStyleOption *option = 0, - const QWidget *widget = 0, + int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const { if (hint == SH_ItemView_ShowDecorationSelected) return 0; @@ -74,11 +69,11 @@ public: /////////////////////////////////////////////////////////////////////// // -// QtMessageLogView +// QmlConsoleView // /////////////////////////////////////////////////////////////////////// -QtMessageLogView::QtMessageLogView(QWidget *parent) : +QmlConsoleView::QmlConsoleView(QWidget *parent) : QTreeView(parent) { setFrameStyle(QFrame::NoFrame); @@ -102,36 +97,35 @@ QtMessageLogView::QtMessageLogView(QWidget *parent) : "QTreeView::branch:open:has-children:has-siblings {" "border-image: none;" "image: none; }")); - QtMessageLogViewViewStyle *style = new QtMessageLogViewViewStyle; + QmlConsoleViewStyle *style = new QmlConsoleViewStyle; setStyle(style); style->setParent(this); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - connect(this, SIGNAL(activated(QModelIndex)), - SLOT(onRowActivated(QModelIndex))); + connect(this, SIGNAL(activated(QModelIndex)), SLOT(onRowActivated(QModelIndex))); } -void QtMessageLogView::onScrollToBottom() +void QmlConsoleView::onScrollToBottom() { - //Keep scrolling to bottom if scroll bar is at maximum() + // Keep scrolling to bottom if scroll bar is at maximum() if (verticalScrollBar()->value() == verticalScrollBar()->maximum()) scrollToBottom(); } -void QtMessageLogView::mousePressEvent(QMouseEvent *event) +void QmlConsoleView::mousePressEvent(QMouseEvent *event) { QPoint pos = event->pos(); QModelIndex index = indexAt(pos); if (index.isValid()) { - QtMessageLogHandler::ItemType type = (QtMessageLogHandler::ItemType)index.data( - QtMessageLogHandler::TypeRole).toInt(); + ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data( + QmlConsoleItemModel::TypeRole).toInt(); bool handled = false; - if (type == QtMessageLogHandler::UndefinedType) { + if (type == ConsoleItem::UndefinedType) { bool showTypeIcon = index.parent() == QModelIndex(); - ConsoleItemPositions positions(visualRect(index), viewOptions().font, - showTypeIcon, true); + ConsoleItemPositions positions(visualRect(index), viewOptions().font, showTypeIcon, + true); if (positions.expandCollapseIcon().contains(pos)) { if (isExpanded(index)) @@ -144,13 +138,12 @@ void QtMessageLogView::mousePressEvent(QMouseEvent *event) if (!handled) QTreeView::mousePressEvent(event); } else { - selectionModel()->setCurrentIndex(model()->index( - model()->rowCount() - 1, 0), - QItemSelectionModel::ClearAndSelect); + selectionModel()->setCurrentIndex(model()->index(model()->rowCount() - 1, 0), + QItemSelectionModel::ClearAndSelect); } } -void QtMessageLogView::keyPressEvent(QKeyEvent *e) +void QmlConsoleView::keyPressEvent(QKeyEvent *e) { if (!e->modifiers() && e->key() == Qt::Key_Return) { emit activated(currentIndex()); @@ -160,22 +153,22 @@ void QtMessageLogView::keyPressEvent(QKeyEvent *e) QTreeView::keyPressEvent(e); } -void QtMessageLogView::resizeEvent(QResizeEvent *e) +void QmlConsoleView::resizeEvent(QResizeEvent *e) { - static_cast<QtMessageLogItemDelegate *>(itemDelegate())->emitSizeHintChanged( + static_cast<QmlConsoleItemDelegate *>(itemDelegate())->emitSizeHintChanged( selectionModel()->currentIndex()); QTreeView::resizeEvent(e); } -void QtMessageLogView::drawBranches(QPainter *painter, const QRect &rect, - const QModelIndex &index) const +void QmlConsoleView::drawBranches(QPainter *painter, const QRect &rect, + const QModelIndex &index) const { - static_cast<QtMessageLogItemDelegate *>(itemDelegate())->drawBackground( - painter, rect, index, false); + static_cast<QmlConsoleItemDelegate *>(itemDelegate())->drawBackground(painter, rect, index, + false); QTreeView::drawBranches(painter, rect, index); } -void QtMessageLogView::contextMenuEvent(QContextMenuEvent *event) +void QmlConsoleView::contextMenuEvent(QContextMenuEvent *event) { QModelIndex itemIndex = indexAt(event->pos()); QMenu menu; @@ -194,69 +187,59 @@ void QtMessageLogView::contextMenuEvent(QContextMenuEvent *event) if (a == 0) return; - if (a == copy) + if (a == copy) { copyToClipboard(itemIndex); - else if (a == show) + } else if (a == show) { onRowActivated(itemIndex); - else if (a == clear) { - QAbstractProxyModel *proxyModel = - qobject_cast<QAbstractProxyModel *>(model()); - QtMessageLogHandler *handler = - qobject_cast<QtMessageLogHandler *>(proxyModel->sourceModel()); + } else if (a == clear) { + QAbstractProxyModel *proxyModel = qobject_cast<QAbstractProxyModel *>(model()); + QmlConsoleItemModel *handler = qobject_cast<QmlConsoleItemModel *>( + proxyModel->sourceModel()); handler->clear(); } } -void QtMessageLogView::onRowActivated(const QModelIndex &index) +void QmlConsoleView::onRowActivated(const QModelIndex &index) { if (!index.isValid()) return; - //See if we have file and line Info + // See if we have file and line Info QString filePath = model()->data(index, - QtMessageLogHandler::FileRole).toString(); + QmlConsoleItemModel::FileRole).toString(); if (!filePath.isEmpty()) { - filePath = debuggerCore()->currentEngine()->toFileInProject( - QUrl(filePath)); QFileInfo fi(filePath); if (fi.exists() && fi.isFile() && fi.isReadable()) { - int line = model()->data(index, - QtMessageLogHandler::LineRole).toInt(); - TextEditor::BaseTextEditorWidget::openEditorAt( - fi.canonicalFilePath(), line); + int line = model()->data(index, QmlConsoleItemModel::LineRole).toInt(); + TextEditor::BaseTextEditorWidget::openEditorAt(fi.canonicalFilePath(), line); } } } -void QtMessageLogView::copyToClipboard(const QModelIndex &index) +void QmlConsoleView::copyToClipboard(const QModelIndex &index) { if (!index.isValid()) return; QString contents = model()->data(index).toString(); - //See if we have file and line Info - QString filePath = model()->data(index, - QtMessageLogHandler::FileRole).toString(); + // See if we have file and line Info + QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString(); if (!filePath.isEmpty()) { - contents = QString(_("%1 %2: %3")).arg(contents).arg(filePath).arg( - model()->data(index, - QtMessageLogHandler::LineRole).toString()); + contents = QString(QLatin1String("%1 %2: %3")).arg(contents).arg(filePath).arg( + model()->data(index, QmlConsoleItemModel::LineRole).toString()); } QClipboard *cb = QApplication::clipboard(); cb->setText(contents); } -bool QtMessageLogView::canShowItemInTextEditor(const QModelIndex &index) +bool QmlConsoleView::canShowItemInTextEditor(const QModelIndex &index) { if (!index.isValid()) return false; - //See if we have file and line Info - QString filePath = model()->data(index, - QtMessageLogHandler::FileRole).toString(); + // See if we have file and line Info + QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString(); if (!filePath.isEmpty()) { - filePath = debuggerCore()->currentEngine()->toFileInProject( - QUrl(filePath)); QFileInfo fi(filePath); if (fi.exists() && fi.isFile() && fi.isReadable()) { return true; @@ -265,5 +248,5 @@ bool QtMessageLogView::canShowItemInTextEditor(const QModelIndex &index) return false; } -} //Internal -} //Debugger +} // Internal +} // QmlJSTools diff --git a/src/plugins/debugger/qtmessagelogview.h b/src/plugins/qmljstools/qmlconsoleview.h index c783816685..d37fb5b853 100644 --- a/src/plugins/debugger/qtmessagelogview.h +++ b/src/plugins/qmljstools/qmlconsoleview.h @@ -27,19 +27,19 @@ ** ****************************************************************************/ -#ifndef QTMESSAGELOGVIEW_H -#define QTMESSAGELOGVIEW_H +#ifndef QMLCONSOLEVIEW_H +#define QMLCONSOLEVIEW_H #include <QTreeView> -namespace Debugger { +namespace QmlJSTools { namespace Internal { -class QtMessageLogView : public QTreeView +class QmlConsoleView : public QTreeView { Q_OBJECT public: - explicit QtMessageLogView(QWidget *parent = 0); + QmlConsoleView(QWidget *parent); public slots: void onScrollToBottom(); @@ -60,7 +60,7 @@ private: bool canShowItemInTextEditor(const QModelIndex &index); }; -} //Internal -} //Debugger +} // Internal +} // QmlJSTools -#endif // QTMESSAGELOGVIEW_H +#endif // QMLCONSOLEVIEW_H diff --git a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp index decf470739..82401b43f0 100644 --- a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp +++ b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp @@ -62,14 +62,14 @@ QmlJSCodeStylePreferencesFactory::QmlJSCodeStylePreferencesFactory() { } -QString QmlJSCodeStylePreferencesFactory::languageId() +Core::Id QmlJSCodeStylePreferencesFactory::languageId() { return Constants::QML_JS_SETTINGS_ID; } QString QmlJSCodeStylePreferencesFactory::displayName() { - return Constants::QML_JS_SETTINGS_NAME; + return QLatin1String(Constants::QML_JS_SETTINGS_NAME); } TextEditor::ICodeStylePreferences *QmlJSCodeStylePreferencesFactory::createCodeStyle() const diff --git a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.h b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.h index 2d9e501669..8891425dab 100644 --- a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.h +++ b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.h @@ -39,13 +39,13 @@ class QmlJSCodeStylePreferencesFactory : public TextEditor::ICodeStylePreference public: QmlJSCodeStylePreferencesFactory(); - virtual QString languageId(); - virtual QString displayName(); - virtual TextEditor::ICodeStylePreferences *createCodeStyle() const; - virtual QWidget *createEditor(TextEditor::ICodeStylePreferences *settings, - QWidget *parent) const; - virtual TextEditor::Indenter *createIndenter() const; - virtual TextEditor::ISnippetProvider *snippetProvider() const; + Core::Id languageId(); + QString displayName(); + TextEditor::ICodeStylePreferences *createCodeStyle() const; + QWidget *createEditor(TextEditor::ICodeStylePreferences *settings, + QWidget *parent) const; + TextEditor::Indenter *createIndenter() const; + TextEditor::ISnippetProvider *snippetProvider() const; QString previewText() const; }; diff --git a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp index 6ec0d5b7e0..9e2e936c18 100644 --- a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp +++ b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp @@ -176,7 +176,7 @@ QmlJSCodeStyleSettingsPage::QmlJSCodeStyleSettingsPage(/*QSharedPointer<CppFileS QWidget *QmlJSCodeStyleSettingsPage::createPage(QWidget *parent) { TextEditor::SimpleCodeStylePreferences *originalTabPreferences - = QmlJSToolsSettings::instance()->qmlJSCodeStyle(); + = QmlJSToolsSettings::globalCodeStyle(); m_pageTabPreferences = new TextEditor::SimpleCodeStylePreferences(m_widget); m_pageTabPreferences->setDelegatingPool(originalTabPreferences->delegatingPool()); m_pageTabPreferences->setTabSettings(originalTabPreferences->tabSettings()); @@ -194,16 +194,16 @@ void QmlJSCodeStyleSettingsPage::apply() if (m_widget) { QSettings *s = Core::ICore::settings(); - TextEditor::SimpleCodeStylePreferences *originalTabPreferences = QmlJSToolsSettings::instance()->qmlJSCodeStyle(); + TextEditor::SimpleCodeStylePreferences *originalTabPreferences = QmlJSToolsSettings::globalCodeStyle(); if (originalTabPreferences->tabSettings() != m_pageTabPreferences->tabSettings()) { originalTabPreferences->setTabSettings(m_pageTabPreferences->tabSettings()); if (s) - originalTabPreferences->toSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID, s); + originalTabPreferences->toSettings(QLatin1String(QmlJSTools::Constants::QML_JS_SETTINGS_ID), s); } if (originalTabPreferences->currentDelegate() != m_pageTabPreferences->currentDelegate()) { originalTabPreferences->setCurrentDelegate(m_pageTabPreferences->currentDelegate()); if (s) - originalTabPreferences->toSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID, s); + originalTabPreferences->toSettings(QLatin1String(QmlJSTools::Constants::QML_JS_SETTINGS_ID), s); } } } diff --git a/src/plugins/qmljstools/qmljsfindexportedcpptypes.cpp b/src/plugins/qmljstools/qmljsfindexportedcpptypes.cpp index c358b219a0..856a691c79 100644 --- a/src/plugins/qmljstools/qmljsfindexportedcpptypes.cpp +++ b/src/plugins/qmljstools/qmljsfindexportedcpptypes.cpp @@ -282,7 +282,7 @@ protected: // and the expression const Token begin = translationUnit()->tokenAt(typeId->firstToken()); const Token last = translationUnit()->tokenAt(typeId->lastToken() - 1); - exportedType.typeExpression = _doc->utf8Source().mid(begin.begin(), last.end() - begin.begin()); + exportedType.typeExpression = QString::fromUtf8(_doc->utf8Source().mid(begin.begin(), last.end() - begin.begin())); _exportedTypes += exportedType; @@ -410,12 +410,12 @@ private: { const Token firstToken = translationUnit()->tokenAt(first); const Token lastToken = translationUnit()->tokenAt(last); - return _doc->utf8Source().mid(firstToken.begin(), lastToken.end() - firstToken.begin()); + return QString::fromUtf8(_doc->utf8Source().mid(firstToken.begin(), lastToken.end() - firstToken.begin())); } QString stringOf(const Token &token) { - return _doc->utf8Source().mid(token.begin(), token.length()); + return QString::fromUtf8(_doc->utf8Source().mid(token.begin(), token.length())); } ExpressionAST *skipStringCall(ExpressionAST *exp) @@ -516,7 +516,7 @@ static FullySpecifiedType stripPointerAndReference(const FullySpecifiedType &typ static QString toQmlType(const FullySpecifiedType &type) { Overview overview; - QString result = overview(stripPointerAndReference(type)); + QString result = overview.prettyType(stripPointerAndReference(type)); if (result == QLatin1String("QString")) result = QLatin1String("string"); return result; @@ -553,7 +553,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject( Overview namePrinter; - fmo->setClassName(namePrinter(klass->name())); + fmo->setClassName(namePrinter.prettyName(klass->name())); // add the no-package export, so the cpp name can be used in properties fmo->addExport(fmo->className(), QmlJS::CppQmlTypes::cppPackage, ComponentVersion()); @@ -564,7 +564,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject( if (Function *func = member->type()->asFunctionType()) { if (!func->isSlot() && !func->isInvokable() && !func->isSignal()) continue; - FakeMetaMethod method(namePrinter(func->name()), toQmlType(func->returnType())); + FakeMetaMethod method(namePrinter.prettyName(func->name()), toQmlType(func->returnType())); if (func->isSignal()) method.setMethodType(FakeMetaMethod::Signal); else @@ -573,7 +573,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject( Symbol *arg = func->argumentAt(a); QString name; if (arg->name()) - name = namePrinter(arg->name()); + name = namePrinter.prettyName(arg->name()); method.addParameter(name, toQmlType(arg->type())); } fmo->addMethod(method); @@ -585,7 +585,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject( const bool isPointer = type.type() && type.type()->isPointerType(); const int revision = 0; // ### fixme FakeMetaProperty property( - namePrinter(propDecl->name()), + namePrinter.prettyName(propDecl->name()), toQmlType(type), isList, isWritable, isPointer, revision); @@ -594,7 +594,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject( if (QtEnum *qtEnum = member->asQtEnum()) { // find the matching enum Enum *e = 0; - QList<LookupItem> result = typeOf(namePrinter(qtEnum->name()).toUtf8(), klass); + QList<LookupItem> result = typeOf(namePrinter.prettyName(qtEnum->name()).toUtf8(), klass); foreach (const LookupItem &item, result) { if (item.declaration()) { e = item.declaration()->asEnum(); @@ -605,12 +605,12 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject( if (!e) continue; - FakeMetaEnum metaEnum(namePrinter(e->name())); + FakeMetaEnum metaEnum(namePrinter.prettyName(e->name())); for (unsigned j = 0; j < e->memberCount(); ++j) { Symbol *enumMember = e->memberAt(j); if (!enumMember->name()) continue; - metaEnum.addKey(namePrinter(enumMember->name()), 0); + metaEnum.addKey(namePrinter.prettyName(enumMember->name()), 0); } fmo->addEnum(metaEnum); } @@ -622,7 +622,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject( if (!base->name()) return fmo; - const QString baseClassName = namePrinter(base->name()); + const QString baseClassName = namePrinter.prettyName(base->name()); fmo->setSuperclassName(baseClassName); Class *baseClass = lookupClass(baseClassName, klass, typeOf); diff --git a/src/plugins/qmljstools/qmljsfunctionfilter.cpp b/src/plugins/qmljstools/qmljsfunctionfilter.cpp index b4450a27ac..97dc5478d8 100644 --- a/src/plugins/qmljstools/qmljsfunctionfilter.cpp +++ b/src/plugins/qmljstools/qmljsfunctionfilter.cpp @@ -70,7 +70,7 @@ QList<Locator::FilterEntry> FunctionFilter::matchesFor(QFutureInterface<Locator: QRegExp regexp(asterisk + entry+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.isValid()) return goodEntries; - bool hasWildcard = (entry.contains(asterisk) || entry.contains('?')); + bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?'))); QHashIterator<QString, QList<LocatorData::Entry> > it(m_data->entries()); while (it.hasNext()) { diff --git a/src/plugins/qmljstools/qmljsfunctionfilter.h b/src/plugins/qmljstools/qmljsfunctionfilter.h index df3d59f300..55c9bb3a2c 100644 --- a/src/plugins/qmljstools/qmljsfunctionfilter.h +++ b/src/plugins/qmljstools/qmljsfunctionfilter.h @@ -44,7 +44,7 @@ public: explicit FunctionFilter(LocatorData *data, QObject *parent = 0); ~FunctionFilter(); - QString displayName() const { return tr("Methods and Functions"); } + QString displayName() const { return tr("QML Methods and Functions"); } QString id() const { return QLatin1String("Functions"); } Priority priority() const { return Medium; } QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry); diff --git a/src/plugins/qmljstools/qmljsinterpreter.cpp b/src/plugins/qmljstools/qmljsinterpreter.cpp new file mode 100644 index 0000000000..a4ce7e4c54 --- /dev/null +++ b/src/plugins/qmljstools/qmljsinterpreter.cpp @@ -0,0 +1,87 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmljsinterpreter.h" + +namespace QmlJSTools { +namespace Internal { + +bool QmlJSInterpreter::canEvaluate() +{ + int yyaction = 0; + int yytoken = -1; + int yytos = -1; + + setCode(m_code, 1); + m_tokens.append(T_FEED_JS_PROGRAM); + + do { + if (++yytos == m_stateStack.size()) + m_stateStack.resize(m_stateStack.size() * 2); + + m_stateStack[yytos] = yyaction; + +again: + if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) { + if (m_tokens.isEmpty()) + yytoken = lex(); + else + yytoken = m_tokens.takeFirst(); + } + + yyaction = t_action(yyaction, yytoken); + if (yyaction > 0) { + if (yyaction == ACCEPT_STATE) { + --yytos; + return true; + } + yytoken = -1; + } else if (yyaction < 0) { + const int ruleno = -yyaction - 1; + yytos -= rhs[ruleno]; + yyaction = nt_action(m_stateStack[yytos], lhs[ruleno] - TERMINAL_COUNT); + } + } while (yyaction); + + const int errorState = m_stateStack[yytos]; + if (t_action(errorState, T_AUTOMATIC_SEMICOLON) && canInsertAutomaticSemicolon(yytoken)) { + yyaction = errorState; + m_tokens.prepend(yytoken); + yytoken = T_SEMICOLON; + goto again; + } + + if (yytoken != EOF_SYMBOL) + return true; + + return false; +} + +} // namespace Internal +} // namespace QmlJSTools diff --git a/src/plugins/qmldesigner/designercore/include/widgetqueryview.h b/src/plugins/qmljstools/qmljsinterpreter.h index 8421e6e2bd..28ff401c9c 100644 --- a/src/plugins/qmldesigner/designercore/include/widgetqueryview.h +++ b/src/plugins/qmljstools/qmljsinterpreter.h @@ -1,4 +1,4 @@ -/**************************************************************************** +/************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal @@ -27,30 +27,43 @@ ** ****************************************************************************/ -#ifndef WIDGETQUERYVIEW_H -#define WIDGETQUERYVIEW_H +#ifndef QMLJSINTERPRETER_H +#define QMLJSINTERPRETER_H -#include "corelib_global.h" -#include "nodeinstanceview.h" -#include "propertycontainer.h" -#include <QHash> -#include <QList> +#include <qmljs/parser/qmljslexer_p.h> +#include <qmljs/parser/qmljsengine_p.h> + +#include <QVector> #include <QString> -#include <QVariant> -#include <QImage> +#include <QList> -namespace QmlDesigner { +namespace QmlJSTools { +namespace Internal { -class CORESHARED_EXPORT WidgetQueryView : public NodeInstanceView +class QmlJSInterpreter: QmlJS::Lexer { - Q_OBJECT public: - WidgetQueryView(QObject *parent); + QmlJSInterpreter() + : Lexer(&m_engine), + m_stateStack(128) + { + + } + + void clearText() { m_code.clear(); } + void appendText(const QString &text) { m_code += text; } + + QString code() const { return m_code; } + bool canEvaluate(); - QImage paintObject(const NodeMetaInfo &metaInfo); - QImage paintObject(const NodeMetaInfo &metaInfo, const QList<PropertyContainer> &properties); +private: + QmlJS::Engine m_engine; + QVector<int> m_stateStack; + QList<int> m_tokens; + QString m_code; }; -} //namespace QmlDesigner +} // namespace Internal +} // namespace QmlJSTools -#endif // WIDGETQUERYVIEW_H +#endif // QMLJSINTERPRETER_H diff --git a/src/plugins/qmljstools/qmljslocatordata.cpp b/src/plugins/qmljstools/qmljslocatordata.cpp index 85ec59501e..d5bd9f10d9 100644 --- a/src/plugins/qmljstools/qmljslocatordata.cpp +++ b/src/plugins/qmljstools/qmljslocatordata.cpp @@ -82,7 +82,7 @@ public: protected: QString contextString(const QString &extra) { - return QString("%1, %2").arg(extra, m_documentContext); + return QString::fromLatin1("%1, %2").arg(extra, m_documentContext); } LocatorData::Entry basicEntry(SourceLocation loc) @@ -130,7 +130,7 @@ protected: m_entries += entry; - accept(ast->body, contextString(QString("function %1").arg(entry.displayName))); + accept(ast->body, contextString(QString::fromLatin1("function %1").arg(entry.displayName))); return false; } @@ -159,7 +159,7 @@ protected: QString context = toString(ast->qualifiedTypeNameId); const QString id = idOfObject(ast); if (!id.isEmpty()) - context = QString("%1 (%2)").arg(id, context); + context = QString::fromLatin1("%1 (%2)").arg(id, context); accept(ast->initializer, contextString(context)); return false; } @@ -172,7 +172,7 @@ protected: QString context = toString(ast->qualifiedTypeNameId); const QString id = idOfObject(ast); if (!id.isEmpty()) - context = QString("%1 (%2)").arg(id, context); + context = QString::fromLatin1("%1 (%2)").arg(id, context); accept(ast->initializer, contextString(context)); return false; } diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index a2d59c61a7..eba6edb429 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -50,6 +50,7 @@ #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/session.h> #include <qtsupport/baseqtversion.h> +#include <utils/hostosinfo.h> #include <QDir> #include <QFile> @@ -71,17 +72,17 @@ static QStringList environmentImportPaths(); QmlJS::Document::Language QmlJSTools::languageOfFile(const QString &fileName) { - QStringList jsSuffixes("js"); - QStringList qmlSuffixes("qml"); - QStringList jsonSuffixes("json"); + QStringList jsSuffixes(QLatin1String("js")); + QStringList qmlSuffixes(QLatin1String("qml")); + QStringList jsonSuffixes(QLatin1String("json")); if (Core::ICore::instance()) { Core::MimeDatabase *db = Core::ICore::mimeDatabase(); - Core::MimeType jsSourceTy = db->findByType(Constants::JS_MIMETYPE); + Core::MimeType jsSourceTy = db->findByType(QLatin1String(Constants::JS_MIMETYPE)); jsSuffixes = jsSourceTy.suffixes(); - Core::MimeType qmlSourceTy = db->findByType(Constants::QML_MIMETYPE); + Core::MimeType qmlSourceTy = db->findByType(QLatin1String(Constants::QML_MIMETYPE)); qmlSuffixes = qmlSourceTy.suffixes(); - Core::MimeType jsonSourceTy = db->findByType(Constants::JSON_MIMETYPE); + Core::MimeType jsonSourceTy = db->findByType(QLatin1String(Constants::JSON_MIMETYPE)); jsonSuffixes = jsonSourceTy.suffixes(); } @@ -101,8 +102,8 @@ QStringList QmlJSTools::qmlAndJsGlobPatterns() QStringList pattern; if (Core::ICore::instance()) { Core::MimeDatabase *db = Core::ICore::mimeDatabase(); - Core::MimeType jsSourceTy = db->findByType(Constants::JS_MIMETYPE); - Core::MimeType qmlSourceTy = db->findByType(Constants::QML_MIMETYPE); + Core::MimeType jsSourceTy = db->findByType(QLatin1String(Constants::JS_MIMETYPE)); + Core::MimeType qmlSourceTy = db->findByType(QLatin1String(Constants::QML_MIMETYPE)); QStringList pattern; foreach (const Core::MimeGlobPattern &glob, jsSourceTy.globPatterns()) @@ -110,7 +111,7 @@ QStringList QmlJSTools::qmlAndJsGlobPatterns() foreach (const Core::MimeGlobPattern &glob, qmlSourceTy.globPatterns()) pattern << glob.regExp().pattern(); } else { - pattern << "*.qml" << "*.js"; + pattern << QLatin1String("*.qml") << QLatin1String("*.js"); } return pattern; } @@ -267,7 +268,7 @@ QFuture<void> ModelManager::refreshSourceFiles(const QStringList &sourceFiles, if (sourceFiles.count() > 1) { Core::ICore::progressManager()->addTask(result, tr("Indexing"), - Constants::TASK_INDEX); + QLatin1String(Constants::TASK_INDEX)); } return result; @@ -464,9 +465,9 @@ static bool findNewQmlLibraryInPath(const QString &path, return false; } -#ifdef Q_OS_WIN - // QTCREATORBUG-3402 - be case sensitive even here? -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + // QTCREATORBUG-3402 - be case sensitive even here? + } // found a new library! qmldirFile.open(QFile::ReadOnly); @@ -503,7 +504,7 @@ static void findNewQmlLibrary( QSet<QString> *scannedPaths, QSet<QString> *newLibraries) { - QString libraryPath = QString("%1.%2.%3").arg( + QString libraryPath = QString::fromLatin1("%1.%2.%3").arg( path, QString::number(version.majorVersion()), QString::number(version.minorVersion())); @@ -511,7 +512,7 @@ static void findNewQmlLibrary( libraryPath, snapshot, modelManager, importedFiles, scannedPaths, newLibraries); - libraryPath = QString("%1.%2").arg( + libraryPath = QString::fromLatin1("%1.%2").arg( path, QString::number(version.majorVersion())); findNewQmlLibraryInPath( @@ -653,12 +654,8 @@ static QStringList environmentImportPaths() QByteArray envImportPath = qgetenv("QML_IMPORT_PATH"); -#if defined(Q_OS_WIN) - QLatin1Char pathSep(';'); -#else - QLatin1Char pathSep(':'); -#endif - foreach (const QString &path, QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts)) { + foreach (const QString &path, QString::fromLatin1(envImportPath) + .split(Utils::HostOsInfo::pathListSeparator(), QString::SkipEmptyParts)) { QString canonicalPath = QDir(path).canonicalPath(); if (!canonicalPath.isEmpty() && !paths.contains(canonicalPath)) paths.append(canonicalPath); diff --git a/src/plugins/qmljstools/qmljsplugindumper.cpp b/src/plugins/qmljstools/qmljsplugindumper.cpp index e4f853c43e..7388c210d4 100644 --- a/src/plugins/qmljstools/qmljsplugindumper.cpp +++ b/src/plugins/qmljstools/qmljsplugindumper.cpp @@ -135,7 +135,7 @@ static QString makeAbsolute(const QString &path, const QString &base) { if (QFileInfo(path).isAbsolute()) return path; - return QString("%1%2%3").arg(base, QDir::separator(), path); + return QString::fromLatin1("%1%2%3").arg(base, QDir::separator(), path); } void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion) @@ -269,7 +269,7 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode) if (exitCode != 0) { Core::MessageManager *messageManager = Core::MessageManager::instance(); - const QString errorMessages = process->readAllStandardError(); + const QString errorMessages = QString::fromLocal8Bit(process->readAllStandardError()); messageManager->printToOutputPane(qmldumpErrorMessage(libraryPath, errorMessages)); libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages)); } @@ -309,7 +309,7 @@ void PluginDumper::qmlPluginTypeDumpError(QProcess::ProcessError) return; Core::MessageManager *messageManager = Core::MessageManager::instance(); - const QString errorMessages = process->readAllStandardError(); + const QString errorMessages = QString::fromLocal8Bit(process->readAllStandardError()); messageManager->printToOutputPane(qmldumpErrorMessage(libraryPath, errorMessages)); if (!libraryPath.isEmpty()) { diff --git a/src/plugins/qmljstools/qmljssemanticinfo.cpp b/src/plugins/qmljstools/qmljssemanticinfo.cpp index 436a6a2b86..bfec2213a1 100644 --- a/src/plugins/qmljstools/qmljssemanticinfo.cpp +++ b/src/plugins/qmljstools/qmljssemanticinfo.cpp @@ -160,14 +160,14 @@ QmlJS::AST::Node *SemanticInfo::declaringMemberNoProperties(int cursorPosition) QList<AST::Node *> path = rangePath(cursorPosition); if (path.size() > 1) return path.at(path.size() - 2); - } else if (name.contains("GradientStop")) { + } else if (name.contains(QLatin1String("GradientStop"))) { QList<AST::Node *> path = rangePath(cursorPosition); if (path.size() > 2) return path.at(path.size() - 3); } } else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(node)) { const QString &name = objectBinding->qualifiedTypeNameId->name.toString(); - if (name.contains("Gradient")) { + if (name.contains(QLatin1String("Gradient"))) { QList<AST::Node *> path = rangePath(cursorPosition); if (path.size() > 1) return path.at(path.size() - 2); diff --git a/src/plugins/qmljstools/qmljstools-lib.pri b/src/plugins/qmljstools/qmljstools-lib.pri deleted file mode 100644 index e618816549..0000000000 --- a/src/plugins/qmljstools/qmljstools-lib.pri +++ /dev/null @@ -1,45 +0,0 @@ -!dll { - DEFINES += QMLJSTOOLS_STATIC -} - -INCLUDEPATH += $$PWD/.. - -HEADERS += \ - $$PWD/qmljstools_global.h \ - $$PWD/qmljstoolsplugin.h \ - $$PWD/qmljstoolsconstants.h \ - $$PWD/qmljstoolssettings.h \ - $$PWD/qmljscodestylepreferencesfactory.h \ - $$PWD/qmljsmodelmanager.h \ - $$PWD/qmljsqtstylecodeformatter.h \ - $$PWD/qmljsrefactoringchanges.h \ - $$PWD/qmljsplugindumper.h \ - $$PWD/qmljsfunctionfilter.h \ - $$PWD/qmljslocatordata.h \ - $$PWD/qmljsindenter.h \ - $$PWD/qmljscodestylesettingspage.h \ - $$PWD/qmljsfindexportedcpptypes.h \ - $$PWD/qmljssemanticinfo.h - -SOURCES += \ - $$PWD/qmljstoolsplugin.cpp \ - $$PWD/qmljstoolssettings.cpp \ - $$PWD/qmljscodestylepreferencesfactory.cpp \ - $$PWD/qmljsmodelmanager.cpp \ - $$PWD/qmljsqtstylecodeformatter.cpp \ - $$PWD/qmljsrefactoringchanges.cpp \ - $$PWD/qmljsplugindumper.cpp \ - $$PWD/qmljsfunctionfilter.cpp \ - $$PWD/qmljslocatordata.cpp \ - $$PWD/qmljsindenter.cpp \ - $$PWD/qmljscodestylesettingspage.cpp \ - $$PWD/qmljsfindexportedcpptypes.cpp \ - $$PWD/qmljssemanticinfo.cpp - -FORMS += \ - $$PWD/qmljscodestylesettingspage.ui - -equals(TEST, 1) { - SOURCES += \ - $$PWD/qmljstools_test.cpp -} diff --git a/src/plugins/qmljstools/qmljstools.pri b/src/plugins/qmljstools/qmljstools.pri index 75415d0c1f..1d36f5e406 100644 --- a/src/plugins/qmljstools/qmljstools.pri +++ b/src/plugins/qmljstools/qmljstools.pri @@ -1,5 +1,3 @@ include(qmljstools_dependencies.pri) -INCLUDEPATH *= $$PWD/.. - LIBS *= -l$$qtLibraryName(QmlJSTools) diff --git a/src/plugins/qmljstools/qmljstools.pro b/src/plugins/qmljstools/qmljstools.pro index 86426bb3b7..32ba18ba18 100644 --- a/src/plugins/qmljstools/qmljstools.pro +++ b/src/plugins/qmljstools/qmljstools.pro @@ -3,8 +3,70 @@ TARGET = QmlJSTools include(../../qtcreatorplugin.pri) include(qmljstools_dependencies.pri) -# DEFINES += QT_NO_CAST_FROM_ASCII -DEFINES += QT_NO_CAST_TO_ASCII +DEFINES += QT_NO_CAST_FROM_ASCII DEFINES += QMLJSTOOLS_LIBRARY -include(qmljstools-lib.pri) +!dll { + DEFINES += QMLJSTOOLS_STATIC +} + +QT += script + +HEADERS += \ + $$PWD/qmljstoolsplugin.h \ + $$PWD/qmljstoolsconstants.h \ + $$PWD/qmljstoolssettings.h \ + $$PWD/qmljscodestylepreferencesfactory.h \ + $$PWD/qmljsmodelmanager.h \ + $$PWD/qmljsqtstylecodeformatter.h \ + $$PWD/qmljsrefactoringchanges.h \ + $$PWD/qmljsplugindumper.h \ + $$PWD/qmljsfunctionfilter.h \ + $$PWD/qmljslocatordata.h \ + $$PWD/qmljsindenter.h \ + $$PWD/qmljscodestylesettingspage.h \ + $$PWD/qmljsfindexportedcpptypes.h \ + $$PWD/qmljssemanticinfo.h \ + $$PWD/qmljstools_global.h \ + $$PWD/qmlconsolemanager.h \ + $$PWD/qmlconsoleitemmodel.h \ + $$PWD/qmlconsolepane.h \ + $$PWD/qmlconsoleview.h \ + $$PWD/qmlconsoleitemdelegate.h \ + $$PWD/qmlconsoleedit.h \ + $$PWD/qmljsinterpreter.h \ + $$PWD/qmlconsoleproxymodel.h + +SOURCES += \ + $$PWD/qmljstoolsplugin.cpp \ + $$PWD/qmljstoolssettings.cpp \ + $$PWD/qmljscodestylepreferencesfactory.cpp \ + $$PWD/qmljsmodelmanager.cpp \ + $$PWD/qmljsqtstylecodeformatter.cpp \ + $$PWD/qmljsrefactoringchanges.cpp \ + $$PWD/qmljsplugindumper.cpp \ + $$PWD/qmljsfunctionfilter.cpp \ + $$PWD/qmljslocatordata.cpp \ + $$PWD/qmljsindenter.cpp \ + $$PWD/qmljscodestylesettingspage.cpp \ + $$PWD/qmljsfindexportedcpptypes.cpp \ + $$PWD/qmljssemanticinfo.cpp \ + $$PWD/qmlconsolemanager.cpp \ + $$PWD/qmlconsoleitemmodel.cpp \ + $$PWD/qmlconsolepane.cpp \ + $$PWD/qmlconsoleview.cpp \ + $$PWD/qmlconsoleitemdelegate.cpp \ + $$PWD/qmlconsoleedit.cpp \ + $$PWD/qmljsinterpreter.cpp \ + $$PWD/qmlconsoleproxymodel.cpp + +RESOURCES += \ + qmljstools.qrc + +FORMS += \ + $$PWD/qmljscodestylesettingspage.ui + +equals(TEST, 1) { + SOURCES += \ + $$PWD/qmljstools_test.cpp +} diff --git a/src/plugins/qmljstools/qmljstools.qbs b/src/plugins/qmljstools/qmljstools.qbs index 2d5d58c64f..5a318f8970 100644 --- a/src/plugins/qmljstools/qmljstools.qbs +++ b/src/plugins/qmljstools/qmljstools.qbs @@ -1,11 +1,12 @@ import qbs.base 1.0 import "../QtcPlugin.qbs" as QtcPlugin +import "../../../qbs/defaults.js" as Defaults QtcPlugin { name: "QmlJSTools" - Depends { name: "Qt.widgets" } + Depends { name: "Qt"; submodules: ["script", "widgets"] } Depends { name: "Core" } Depends { name: "LanguageUtils" } Depends { name: "CppTools" } @@ -17,17 +18,12 @@ QtcPlugin { Depends { name: "QtSupport" } Depends { name: "cpp" } - cpp.defines: base.concat(["QT_NO_CAST_TO_ASCII"]) - cpp.includePaths: [ - "..", - "../../libs", - "../../libs/3rdparty", - buildDirectory - ] + cpp.defines: base.concat(["QT_NO_CAST_FROM_ASCII"]) + cpp.includePaths: base.concat("../../libs/3rdparty") files: [ - "qmljsmodelmanager.cpp", - "qmljsmodelmanager.h", + "qmljscodestylepreferencesfactory.cpp", + "qmljscodestylepreferencesfactory.h", "qmljscodestylesettingspage.cpp", "qmljscodestylesettingspage.h", "qmljscodestylesettingspage.ui", @@ -40,6 +36,8 @@ QtcPlugin { "qmljslocatordata.cpp", "qmljslocatordata.h", "qmljsmodelmanager.cpp", + "qmljsmodelmanager.cpp", + "qmljsmodelmanager.h", "qmljsmodelmanager.h", "qmljsplugindumper.cpp", "qmljsplugindumper.h", @@ -47,21 +45,40 @@ QtcPlugin { "qmljsqtstylecodeformatter.h", "qmljsrefactoringchanges.cpp", "qmljsrefactoringchanges.h", + "qmljssemanticinfo.cpp", + "qmljssemanticinfo.h", "qmljstools_global.h", "qmljstoolsconstants.h", "qmljstoolsplugin.cpp", "qmljstoolsplugin.h", "qmljstoolssettings.cpp", "qmljstoolssettings.h", - "qmljscodestylepreferencesfactory.cpp", - "qmljscodestylepreferencesfactory.h", - "qmljssemanticinfo.cpp", - "qmljssemanticinfo.h" + "qmlconsolemanager.cpp", + "qmlconsolemanager.h", + "qmlconsoleitemmodel.cpp", + "qmlconsoleitemmodel.h", + "qmlconsolepane.cpp", + "qmlconsolepane.h", + "qmlconsoleview.cpp", + "qmlconsoleview.h", + "qmlconsoleitemdelegate.cpp", + "qmlconsoleitemdelegate.h", + "qmlconsoleedit.cpp", + "qmlconsoleedit.h", + "qmlconsoleproxymodel.cpp", + "qmlconsoleproxymodel.h", + "qmljsinterpreter.cpp", + "qmljsinterpreter.h", + "qmljstools.qrc" ] + Group { + condition: Defaults.testsEnabled(qbs) + files: ["qmljstools_test.cpp"] + } + ProductModule { Depends { name: "CppTools" } Depends { name: "QmlDebug" } } } - diff --git a/src/plugins/qmljstools/qmljstools.qrc b/src/plugins/qmljstools/qmljstools.qrc new file mode 100644 index 0000000000..9e396a3995 --- /dev/null +++ b/src/plugins/qmljstools/qmljstools.qrc @@ -0,0 +1,10 @@ +<RCC> + <qresource prefix="/qmljstools"> + <file>images/prompt.png</file> + <file>images/collapse.png</file> + <file>images/warning.png</file> + <file>images/log.png</file> + <file>images/expand.png</file> + <file>images/error.png</file> + </qresource> +</RCC> diff --git a/src/plugins/qmljstools/qmljstools_test.cpp b/src/plugins/qmljstools/qmljstools_test.cpp index 149b3673de..8a8c719d7a 100644 --- a/src/plugins/qmljstools/qmljstools_test.cpp +++ b/src/plugins/qmljstools/qmljstools_test.cpp @@ -55,7 +55,7 @@ void QmlJSTools::Internal::QmlJSToolsPlugin::test_basic() { QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); - const QString welcomescreenRootPath = Core::ICore::resourcePath() + "/welcomescreen/welcomescreen.qml"; + const QString welcomescreenRootPath = Core::ICore::resourcePath() + QLatin1String("/welcomescreen/welcomescreen.qml"); modelManager->updateSourceFiles(QStringList(welcomescreenRootPath), false); modelManager->joinAllThreads(); @@ -67,34 +67,34 @@ void QmlJSTools::Internal::QmlJSToolsPlugin::test_basic() QVERIFY(context); const CppComponentValue *rectangleValue = context->valueOwner()->cppQmlTypes().objectByQualifiedName( - "QtQuick", "QDeclarative1Rectangle", LanguageUtils::ComponentVersion(1, 0)); + QLatin1String("QtQuick"), QLatin1String("QDeclarative1Rectangle"), LanguageUtils::ComponentVersion(1, 0)); QVERIFY(rectangleValue); - QVERIFY(!rectangleValue->isWritable("border")); - QVERIFY(rectangleValue->hasProperty("border")); - QVERIFY(rectangleValue->isPointer("border")); - QVERIFY(rectangleValue->isWritable("color")); - QVERIFY(!rectangleValue->isPointer("color")); + QVERIFY(!rectangleValue->isWritable(QLatin1String("border"))); + QVERIFY(rectangleValue->hasProperty(QLatin1String("border"))); + QVERIFY(rectangleValue->isPointer(QLatin1String("border"))); + QVERIFY(rectangleValue->isWritable(QLatin1String("color"))); + QVERIFY(!rectangleValue->isPointer(QLatin1String("color"))); - const ObjectValue *ovItem = context->lookupType(doc.data(), QStringList() << "Item"); + const ObjectValue *ovItem = context->lookupType(doc.data(), QStringList(QLatin1String("Item"))); QVERIFY(ovItem); - QCOMPARE(ovItem->className(), QString("Item")); - QCOMPARE(context->imports(doc.data())->info("Item", context.data()).name(), QString("QtQuick")); + QCOMPARE(ovItem->className(), QLatin1String("Item")); + QCOMPARE(context->imports(doc.data())->info(QLatin1String("Item"), context.data()).name(), QLatin1String("QtQuick")); - const ObjectValue *ovProperty = context->lookupType(doc.data(), QStringList() << "Item" << "states"); + const ObjectValue *ovProperty = context->lookupType(doc.data(), QStringList() << QLatin1String("Item") << QLatin1String("states")); QVERIFY(ovProperty); - QCOMPARE(ovProperty->className(), QString("State")); + QCOMPARE(ovProperty->className(), QLatin1String("State")); - const CppComponentValue * qmlItemValue = value_cast<CppComponentValue>(ovItem); + const CppComponentValue *qmlItemValue = value_cast<CppComponentValue>(ovItem); QVERIFY(qmlItemValue); - QCOMPARE(qmlItemValue->defaultPropertyName(), QString("data")); - QCOMPARE(qmlItemValue->propertyType("state"), QString("string")); + QCOMPARE(qmlItemValue->defaultPropertyName(), QLatin1String("data")); + QCOMPARE(qmlItemValue->propertyType(QLatin1String("state")), QLatin1String("string")); - const ObjectValue *ovState = context->lookupType(doc.data(), QStringList() << "State"); - const CppComponentValue * qmlState2Value = value_cast<CppComponentValue>(ovState); - QCOMPARE(qmlState2Value->className(), QString("State")); + const ObjectValue *ovState = context->lookupType(doc.data(), QStringList(QLatin1String("State"))); + const CppComponentValue *qmlState2Value = value_cast<CppComponentValue>(ovState); + QCOMPARE(qmlState2Value->className(), QLatin1String("State")); - const ObjectValue *ovImage = context->lookupType(doc.data(), QStringList() << "Image"); - const CppComponentValue * qmlImageValue = value_cast<CppComponentValue>(ovImage); - QCOMPARE(qmlImageValue->className(), QString("Image")); - QCOMPARE(qmlImageValue->propertyType("source"), QString("QUrl")); + const ObjectValue *ovImage = context->lookupType(doc.data(), QStringList(QLatin1String("Image"))); + const CppComponentValue *qmlImageValue = value_cast<CppComponentValue>(ovImage); + QCOMPARE(qmlImageValue->className(), QLatin1String("Image")); + QCOMPARE(qmlImageValue->propertyType(QLatin1String("source")), QLatin1String("QUrl")); } diff --git a/src/plugins/qmljstools/qmljstoolsplugin.cpp b/src/plugins/qmljstools/qmljstoolsplugin.cpp index 69bf5eef8d..9d6e916239 100644 --- a/src/plugins/qmljstools/qmljstoolsplugin.cpp +++ b/src/plugins/qmljstools/qmljstoolsplugin.cpp @@ -34,6 +34,7 @@ #include "qmljscodestylesettingspage.h" #include "qmljstoolsconstants.h" #include "qmljstoolssettings.h" +#include "qmlconsolemanager.h" #include <extensionsystem/pluginmanager.h> @@ -51,6 +52,7 @@ #include <QSettings> #include <QMenu> +using namespace QmlJSTools; using namespace QmlJSTools::Internal; enum { debug = 0 }; @@ -67,6 +69,7 @@ QmlJSToolsPlugin::~QmlJSToolsPlugin() { m_instance = 0; m_modelManager = 0; // deleted automatically + m_consoleManager = 0; // deleted automatically } bool QmlJSToolsPlugin::initialize(const QStringList &arguments, QString *error) @@ -78,6 +81,8 @@ bool QmlJSToolsPlugin::initialize(const QStringList &arguments, QString *error) // Objects m_modelManager = new ModelManager(this); + m_consoleManager = new QmlConsoleManager(this); + // Core::VCSManager *vcsManager = core->vcsManager(); // Core::DocumentManager *fileManager = core->fileManager(); // connect(vcsManager, SIGNAL(repositoryChanged(QString)), @@ -127,14 +132,14 @@ ExtensionSystem::IPlugin::ShutdownFlag QmlJSToolsPlugin::aboutToShutdown() void QmlJSToolsPlugin::onTaskStarted(const QString &type) { - if (type == QmlJSTools::Constants::TASK_INDEX) { + if (type == QLatin1String(QmlJSTools::Constants::TASK_INDEX)) { m_resetCodeModelAction->setEnabled(false); } } void QmlJSToolsPlugin::onAllTasksFinished(const QString &type) { - if (type == QmlJSTools::Constants::TASK_INDEX) { + if (type == QLatin1String(QmlJSTools::Constants::TASK_INDEX)) { m_resetCodeModelAction->setEnabled(true); } } diff --git a/src/plugins/qmljstools/qmljstoolsplugin.h b/src/plugins/qmljstools/qmljstoolsplugin.h index df6297e628..e1ca0036a7 100644 --- a/src/plugins/qmljstools/qmljstoolsplugin.h +++ b/src/plugins/qmljstools/qmljstoolsplugin.h @@ -45,6 +45,7 @@ QT_END_NAMESPACE namespace QmlJSTools { class QmlJSToolsSettings; +class QmlConsoleManager; namespace Internal { @@ -76,6 +77,7 @@ private slots: private: ModelManager *m_modelManager; + QmlConsoleManager *m_consoleManager; QmlJSToolsSettings *m_settings; QAction *m_resetCodeModelAction; diff --git a/src/plugins/qmljstools/qmljstoolssettings.cpp b/src/plugins/qmljstools/qmljstoolssettings.cpp index b602db0544..be35adb071 100644 --- a/src/plugins/qmljstools/qmljstoolssettings.cpp +++ b/src/plugins/qmljstools/qmljstoolssettings.cpp @@ -42,53 +42,40 @@ #include <QSettings> -static const char *idKey = "QmlJSGlobal"; - -using namespace QmlJSTools; -using TextEditor::TabSettings; +using namespace TextEditor; namespace QmlJSTools { -namespace Internal { -class QmlJSToolsSettingsPrivate -{ -public: - TextEditor::SimpleCodeStylePreferences *m_globalCodeStyle; -}; +const char idKey[] = "QmlJSGlobal"; -} // namespace Internal -} // namespace QmlJSTools - -QmlJSToolsSettings *QmlJSToolsSettings::m_instance = 0; +static TextEditor::SimpleCodeStylePreferences *m_globalCodeStyle = 0; QmlJSToolsSettings::QmlJSToolsSettings(QObject *parent) : QObject(parent) - , d(new Internal::QmlJSToolsSettingsPrivate) { - QTC_ASSERT(!m_instance, return); - m_instance = this; + QTC_ASSERT(!m_globalCodeStyle, return); - TextEditor::TextEditorSettings *textEditorSettings = TextEditor::TextEditorSettings::instance(); + TextEditorSettings *textEditorSettings = TextEditorSettings::instance(); // code style factory - TextEditor::ICodeStylePreferencesFactory *factory = new QmlJSTools::QmlJSCodeStylePreferencesFactory(); + ICodeStylePreferencesFactory *factory = new QmlJSCodeStylePreferencesFactory(); textEditorSettings->registerCodeStyleFactory(factory); // code style pool - TextEditor::CodeStylePool *pool = new TextEditor::CodeStylePool(factory, this); + CodeStylePool *pool = new CodeStylePool(factory, this); textEditorSettings->registerCodeStylePool(Constants::QML_JS_SETTINGS_ID, pool); // global code style settings - d->m_globalCodeStyle = new TextEditor::SimpleCodeStylePreferences(this); - d->m_globalCodeStyle->setDelegatingPool(pool); - d->m_globalCodeStyle->setDisplayName(tr("Global", "Settings")); - d->m_globalCodeStyle->setId(idKey); - pool->addCodeStyle(d->m_globalCodeStyle); - textEditorSettings->registerCodeStyle(QmlJSTools::Constants::QML_JS_SETTINGS_ID, d->m_globalCodeStyle); + m_globalCodeStyle = new SimpleCodeStylePreferences(this); + m_globalCodeStyle->setDelegatingPool(pool); + m_globalCodeStyle->setDisplayName(tr("Global", "Settings")); + m_globalCodeStyle->setId(QLatin1String(idKey)); + pool->addCodeStyle(m_globalCodeStyle); + textEditorSettings->registerCodeStyle(QmlJSTools::Constants::QML_JS_SETTINGS_ID, m_globalCodeStyle); // built-in settings // Qt style - TextEditor::SimpleCodeStylePreferences *qtCodeStyle = new TextEditor::SimpleCodeStylePreferences(); + SimpleCodeStylePreferences *qtCodeStyle = new SimpleCodeStylePreferences(); qtCodeStyle->setId(QLatin1String("qt")); qtCodeStyle->setDisplayName(tr("Qt")); qtCodeStyle->setReadOnly(true); @@ -101,13 +88,13 @@ QmlJSToolsSettings::QmlJSToolsSettings(QObject *parent) pool->addCodeStyle(qtCodeStyle); // default delegate for global preferences - d->m_globalCodeStyle->setCurrentDelegate(qtCodeStyle); + m_globalCodeStyle->setCurrentDelegate(qtCodeStyle); pool->loadCustomCodeStyles(); // load global settings (after built-in settings are added to the pool) QSettings *s = Core::ICore::settings(); - d->m_globalCodeStyle->fromSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID, s); + m_globalCodeStyle->fromSettings(QLatin1String(QmlJSTools::Constants::QML_JS_SETTINGS_ID), s); // legacy handling start (Qt Creator Version < 2.4) const bool legacyTransformed = @@ -136,13 +123,13 @@ QmlJSToolsSettings::QmlJSToolsSettings(QObject *parent) } // create custom code style out of old settings - TextEditor::ICodeStylePreferences *oldCreator = pool->createCodeStyle( + ICodeStylePreferences *oldCreator = pool->createCodeStyle( QLatin1String("legacy"), legacyTabSettings, QVariant(), tr("Old Creator")); // change the current delegate and save - d->m_globalCodeStyle->setCurrentDelegate(oldCreator); - d->m_globalCodeStyle->toSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID, s); + m_globalCodeStyle->setCurrentDelegate(oldCreator); + m_globalCodeStyle->toSettings(QLatin1String(QmlJSTools::Constants::QML_JS_SETTINGS_ID), s); } // mark old settings as transformed s->setValue(QLatin1String("QmlJSTabPreferences/LegacyTransformed"), true); @@ -163,19 +150,13 @@ QmlJSToolsSettings::QmlJSToolsSettings(QObject *parent) QmlJSToolsSettings::~QmlJSToolsSettings() { - delete d; - - m_instance = 0; -} - -QmlJSToolsSettings *QmlJSToolsSettings::instance() -{ - return m_instance; + delete m_globalCodeStyle; + m_globalCodeStyle = 0; } -TextEditor::SimpleCodeStylePreferences *QmlJSToolsSettings::qmlJSCodeStyle() const +SimpleCodeStylePreferences *QmlJSToolsSettings::globalCodeStyle() { - return d->m_globalCodeStyle; + return m_globalCodeStyle; } - +} // namespace QmlJSTools diff --git a/src/plugins/qmljstools/qmljstoolssettings.h b/src/plugins/qmljstools/qmljstoolssettings.h index ffd1589887..4118b8df85 100644 --- a/src/plugins/qmljstools/qmljstoolssettings.h +++ b/src/plugins/qmljstools/qmljstoolssettings.h @@ -34,18 +34,9 @@ #include <QObject> -namespace TextEditor -{ -class SimpleCodeStylePreferences; -} - -namespace QmlJSTools -{ +namespace TextEditor { class SimpleCodeStylePreferences; } -namespace Internal -{ -class QmlJSToolsSettingsPrivate; -} +namespace QmlJSTools { /** * This class provides a central place for cpp tools settings. @@ -58,14 +49,7 @@ public: explicit QmlJSToolsSettings(QObject *parent); ~QmlJSToolsSettings(); - static QmlJSToolsSettings *instance(); - - TextEditor::SimpleCodeStylePreferences *qmlJSCodeStyle() const; - -private: - Internal::QmlJSToolsSettingsPrivate *d; - - static QmlJSToolsSettings *m_instance; + static TextEditor::SimpleCodeStylePreferences *globalCodeStyle(); }; } // namespace QmlJSTools diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs index 345a5354e0..7a97fec0b7 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.qbs +++ b/src/plugins/qmlprofiler/qmlprofiler.qbs @@ -20,17 +20,13 @@ QtcPlugin { Depends { name: "CPlusPlus" } Depends { name: "cpp" } - cpp.includePaths: [ - "canvas", - "..", - "../../libs", - buildDirectory - ] + cpp.includePaths: base.concat("canvas") files: [ "abstractqmlprofilerrunner.h", "localqmlprofilerrunner.cpp", "localqmlprofilerrunner.h", + "qmlprofiler_global.h", "qmlprofilerattachdialog.cpp", "qmlprofilerattachdialog.h", "qmlprofilerattachdialog.ui", @@ -45,7 +41,6 @@ QtcPlugin { "qmlprofilerengine.h", "qmlprofilereventview.cpp", "qmlprofilereventview.h", - "qmlprofiler_global.h", "qmlprofilerplugin.cpp", "qmlprofilerplugin.h", "qmlprofilerstatemanager.cpp", @@ -75,6 +70,7 @@ QtcPlugin { "qml/Detail.qml", "qml/Label.qml", "qml/MainView.qml", + "qml/Overview.js", "qml/Overview.qml", "qml/RangeDetails.qml", "qml/RangeMover.qml", @@ -84,7 +80,5 @@ QtcPlugin { "qml/TimeDisplay.qml", "qml/TimeMarks.qml", "qml/qmlprofiler.qrc", - "qml/Overview.js" ] } - diff --git a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp index 625bb99a69..68d02cd636 100644 --- a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp @@ -36,7 +36,7 @@ #include <qmldebug/qv8profilerclient.h> #include <utils/qtcassert.h> -#include <QWeakPointer> +#include <QPointer> #include <QTimer> #include <QMessageBox> @@ -53,8 +53,8 @@ public: QmlProfilerStateManager* profilerState; QmlDebugConnection *connection; - QWeakPointer<QmlProfilerTraceClient> qmlclientplugin; - QWeakPointer<QV8ProfilerClient> v8clientplugin; + QPointer<QmlProfilerTraceClient> qmlclientplugin; + QPointer<QV8ProfilerClient> v8clientplugin; QTimer connectionTimer; int connectionAttempts; diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 8b539bfa27..6ff47b359e 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -199,7 +199,7 @@ QmlProfilerTool::~QmlProfilerTool() Core::Id QmlProfilerTool::id() const { - return "QmlProfiler"; + return Core::Id("QmlProfiler"); } RunMode QmlProfilerTool::runMode() const diff --git a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp index 161bf8aa43..81ed97d1c0 100644 --- a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp +++ b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp @@ -325,7 +325,7 @@ ImageFileFilterItem::ImageFileFilterItem(QObject *parent) // supported image formats according to QList<QByteArray> extensions = QImageReader::supportedImageFormats(); foreach (const QByteArray &extension, extensions) { - filter.append(QString("*.%1;").arg(QString::fromAscii(extension))); + filter.append(QString("*.%1;").arg(QString::fromLatin1(extension))); } setFilter(filter); } diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index abd4f2e5a4..e20ab08a6b 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -301,11 +301,6 @@ bool QmlProject::supportsKit(ProjectExplorer::Kit *k, QString *errorMessage) con return version; } -QList<ProjectExplorer::BuildConfigWidget*> QmlProject::subConfigWidgets() -{ - return QList<ProjectExplorer::BuildConfigWidget*>(); -} - ProjectExplorer::ProjectNode *QmlProject::rootProjectNode() const { return m_rootNode; diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h index af49bfa284..4b642db986 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.h +++ b/src/plugins/qmlprojectmanager/qmlproject.h @@ -35,6 +35,7 @@ #include <projectexplorer/project.h> #include <QDeclarativeEngine> +#include <QPointer> namespace ProjectExplorer { class RunConfiguration; } namespace QmlJS { class ModelManagerInterface; } @@ -67,8 +68,6 @@ public: bool supportsKit(ProjectExplorer::Kit *k, QString *errorMessage) const; - QList<ProjectExplorer::BuildConfigWidget*> subConfigWidgets(); - ProjectExplorer::ProjectNode *rootProjectNode() const; QStringList files(FilesMode fileMode) const; @@ -117,7 +116,7 @@ private: // qml based, new format QDeclarativeEngine m_engine; - QWeakPointer<QmlProjectItem> m_projectItem; + QPointer<QmlProjectItem> m_projectItem; Internal::QmlProjectNode *m_rootNode; }; diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs b/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs index 5461694201..2b30235949 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs @@ -13,46 +13,39 @@ QtcPlugin { Depends { name: "QmlJS" } Depends { name: "Debugger" } Depends { name: "QtSupport" } - - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] + Depends { name: "app_version_header" } files: [ - "fileformat/qmlprojectitem.h", - "fileformat/filefilteritems.h", - "fileformat/qmlprojectfileformat.h", + "QmlProject.mimetypes.xml", + "qmlproject.cpp", "qmlproject.h", - "qmlprojectplugin.h", - "qmlprojectmanager.h", + "qmlproject.qrc", + "qmlprojectapplicationwizard.cpp", + "qmlprojectapplicationwizard.h", "qmlprojectconstants.h", - "qmlprojectnodes.h", + "qmlprojectfile.cpp", "qmlprojectfile.h", - "qmlprojectruncontrol.h", - "qmlprojectrunconfiguration.h", - "qmlprojectrunconfigurationfactory.h", - "qmlprojectapplicationwizard.h", + "qmlprojectmanager.cpp", + "qmlprojectmanager.h", "qmlprojectmanager_global.h", "qmlprojectmanagerconstants.h", - "qmlprojectrunconfigurationwidget.h", - "fileformat/qmlprojectitem.cpp", - "fileformat/filefilteritems.cpp", - "fileformat/qmlprojectfileformat.cpp", - "qmlproject.cpp", - "qmlprojectplugin.cpp", - "qmlprojectmanager.cpp", "qmlprojectnodes.cpp", - "qmlprojectfile.cpp", - "qmlprojectruncontrol.cpp", + "qmlprojectnodes.h", + "qmlprojectplugin.cpp", + "qmlprojectplugin.h", "qmlprojectrunconfiguration.cpp", + "qmlprojectrunconfiguration.h", "qmlprojectrunconfigurationfactory.cpp", - "qmlprojectapplicationwizard.cpp", + "qmlprojectrunconfigurationfactory.h", "qmlprojectrunconfigurationwidget.cpp", - "qmlproject.qrc", - "QmlProject.mimetypes.xml" + "qmlprojectrunconfigurationwidget.h", + "qmlprojectruncontrol.cpp", + "qmlprojectruncontrol.h", + "fileformat/filefilteritems.cpp", + "fileformat/filefilteritems.h", + "fileformat/qmlprojectfileformat.cpp", + "fileformat/qmlprojectfileformat.h", + "fileformat/qmlprojectitem.cpp", + "fileformat/qmlprojectitem.h", ] } - diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h index a20c4cb217..df331ede42 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h @@ -34,7 +34,7 @@ #include <projectexplorer/runconfiguration.h> -#include <QWeakPointer> +#include <QPointer> QT_FORWARD_DECLARE_CLASS(QStringListModel) @@ -124,7 +124,7 @@ private: QString m_scriptFile; QString m_qmlViewerArgs; - QWeakPointer<Internal::QmlProjectRunConfigurationWidget> m_configurationWidget; + QPointer<Internal::QmlProjectRunConfigurationWidget> m_configurationWidget; bool m_isEnabled; diff --git a/src/plugins/qnx/blackberryapplicationrunner.cpp b/src/plugins/qnx/blackberryapplicationrunner.cpp index 2f8438821f..d69092eb0c 100644 --- a/src/plugins/qnx/blackberryapplicationrunner.cpp +++ b/src/plugins/qnx/blackberryapplicationrunner.cpp @@ -103,11 +103,11 @@ BlackBerryApplicationRunner::BlackBerryApplicationRunner(bool debugMode, BlackBe m_environment = buildConfig->environment(); m_deployCmd = m_environment.searchInPath(QLatin1String(DEPLOY_CMD)); - m_deviceHost = runConfiguration->deployConfiguration()->deviceHost(); - m_password = runConfiguration->deployConfiguration()->password(); + BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target->kit()); + m_deviceHost = device->sshParameters().host; + m_password = device->sshParameters().password; m_barPackage = runConfiguration->barPackage(); - BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target->kit()); m_sshParams = device->sshParameters(); // The BlackBerry device always uses key authentication m_sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationByKey; diff --git a/src/plugins/qnx/blackberryconnect.cpp b/src/plugins/qnx/blackberryconnect.cpp index 9a9192a95b..1d241ba9dd 100644 --- a/src/plugins/qnx/blackberryconnect.cpp +++ b/src/plugins/qnx/blackberryconnect.cpp @@ -55,8 +55,12 @@ QMap<QString, int> BlackBerryConnect::m_usageCount = QMap<QString, int>(); BlackBerryConnect *BlackBerryConnect::instance(BlackBerryRunConfiguration *runConfig) { - BlackBerryDeployConfiguration *deployConfig = runConfig->deployConfiguration(); - QString deviceHost = deployConfig->deviceHost(); + + BlackBerryDeviceConfiguration::ConstPtr device + = BlackBerryDeviceConfiguration::device(runConfig->target()->kit()); + QString deviceHost; + if (device) + deviceHost = device->sshParameters().host; if (!m_instances.contains(deviceHost)) { m_instances[deviceHost] = new BlackBerryConnect(runConfig); m_usageCount[deviceHost] = 1; @@ -97,11 +101,10 @@ BlackBerryConnect::BlackBerryConnect(BlackBerryRunConfiguration *runConfig) m_connectCmd = env.searchInPath(QLatin1String(CONNECT_CMD)); m_qnxHost = env.value(QLatin1String("QNX_HOST")); - BlackBerryDeployConfiguration *deployConfig = runConfig->deployConfiguration(); - m_deviceHost = deployConfig->deviceHost(); - m_password = deployConfig->password(); - - BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target->kit()); + BlackBerryDeviceConfiguration::ConstPtr device + = BlackBerryDeviceConfiguration::device(target->kit()); + m_deviceHost = device->sshParameters().host; + m_password = device->sshParameters().password; m_publicKeyFile = device->sshParameters().privateKeyFile + QLatin1String(".pub"); connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput())); diff --git a/src/plugins/qnx/blackberrydeployconfiguration.cpp b/src/plugins/qnx/blackberrydeployconfiguration.cpp index 4f6e6a7a09..4bee532888 100644 --- a/src/plugins/qnx/blackberrydeployconfiguration.cpp +++ b/src/plugins/qnx/blackberrydeployconfiguration.cpp @@ -37,10 +37,15 @@ #include <projectexplorer/kitinformation.h> #include <projectexplorer/target.h> +#include <projectexplorer/projectexplorer.h> #include <qt4projectmanager/qt4nodes.h> #include <qt4projectmanager/qt4project.h> +#include <qt4projectmanager/qt4buildconfiguration.h> +#include <coreplugin/icore.h> #include <ssh/sshconnection.h> +#include <QMessageBox> + using namespace Qnx; using namespace Qnx::Internal; @@ -59,6 +64,7 @@ BlackBerryDeployConfiguration::BlackBerryDeployConfiguration(ProjectExplorer::Ta : ProjectExplorer::DeployConfiguration(parent, source) { ctor(); + cloneSteps(source); } void BlackBerryDeployConfiguration::ctor() @@ -74,42 +80,86 @@ void BlackBerryDeployConfiguration::ctor() setDefaultDisplayName(tr("Deploy to BlackBerry Device")); } -BlackBerryDeployConfiguration::~BlackBerryDeployConfiguration() +void BlackBerryDeployConfiguration::setupBarDescriptor() { + Qt4ProjectManager::Qt4BuildConfiguration *bc = qobject_cast<Qt4ProjectManager::Qt4BuildConfiguration *>(target()->activeBuildConfiguration()); + if (!bc || !target()->kit()) + return; + + Core::Id deviceType = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(target()->kit()); + QString projectName = target()->project()->displayName(); + + if (deviceType == Constants::QNX_BB_OS_TYPE) { + const QLatin1String barDescriptorFileName("bar-descriptor.xml"); + Utils::FileName barDescriptorPath = Utils::FileName::fromString(target()->project()->projectDirectory()).appendPath(barDescriptorFileName); + const QFile barDescriptorFile(barDescriptorPath.toString()); + if (barDescriptorFile.exists()) + return; + + Utils::FileReader reader; + QString barDescriptorTemplate; + if (QDir(Utils::FileName::fromString(target()->project()->projectDirectory()).appendPath(QLatin1String("qml")).toString()).exists()) + barDescriptorTemplate = Core::ICore::resourcePath() + + QLatin1String("/templates/wizards/bb-quickapp/") + barDescriptorFileName; + else + barDescriptorTemplate = Core::ICore::resourcePath() + + QLatin1String("/templates/wizards/bb-guiapp/") + barDescriptorFileName; + + + if (!reader.fetch(barDescriptorTemplate)) { + QMessageBox::warning(Core::ICore::mainWindow(), + tr("Error while setting up bar descriptor"), + tr("Reading bar descriptor template failed"), + QMessageBox::Ok); + return; + } + + QString content = QString::fromUtf8(reader.data()); + content.replace(QLatin1String("%ProjectName%"), projectName); + Utils::FileSaver writer(barDescriptorFile.fileName(), QIODevice::WriteOnly); + writer.write(content.toUtf8()); + if (!writer.finalize()) { + QMessageBox::warning(Core::ICore::mainWindow(), + tr("Error while setting up bar descriptor"), + tr("Failure writing bar descriptor file."), + QMessageBox::Ok); + return; + } + + // Add the Bar Descriptor to the existing project + if (target()->project()->rootProjectNode()) + addBarDescriptorToProject(barDescriptorPath.toString()); + } } -BlackBerryDeployInformation *BlackBerryDeployConfiguration::deploymentInfo() const -{ - BlackBerryDeployInformation *info - = qobject_cast<BlackBerryDeployInformation *>(target()->project()->namedSettings(QLatin1String(DEPLOYMENT_INFO_SETTING)).value<QObject *>()); - return info; -} - -QString BlackBerryDeployConfiguration::deviceHost() const +void BlackBerryDeployConfiguration::addBarDescriptorToProject(const QString &barDesciptorPath) { - BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target()->kit()); - if (!device) - return QString(); - - return device->sshParameters().host; + if (barDesciptorPath.isEmpty()) + return; + + QMessageBox::StandardButton button = + QMessageBox::question(Core::ICore::mainWindow(), + tr("Add bar-descriptor.xml file to project"), + tr("Qt Creator has set up a bar descriptor file to enable " + "packaging.\nDo you want to add it to the project?"), + QMessageBox::Yes | QMessageBox::No); + if (button == QMessageBox::Yes) + ProjectExplorer::ProjectExplorerPlugin::instance() + ->addExistingFiles(target()->project()->rootProjectNode(), QStringList() << barDesciptorPath); } -QString BlackBerryDeployConfiguration::password() const +BlackBerryDeployConfiguration::~BlackBerryDeployConfiguration() { - BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target()->kit()); - return device->sshParameters().password; } -QString BlackBerryDeployConfiguration::deviceName() const +BlackBerryDeployInformation *BlackBerryDeployConfiguration::deploymentInfo() const { - BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target()->kit()); - if (!device) - return QString(); - - return device->displayName(); + BlackBerryDeployInformation *info + = qobject_cast<BlackBerryDeployInformation *>(target()->project()->namedSettings(QLatin1String(DEPLOYMENT_INFO_SETTING)).value<QObject *>()); + return info; } -ProjectExplorer::DeployConfigurationWidget *BlackBerryDeployConfiguration::configurationWidget() const +ProjectExplorer::NamedWidget *BlackBerryDeployConfiguration::createConfigWidget() { - return new BlackBerryDeployConfigurationWidget; + return new BlackBerryDeployConfigurationWidget(this); } diff --git a/src/plugins/qnx/blackberrydeployconfiguration.h b/src/plugins/qnx/blackberrydeployconfiguration.h index 1e9c772dbb..c6238eb27b 100644 --- a/src/plugins/qnx/blackberrydeployconfiguration.h +++ b/src/plugins/qnx/blackberrydeployconfiguration.h @@ -54,19 +54,17 @@ public: explicit BlackBerryDeployConfiguration(ProjectExplorer::Target *parent); virtual ~BlackBerryDeployConfiguration(); - ProjectExplorer::DeployConfigurationWidget *configurationWidget() const; + ProjectExplorer::NamedWidget *createConfigWidget(); BlackBerryDeployInformation *deploymentInfo() const; - QString deviceHost() const; - QString password() const; - QString deviceName() const; - protected: BlackBerryDeployConfiguration(ProjectExplorer::Target *parent, BlackBerryDeployConfiguration *source); private: void ctor(); + void setupBarDescriptor(); + void addBarDescriptorToProject(const QString& barDescriptorPath); }; } // namespace Internal diff --git a/src/plugins/qnx/blackberrydeployconfigurationfactory.cpp b/src/plugins/qnx/blackberrydeployconfigurationfactory.cpp index 9579f28f3a..f3a64af0bf 100644 --- a/src/plugins/qnx/blackberrydeployconfigurationfactory.cpp +++ b/src/plugins/qnx/blackberrydeployconfigurationfactory.cpp @@ -92,6 +92,7 @@ ProjectExplorer::DeployConfiguration *BlackBerryDeployConfigurationFactory::crea return 0; BlackBerryDeployConfiguration *dc = new BlackBerryDeployConfiguration(parent); + dc->setupBarDescriptor(); dc->stepList()->insertStep(0, new BlackBerryCreatePackageStep(dc->stepList())); dc->stepList()->insertStep(1, new BlackBerryDeployStep(dc->stepList())); return dc; diff --git a/src/plugins/qnx/blackberrydeployconfigurationwidget.cpp b/src/plugins/qnx/blackberrydeployconfigurationwidget.cpp index 38b4172a07..0f62570ead 100644 --- a/src/plugins/qnx/blackberrydeployconfigurationwidget.cpp +++ b/src/plugins/qnx/blackberrydeployconfigurationwidget.cpp @@ -43,22 +43,14 @@ using namespace Qnx; using namespace Qnx::Internal; -BlackBerryDeployConfigurationWidget::BlackBerryDeployConfigurationWidget(QWidget *parent) - : ProjectExplorer::DeployConfigurationWidget(parent) +BlackBerryDeployConfigurationWidget::BlackBerryDeployConfigurationWidget(BlackBerryDeployConfiguration *dc, + QWidget *parent) + : ProjectExplorer::NamedWidget(parent) , m_ui(new Ui::BlackBerryDeployConfigurationWidget) , m_deployConfiguration(0) { m_ui->setupUi(this); -} - -BlackBerryDeployConfigurationWidget::~BlackBerryDeployConfigurationWidget() -{ - delete m_ui; -} - -void BlackBerryDeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc) -{ - m_deployConfiguration = qobject_cast<BlackBerryDeployConfiguration *>(dc); + m_deployConfiguration = dc; m_ui->deployPackagesView->setModel(m_deployConfiguration->deploymentInfo()); @@ -75,3 +67,8 @@ void BlackBerryDeployConfigurationWidget::init(ProjectExplorer::DeployConfigurat m_ui->deployPackagesView->header()->resizeSections(QHeaderView::ResizeToContents); } + +BlackBerryDeployConfigurationWidget::~BlackBerryDeployConfigurationWidget() +{ + delete m_ui; +} diff --git a/src/plugins/qnx/blackberrydeployconfigurationwidget.h b/src/plugins/qnx/blackberrydeployconfigurationwidget.h index d2451f64bb..093ed69846 100644 --- a/src/plugins/qnx/blackberrydeployconfigurationwidget.h +++ b/src/plugins/qnx/blackberrydeployconfigurationwidget.h @@ -43,15 +43,13 @@ class BlackBerryDeployConfigurationWidget; class BlackBerryDeployConfiguration; -class BlackBerryDeployConfigurationWidget : public ProjectExplorer::DeployConfigurationWidget +class BlackBerryDeployConfigurationWidget : public ProjectExplorer::NamedWidget { Q_OBJECT public: - explicit BlackBerryDeployConfigurationWidget(QWidget *parent = 0); + explicit BlackBerryDeployConfigurationWidget(BlackBerryDeployConfiguration *dc, QWidget *parent = 0); ~BlackBerryDeployConfigurationWidget(); - void init(ProjectExplorer::DeployConfiguration *dc); - private: Ui::BlackBerryDeployConfigurationWidget *m_ui; diff --git a/src/plugins/qnx/blackberrydeploystep.cpp b/src/plugins/qnx/blackberrydeploystep.cpp index 13efd32b4c..82bd1643cb 100644 --- a/src/plugins/qnx/blackberrydeploystep.cpp +++ b/src/plugins/qnx/blackberrydeploystep.cpp @@ -41,6 +41,7 @@ #include <projectexplorer/target.h> #include <qt4projectmanager/qt4buildconfiguration.h> #include <utils/qtcassert.h> +#include <ssh/sshconnection.h> #include <QDir> @@ -173,14 +174,20 @@ ProjectExplorer::BuildStepConfigWidget *BlackBerryDeployStep::createConfigWidget QString BlackBerryDeployStep::deviceHost() const { - BlackBerryDeployConfiguration *dc = static_cast<BlackBerryDeployConfiguration *>(deployConfiguration()); - return dc->deviceHost(); + BlackBerryDeviceConfiguration::ConstPtr device + = BlackBerryDeviceConfiguration::device(target()->kit()); + if (device) + return device->sshParameters().host; + return QString(); } QString BlackBerryDeployStep::password() const { - BlackBerryDeployConfiguration *dc = static_cast<BlackBerryDeployConfiguration *>(deployConfiguration()); - return dc->password(); + BlackBerryDeviceConfiguration::ConstPtr device + = BlackBerryDeviceConfiguration::device(target()->kit()); + if (device) + return device->sshParameters().password; + return QString(); } void BlackBerryDeployStep::raiseError(const QString &errorMessage) diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizard.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwizard.cpp index 5955a078a2..d7b80d7eb5 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizard.cpp +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizard.cpp @@ -66,7 +66,7 @@ BlackBerryDeviceConfigurationWizard::BlackBerryDeviceConfigurationWizard(QWidget ProjectExplorer::IDevice::Ptr BlackBerryDeviceConfigurationWizard::device() { QSsh::SshConnectionParameters sshParams; - sshParams.proxyType = QSsh::SshConnectionParameters::NoProxy; + sshParams.options = QSsh::SshIgnoreDefaultProxy; sshParams.host = m_setupPage->hostName(); sshParams.password = m_setupPage->password(); sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationByKey; diff --git a/src/plugins/qnx/blackberryqtversion.cpp b/src/plugins/qnx/blackberryqtversion.cpp index efa8614abf..fefe644b2f 100644 --- a/src/plugins/qnx/blackberryqtversion.cpp +++ b/src/plugins/qnx/blackberryqtversion.cpp @@ -34,6 +34,7 @@ #include "qnxconstants.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QTextStream> @@ -65,29 +66,32 @@ QMultiMap<QString, QString> parseEnvironmentFile(const QString &fileName) QString value = line.mid(equalIndex + 1); -#if defined Q_OS_WIN - QRegExp systemVarRegExp(QLatin1String("IF NOT DEFINED ([\\w\\d]+)\\s+set ([\\w\\d]+)=([\\w\\d]+)")); - if (line.contains(systemVarRegExp)) { - var = systemVarRegExp.cap(2); - Utils::Environment sysEnv = Utils::Environment::systemEnvironment(); - QString sysVar = systemVarRegExp.cap(1); - if (sysEnv.hasKey(sysVar)) - value = sysEnv.value(sysVar); - else - value = systemVarRegExp.cap(3); + if (Utils::HostOsInfo::isWindowsHost()) { + QRegExp systemVarRegExp(QLatin1String("IF NOT DEFINED ([\\w\\d]+)\\s+set " + "([\\w\\d]+)=([\\w\\d]+)")); + if (line.contains(systemVarRegExp)) { + var = systemVarRegExp.cap(2); + Utils::Environment sysEnv = Utils::Environment::systemEnvironment(); + QString sysVar = systemVarRegExp.cap(1); + if (sysEnv.hasKey(sysVar)) + value = sysEnv.value(sysVar); + else + value = systemVarRegExp.cap(3); + } } -#elif defined Q_OS_UNIX - QRegExp systemVarRegExp(QLatin1String("\\$\\{([\\w\\d]+):=([\\w\\d]+)\\}")); // to match e.g. "${QNX_HOST_VERSION:=10_0_9_52}" - if (value.contains(systemVarRegExp)) { - Utils::Environment sysEnv = Utils::Environment::systemEnvironment(); - QString sysVar = systemVarRegExp.cap(1); - if (sysEnv.hasKey(sysVar)) - value = sysEnv.value(sysVar); - else - value = systemVarRegExp.cap(2); + else if (Utils::HostOsInfo::isAnyUnixHost()) { + // to match e.g. "${QNX_HOST_VERSION:=10_0_9_52}" + QRegExp systemVarRegExp(QLatin1String("\\$\\{([\\w\\d]+):=([\\w\\d]+)\\}")); + + if (value.contains(systemVarRegExp)) { + Utils::Environment sysEnv = Utils::Environment::systemEnvironment(); + QString sysVar = systemVarRegExp.cap(1); + if (sysEnv.hasKey(sysVar)) + value = sysEnv.value(sysVar); + else + value = systemVarRegExp.cap(2); + } } -#endif - if (value.startsWith(QLatin1Char('"'))) value = value.mid(1); if (value.endsWith(QLatin1Char('"'))) @@ -100,11 +104,8 @@ QMultiMap<QString, QString> parseEnvironmentFile(const QString &fileName) QMapIterator<QString, QString> it(fileContent); while (it.hasNext()) { it.next(); -#if defined Q_OS_WIN - QStringList values = it.value().split(QLatin1Char(';')); -#elif defined Q_OS_UNIX - QStringList values = it.value().split(QLatin1Char(':')); -#endif + const QStringList values + = it.value().split(Utils::HostOsInfo::pathListSeparator()); QString key = it.key(); foreach (const QString &value, values) { const QString ownKeyAsWindowsVar = QLatin1Char('%') + key + QLatin1Char('%'); @@ -173,11 +174,11 @@ QMultiMap<QString, QString> BlackBerryQtVersion::environment() const if (sdkPath().isEmpty()) return QMultiMap<QString, QString>(); -#if defined Q_OS_WIN - const QString envFile = sdkPath() + QLatin1String("/bbndk-env.bat"); -#elif defined Q_OS_UNIX - const QString envFile = sdkPath() + QLatin1String("/bbndk-env.sh"); -#endif + QString envFile; + if (Utils::HostOsInfo::isWindowsHost()) + envFile = sdkPath() + QLatin1String("/bbndk-env.bat"); + else if (Utils::HostOsInfo::isAnyUnixHost()) + envFile = sdkPath() + QLatin1String("/bbndk-env.sh"); return parseEnvironmentFile(envFile); } diff --git a/src/plugins/qnx/blackberryrunconfiguration.cpp b/src/plugins/qnx/blackberryrunconfiguration.cpp index 7d85a445f3..b6339d0b17 100644 --- a/src/plugins/qnx/blackberryrunconfiguration.cpp +++ b/src/plugins/qnx/blackberryrunconfiguration.cpp @@ -87,7 +87,12 @@ QString BlackBerryRunConfiguration::proFilePath() const QString BlackBerryRunConfiguration::deviceName() const { - return deployConfiguration()->deviceName(); + BlackBerryDeviceConfiguration::ConstPtr device + = BlackBerryDeviceConfiguration::device(target()->kit()); + if (!device) + return QString(); + + return device->displayName(); } QString BlackBerryRunConfiguration::barPackage() const diff --git a/src/plugins/qnx/blackberryruncontrolfactory.cpp b/src/plugins/qnx/blackberryruncontrolfactory.cpp index 06c86a29d9..21bd416775 100644 --- a/src/plugins/qnx/blackberryruncontrolfactory.cpp +++ b/src/plugins/qnx/blackberryruncontrolfactory.cpp @@ -72,7 +72,7 @@ bool BlackBerryRunControlFactory::canRun(ProjectExplorer::RunConfiguration *runC // not launch a second instance. Disable the Run button if the application is already // running on the device. if (m_activeRunControls.contains(rc->key())) { - QWeakPointer<ProjectExplorer::RunControl> activeRunControl = m_activeRunControls[rc->key()]; + QPointer<ProjectExplorer::RunControl> activeRunControl = m_activeRunControls[rc->key()]; if (activeRunControl && activeRunControl.data()->isRunning()) return false; else @@ -101,7 +101,7 @@ ProjectExplorer::RunControl *BlackBerryRunControlFactory::create(ProjectExplorer if (mode == ProjectExplorer::NormalRunMode) { BlackBerryRunControl *runControl = new BlackBerryRunControl(rc); - m_activeRunControls[rc->key()] = QWeakPointer<ProjectExplorer::RunControl>(runControl); + m_activeRunControls[rc->key()] = runControl; return runControl; } @@ -111,7 +111,7 @@ ProjectExplorer::RunControl *BlackBerryRunControlFactory::create(ProjectExplorer return 0; new BlackBerryDebugSupport(rc, runControl); - m_activeRunControls[rc->key()] = QWeakPointer<ProjectExplorer::RunControl>(runControl); + m_activeRunControls[rc->key()] = runControl; return runControl; } diff --git a/src/plugins/qnx/blackberryruncontrolfactory.h b/src/plugins/qnx/blackberryruncontrolfactory.h index 0f014cc04e..d87379957f 100644 --- a/src/plugins/qnx/blackberryruncontrolfactory.h +++ b/src/plugins/qnx/blackberryruncontrolfactory.h @@ -66,7 +66,7 @@ public: private: static Debugger::DebuggerStartParameters startParameters( const BlackBerryRunConfiguration *runConfig); - mutable QMap<QString, QWeakPointer<ProjectExplorer::RunControl> > m_activeRunControls; + mutable QMap<QString, QPointer<ProjectExplorer::RunControl> > m_activeRunControls; }; } // namespace Internal diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs index a23e9c1146..b5b093b903 100644 --- a/src/plugins/qnx/qnx.qbs +++ b/src/plugins/qnx/qnx.qbs @@ -15,12 +15,7 @@ QtcPlugin { Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] } cpp.defines: base.concat(["QT_NO_CAST_TO_ASCII", "QT_NO_CAST_FROM_ASCII"]) - cpp.includePaths: [ - "..", - buildDirectory, - "../../libs", - "../../shared" - ] + cpp.includePaths: base.concat("../../shared") files: [ "bardescriptorfileimagewizardpage.cpp", @@ -32,33 +27,33 @@ QtcPlugin { "blackberryapplicationrunner.h", "blackberryconnect.cpp", "blackberryconnect.h", + "blackberrycreatepackagestep.cpp", + "blackberrycreatepackagestep.h", "blackberrycreatepackagestepconfigwidget.cpp", "blackberrycreatepackagestepconfigwidget.h", - "blackberrycreatepackagestep.cpp", "blackberrycreatepackagestepfactory.cpp", "blackberrycreatepackagestepfactory.h", - "blackberrycreatepackagestep.h", "blackberrydebugsupport.cpp", "blackberrydebugsupport.h", "blackberrydeployconfiguration.cpp", + "blackberrydeployconfiguration.h", "blackberrydeployconfigurationfactory.cpp", "blackberrydeployconfigurationfactory.h", - "blackberrydeployconfiguration.h", "blackberrydeployconfigurationwidget.cpp", "blackberrydeployconfigurationwidget.h", "blackberrydeployconfigurationwidget.ui", "blackberrydeployinformation.cpp", "blackberrydeployinformation.h", + "blackberrydeploystep.cpp", + "blackberrydeploystep.h", "blackberrydeploystepconfigwidget.cpp", "blackberrydeploystepconfigwidget.h", - "blackberrydeploystep.cpp", "blackberrydeploystepfactory.cpp", "blackberrydeploystepfactory.h", - "blackberrydeploystep.h", "blackberrydeviceconfiguration.cpp", + "blackberrydeviceconfiguration.h", "blackberrydeviceconfigurationfactory.cpp", "blackberrydeviceconfigurationfactory.h", - "blackberrydeviceconfiguration.h", "blackberrydeviceconfigurationwidget.cpp", "blackberrydeviceconfigurationwidget.h", "blackberrydeviceconfigurationwidget.ui", @@ -69,26 +64,25 @@ QtcPlugin { "blackberrydeviceconfigurationwizardsetuppage.ui", "blackberrydeviceconfigurationwizardsshkeypage.ui", "blackberryqtversion.cpp", + "blackberryqtversion.h", "blackberryqtversionfactory.cpp", "blackberryqtversionfactory.h", - "blackberryqtversion.h", "blackberryrunconfiguration.cpp", + "blackberryrunconfiguration.h", "blackberryrunconfigurationfactory.cpp", "blackberryrunconfigurationfactory.h", - "blackberryrunconfiguration.h", "blackberryrunconfigurationwidget.cpp", "blackberryrunconfigurationwidget.h", "blackberryrunconfigurationwidget.ui", "blackberryruncontrol.cpp", + "blackberryruncontrol.h", "blackberryruncontrolfactory.cpp", "blackberryruncontrolfactory.h", - "blackberryruncontrol.h", "blackberrywizardextension.cpp", "blackberrywizardextension.h", - "images/target.png", - "images/target-small.png", "pathchooserdelegate.cpp", "pathchooserdelegate.h", + "qnx.qrc", "qnxabstractqtversion.cpp", "qnxabstractqtversion.h", "qnxbaseqtconfigwidget.cpp", @@ -98,35 +92,36 @@ QtcPlugin { "qnxdebugsupport.cpp", "qnxdebugsupport.h", "qnxdeployconfiguration.cpp", + "qnxdeployconfiguration.h", "qnxdeployconfigurationfactory.cpp", "qnxdeployconfigurationfactory.h", - "qnxdeployconfiguration.h", "qnxdeploystepfactory.cpp", "qnxdeploystepfactory.h", "qnxdeviceconfiguration.cpp", + "qnxdeviceconfiguration.h", "qnxdeviceconfigurationfactory.cpp", "qnxdeviceconfigurationfactory.h", - "qnxdeviceconfiguration.h", "qnxdeviceconfigurationwizard.cpp", "qnxdeviceconfigurationwizard.h", "qnxdeviceconfigurationwizardpages.cpp", "qnxdeviceconfigurationwizardpages.h", "qnxplugin.cpp", "qnxplugin.h", - "qnx.qrc", "qnxqtversion.cpp", + "qnxqtversion.h", "qnxqtversionfactory.cpp", "qnxqtversionfactory.h", - "qnxqtversion.h", "qnxrunconfiguration.cpp", + "qnxrunconfiguration.h", "qnxrunconfigurationfactory.cpp", "qnxrunconfigurationfactory.h", - "qnxrunconfiguration.h", "qnxruncontrol.cpp", + "qnxruncontrol.h", "qnxruncontrolfactory.cpp", "qnxruncontrolfactory.h", - "qnxruncontrol.h", "qnxutils.cpp", - "qnxutils.h" + "qnxutils.h", + "images/target-small.png", + "images/target.png", ] } diff --git a/src/plugins/qnx/qnxabstractqtversion.cpp b/src/plugins/qnx/qnxabstractqtversion.cpp index 7bfdb9b109..f45adcbb5c 100644 --- a/src/plugins/qnx/qnxabstractqtversion.cpp +++ b/src/plugins/qnx/qnxabstractqtversion.cpp @@ -34,6 +34,7 @@ #include "qnxbaseqtconfigwidget.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <QDir> @@ -180,13 +181,10 @@ void QnxAbstractQtVersion::setDefaultSdkPath() return; QString envFile; -#if defined Q_OS_WIN - envFile = qtHostPrefix + QLatin1String("/bbndk-env.bat"); -#elif defined Q_OS_UNIX - envFile = qtHostPrefix + QLatin1String("/bbndk-env.sh"); -#endif - + if (Utils::HostOsInfo::isWindowsHost()) + envFile = qtHostPrefix + QLatin1String("/bbndk-env.bat"); + else if (Utils::HostOsInfo::isAnyUnixHost()) + envFile = qtHostPrefix + QLatin1String("/bbndk-env.sh"); if (QFileInfo(envFile).exists()) setSdkPath(qtHostPrefix); - } diff --git a/src/plugins/qnx/qnxdeployconfiguration.cpp b/src/plugins/qnx/qnxdeployconfiguration.cpp index 1058455014..88265ec345 100644 --- a/src/plugins/qnx/qnxdeployconfiguration.cpp +++ b/src/plugins/qnx/qnxdeployconfiguration.cpp @@ -42,4 +42,5 @@ QnxDeployConfiguration::QnxDeployConfiguration(ProjectExplorer::Target *target, QnxDeployConfiguration::QnxDeployConfiguration(ProjectExplorer::Target *target, QnxDeployConfiguration *source) : RemoteLinux::RemoteLinuxDeployConfiguration(target, source) { + cloneSteps(source); } diff --git a/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp b/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp index f1c8281773..725bdac76a 100644 --- a/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp +++ b/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp @@ -61,7 +61,7 @@ QnxDeviceConfigurationWizard::QnxDeviceConfigurationWizard(QWidget *parent) : IDevice::Ptr QnxDeviceConfigurationWizard::device() { QSsh::SshConnectionParameters sshParams; - sshParams.proxyType = QSsh::SshConnectionParameters::NoProxy; + sshParams.options = QSsh::SshIgnoreDefaultProxy; sshParams.host = m_setupPage->hostName(); sshParams.userName = m_setupPage->userName(); sshParams.port = 22; diff --git a/src/plugins/qnx/qnxqtversion.cpp b/src/plugins/qnx/qnxqtversion.cpp index 795ecfeda7..fc008451f9 100644 --- a/src/plugins/qnx/qnxqtversion.cpp +++ b/src/plugins/qnx/qnxqtversion.cpp @@ -33,6 +33,8 @@ #include "qnxconstants.h" +#include <utils/hostosinfo.h> + using namespace Qnx; using namespace Qnx::Internal; @@ -94,26 +96,26 @@ QMultiMap<QString, QString> QnxQtVersion::environment() const QMultiMap<QString, QString> environment; -#if defined Q_OS_WIN - // TODO: - //environment.insert(QLatin1String("QNX_CONFIGURATION"), QLatin1String("/etc/qnx")); - environment.insert(QLatin1String(Constants::QNX_TARGET_KEY), sdkPath() + QLatin1String("/target/qnx6")); - environment.insert(QLatin1String(Constants::QNX_HOST_KEY), sdkPath() + QLatin1String("/host/win32/x86")); + if (Utils::HostOsInfo::isWindowsHost()) { + // TODO: + //environment.insert(QLatin1String("QNX_CONFIGURATION"), QLatin1String("/etc/qnx")); + environment.insert(QLatin1String(Constants::QNX_TARGET_KEY), sdkPath() + QLatin1String("/target/qnx6")); + environment.insert(QLatin1String(Constants::QNX_HOST_KEY), sdkPath() + QLatin1String("/host/win32/x86")); - environment.insert(QLatin1String("PATH"), sdkPath() + QLatin1String("/host/win32/x86/usr/bin")); + environment.insert(QLatin1String("PATH"), sdkPath() + QLatin1String("/host/win32/x86/usr/bin")); - // TODO: - //environment.insert(QLatin1String("PATH"), QLatin1String("/etc/qnx/bin")); -#elif defined Q_OS_UNIX - environment.insert(QLatin1String("QNX_CONFIGURATION"), QLatin1String("/etc/qnx")); - environment.insert(QLatin1String(Constants::QNX_TARGET_KEY), sdkPath() + QLatin1String("/target/qnx6")); - environment.insert(QLatin1String(Constants::QNX_HOST_KEY), sdkPath() + QLatin1String("/host/linux/x86")); + // TODO: + //environment.insert(QLatin1String("PATH"), QLatin1String("/etc/qnx/bin")); + } else if (Utils::HostOsInfo::isAnyUnixHost()) { + environment.insert(QLatin1String("QNX_CONFIGURATION"), QLatin1String("/etc/qnx")); + environment.insert(QLatin1String(Constants::QNX_TARGET_KEY), sdkPath() + QLatin1String("/target/qnx6")); + environment.insert(QLatin1String(Constants::QNX_HOST_KEY), sdkPath() + QLatin1String("/host/linux/x86")); - environment.insert(QLatin1String("PATH"), sdkPath() + QLatin1String("/host/linux/x86/usr/bin")); - environment.insert(QLatin1String("PATH"), QLatin1String("/etc/qnx/bin")); + environment.insert(QLatin1String("PATH"), sdkPath() + QLatin1String("/host/linux/x86/usr/bin")); + environment.insert(QLatin1String("PATH"), QLatin1String("/etc/qnx/bin")); - environment.insert(QLatin1String("LD_LIBRARY_PATH"), sdkPath() + QLatin1String("/host/linux/x86/usr/lib")); -#endif + environment.insert(QLatin1String("LD_LIBRARY_PATH"), sdkPath() + QLatin1String("/host/linux/x86/usr/lib")); + } environment.insert(QLatin1String("QNX_JAVAHOME"), sdkPath() + QLatin1String("/_jvm")); environment.insert(QLatin1String("MAKEFLAGS"), QLatin1String("-I") + sdkPath() + QLatin1String("/target/qnx6/usr/include")); diff --git a/src/plugins/qnx/qnxrunconfiguration.h b/src/plugins/qnx/qnxrunconfiguration.h index 29a51bdcae..93704398a0 100644 --- a/src/plugins/qnx/qnxrunconfiguration.h +++ b/src/plugins/qnx/qnxrunconfiguration.h @@ -41,7 +41,8 @@ class QnxRunConfiguration : public RemoteLinux::RemoteLinuxRunConfiguration { Q_OBJECT public: - QnxRunConfiguration(ProjectExplorer::Target *parent, const Core::Id id, const QString &proFilePath); + QnxRunConfiguration(ProjectExplorer::Target *parent, const Core::Id id, + const QString &projectFilePath); QString environmentPreparationCommand() const; diff --git a/src/plugins/qt4projectmanager/addlibrarywizard.cpp b/src/plugins/qt4projectmanager/addlibrarywizard.cpp index 2ce0d1241b..4d8ec4c729 100644 --- a/src/plugins/qt4projectmanager/addlibrarywizard.cpp +++ b/src/plugins/qt4projectmanager/addlibrarywizard.cpp @@ -31,6 +31,8 @@ #include "ui_librarydetailswidget.h" #include "librarydetailscontroller.h" +#include <utils/hostosinfo.h> + #include <QVBoxLayout> #include <QRadioButton> #include <QLabel> @@ -175,10 +177,10 @@ LibraryTypePage::LibraryTypePage(AddLibraryWizard *parent) packageLabel->setAttribute(Qt::WA_MacSmallSize, true); layout->addWidget(packageLabel); -#ifdef Q_OS_WIN - m_packageRadio->setVisible(false); - packageLabel->setVisible(false); -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + m_packageRadio->setVisible(false); + packageLabel->setVisible(false); + } // select the default m_internalRadio->setChecked(true); diff --git a/src/plugins/qt4projectmanager/librarydetailscontroller.cpp b/src/plugins/qt4projectmanager/librarydetailscontroller.cpp index b1f7ce4852..d8f964320b 100644 --- a/src/plugins/qt4projectmanager/librarydetailscontroller.cpp +++ b/src/plugins/qt4projectmanager/librarydetailscontroller.cpp @@ -40,6 +40,7 @@ #include <projectexplorer/target.h> #include <projectexplorer/toolchain.h> #include <projectexplorer/buildconfiguration.h> +#include <utils/hostosinfo.h> #include <QFileInfo> #include <QDir> @@ -66,27 +67,31 @@ LibraryDetailsController::LibraryDetailsController( m_windowsGroupVisible(true), m_libraryDetailsWidget(libraryDetails) { -#ifdef Q_OS_MAC - m_creatorPlatform = CreatorMac; -#endif -#ifdef Q_OS_LINUX - m_creatorPlatform = CreatorLinux; -#endif -#ifdef Q_OS_WIN - m_creatorPlatform = CreatorWindows; -#endif - -#ifndef Q_OS_LINUX - // project for which we are going to insert the snippet - const ProjectExplorer::Project *project = - ProjectExplorer::ProjectExplorerPlugin::instance()->session()->projectForFile(proFile); - // if its tool chain is maemo behave the same as we would be on linux - ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(project->activeTarget()->kit()); - if (tc - && (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::HarmattanLinuxFlavor - || tc->targetAbi().osFlavor() == ProjectExplorer::Abi::MaemoLinuxFlavor)) + switch (Utils::HostOsInfo::hostOs()) { + case Utils::HostOsInfo::HostOsMac: + m_creatorPlatform = CreatorMac; + break; + case Utils::HostOsInfo::HostOsLinux: m_creatorPlatform = CreatorLinux; -#endif + break; + case Utils::HostOsInfo::HostOsWindows: + m_creatorPlatform = CreatorWindows; + break; + default: + break; + } + + if (!Utils::HostOsInfo::isLinuxHost()) { + // project for which we are going to insert the snippet + const ProjectExplorer::Project *project = + ProjectExplorer::ProjectExplorerPlugin::instance()->session()->projectForFile(proFile); + // if its tool chain is maemo behave the same as we would be on linux + ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(project->activeTarget()->kit()); + if (tc + && (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::HarmattanLinuxFlavor + || tc->targetAbi().osFlavor() == ProjectExplorer::Abi::MaemoLinuxFlavor)) + m_creatorPlatform = CreatorLinux; + } setPlatformsVisible(true); setLinkageGroupVisible(true); diff --git a/src/plugins/qt4projectmanager/makestep.cpp b/src/plugins/qt4projectmanager/makestep.cpp index b9aae765af..10fecb6372 100644 --- a/src/plugins/qt4projectmanager/makestep.cpp +++ b/src/plugins/qt4projectmanager/makestep.cpp @@ -38,6 +38,7 @@ #include <projectexplorer/target.h> #include <projectexplorer/toolchain.h> #include <projectexplorer/buildsteplist.h> +#include <projectexplorer/gnumakeparser.h> #include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/kitinformation.h> @@ -248,20 +249,11 @@ bool MakeStep::init() pp->setEnvironment(env); pp->setArguments(args); - IOutputParser *parser = 0; - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); - if (version) - parser = version->createOutputParser(); + setOutputParser(new ProjectExplorer::GnuMakeParser()); + IOutputParser *parser = target()->kit()->createOutputParser(); if (parser) - parser->appendOutputParser(new QtSupport::QtParser); - else - parser = new QtSupport::QtParser; - if (tc) - parser->appendOutputParser(tc->outputParser()); - - parser->setWorkingDirectory(workingDirectory); - - setOutputParser(parser); + appendOutputParser(parser); + outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory()); m_scriptTarget = (static_cast<Qt4Project *>(bc->target()->project())->rootQt4ProjectNode()->projectType() == ScriptTemplate); diff --git a/src/plugins/qt4projectmanager/profilecompletionassist.cpp b/src/plugins/qt4projectmanager/profilecompletionassist.cpp index 2478b5d00a..a0ae7dc887 100644 --- a/src/plugins/qt4projectmanager/profilecompletionassist.cpp +++ b/src/plugins/qt4projectmanager/profilecompletionassist.cpp @@ -29,73 +29,236 @@ #include "profilecompletionassist.h" #include "qt4projectmanagerconstants.h" -#include "profilekeywords.h" -#include <texteditor/codeassist/iassistinterface.h> -#include <texteditor/codeassist/genericproposal.h> -#include <texteditor/completionsettings.h> -#include <texteditor/texteditorsettings.h> -#include <texteditor/basetexteditor.h> - -#include <cplusplus/Icons.h> - -#include <QTextCursor> +#include <texteditor/codeassist/keywordscompletionassist.h> using namespace Qt4ProjectManager::Internal; using namespace TextEditor; -// ------------------------- -// ProFileAssistProposalItem -// ------------------------- -ProFileAssistProposalItem::ProFileAssistProposalItem() -{} -ProFileAssistProposalItem::~ProFileAssistProposalItem() -{} - -bool ProFileAssistProposalItem::prematurelyApplies(const QChar &c) const -{ - // only '(' in case of a function - if (c == QLatin1Char('(') && ProFileKeywords::isFunction(text())) - return true; - return false; -} - -void ProFileAssistProposalItem::applyContextualContent(TextEditor::BaseTextEditor *editor, - int basePosition) const -{ - const CompletionSettings &settings = TextEditorSettings::instance()->completionSettings(); - - int replaceLength = editor->position() - basePosition; - QString toInsert = text(); - int cursorOffset = 0; - if (ProFileKeywords::isFunction(toInsert) && settings.m_autoInsertBrackets) { - if (settings.m_spaceAfterFunctionName) { - if (editor->textAt(editor->position(), 2) == QLatin1String(" (")) { - cursorOffset = 2; - } else if (editor->characterAt(editor->position()) == QLatin1Char('(') - || editor->characterAt(editor->position()) == QLatin1Char(' ')) { - replaceLength += 1; - toInsert += QLatin1String(" ("); - } else { - toInsert += QLatin1String(" ()"); - cursorOffset = -1; - } - } else { - if (editor->characterAt(editor->position()) == QLatin1Char('(')) { - cursorOffset = 1; - } else { - toInsert += QLatin1String("()"); - cursorOffset = -1; - } - } - } - - editor->setCursorPosition(basePosition); - editor->replace(replaceLength, toInsert); - if (cursorOffset) - editor->setCursorPosition(editor->position() + cursorOffset); -} +static const char *const variableKeywords[] = { + "BACKUP_REGISTRATION_FILE_MAEMO", + "CCFLAG", + "CONFIG", + "DEFINES", + "DEF_FILE", + "DEPENDPATH", + "DEPLOYMENT", + "DEPLOYMENT_PLUGIN", + "DESTDIR", + "DESTDIR_TARGET", + "DISTFILES", + "DLLDESTDIR", + "DISTFILES", + "DSP_TEMPLATE", + "FORMS", + "FORMS3", + "GUID", + "HEADERS", + "ICON", + "INCLUDEPATH", + "INSTALLS", + "LEXIMPLS", + "LEXOBJECTS", + "LEXSOURCES", + "LIBS", + "LITERAL_HASH", + "MAKEFILE", + "MAKEFILE_GENERATOR", + "MOBILITY", + "MOC_DIR", + "OBJECTIVE_HEADERS", + "OBJECTIVE_SOURCES", + "OBJECTS", + "OBJECTS_DIR", + "OBJMOC", + "OTHER_FILES", + "PKGCONFIG", + "POST_TARGETDEPS", + "PRE_TARGETDEPS", + "PRECOMPILED_HEADER", + "PWD", + "OUT_PWD", + "QMAKE", + "QMAKESPEC", + "QMAKE_APP_FLAG", + "QMAKE_APP_OR_DLL", + "QMAKE_AR_CMD", + "QMAKE_BUNDLE_DATA", + "QMAKE_BUNDLE_EXTENSION", + "QMAKE_CC", + "QMAKE_CFLAGS_DEBUG", + "QMAKE_CFLAGS_MT", + "QMAKE_CFLAGS_MT_DBG", + "QMAKE_CFLAGS_MT_DLL", + "QMAKE_CFLAGS_MT_DLLDBG", + "QMAKE_CFLAGS_RELEASE", + "QMAKE_CFLAGS_SHLIB", + "QMAKE_CFLAGS_THREAD", + "QMAKE_CFLAGS_WARN_OFF", + "QMAKE_CFLAGS_WARN_ON", + "QMAKE_CLEAN", + "QMAKE_CXX", + "QMAKE_CXXFLAGS", + "QMAKE_CXXFLAGS_DEBUG", + "QMAKE_CXXFLAGS_MT", + "QMAKE_CXXFLAGS_MT_DBG", + "QMAKE_CXXFLAGS_MT_DLL", + "QMAKE_CXXFLAGS_MT_DLLDBG", + "QMAKE_CXXFLAGS_RELEASE", + "QMAKE_CXXFLAGS_SHLIB", + "QMAKE_CXXFLAGS_THREAD", + "QMAKE_CXXFLAGS_WARN_OFF", + "QMAKE_CXXFLAGS_WARN_ON", + "QMAKE_DISTCLEAN", + "QMAKE_EXTENSION_SHLIB", + "QMAKE_EXT_MOC", + "QMAKE_EXT_UI", + "QMAKE_EXT_PRL", + "QMAKE_EXT_LEX", + "QMAKE_EXT_YACC", + "QMAKE_EXT_OBJ", + "QMAKE_EXT_CPP", + "QMAKE_EXT_H", + "QMAKE_EXTRA_COMPILERS", + "QMAKE_EXTRA_TARGETS", + "QMAKE_FAILED_REQUIREMENTS", + "QMAKE_FRAMEWORK_BUNDLE_NAME", + "QMAKE_FRAMEWORK_VERSION", + "QMAKE_INCDIR", + "QMAKE_INCDIR_EGL", + "QMAKE_INCDIR_OPENGL", + "QMAKE_INCDIR_OPENGL_ES1", + "QMAKE_INCDIR_OPENGL_ES2", + "QMAKE_INCDIR_OPENVG", + "QMAKE_INCDIR_QT", + "QMAKE_INCDIR_THREAD", + "QMAKE_INCDIR_X11", + "QMAKE_INFO_PLIST", + "QMAKE_LFLAGS", + "QMAKE_LFLAGS_CONSOLE", + "QMAKE_LFLAGS_CONSOLE_DLL", + "QMAKE_LFLAGS_DEBUG", + "QMAKE_LFLAGS_PLUGIN", + "QMAKE_LFLAGS_RPATH", + "QMAKE_LFLAGS_QT_DLL", + "QMAKE_LFLAGS_RELEASE", + "QMAKE_LFLAGS_SHAPP", + "QMAKE_LFLAGS_SHLIB", + "QMAKE_LFLAGS_SONAME", + "QMAKE_LFLAGS_THREAD", + "QMAKE_LFLAGS_WINDOWS", + "QMAKE_LFLAGS_WINDOWS_DLL", + "QMAKE_LIBDIR", + "QMAKE_LIBDIR_FLAGS", + "QMAKE_LIBDIR_EGL", + "QMAKE_LIBDIR_OPENGL", + "QMAKE_LIBDIR_OPENVG", + "QMAKE_LIBDIR_QT", + "QMAKE_LIBDIR_X11", + "QMAKE_LIBS", + "QMAKE_LIBS_CONSOLE", + "QMAKE_LIBS_EGL", + "QMAKE_LIBS_OPENGL", + "QMAKE_LIBS_OPENGL_QT", + "QMAKE_LIBS_OPENGL_ES1", + "QMAKE_LIBS_OPENGL_ES2", + "QMAKE_LIBS_OPENVG", + "QMAKE_LIBS_QT", + "QMAKE_LIBS_QT_DLL", + "QMAKE_LIBS_QT_OPENGL", + "QMAKE_LIBS_QT_THREAD", + "QMAKE_LIBS_RT", + "QMAKE_LIBS_RTMT", + "QMAKE_LIBS_THREAD", + "QMAKE_LIBS_WINDOWS", + "QMAKE_LIBS_X11", + "QMAKE_LIBS_X11SM", + "QMAKE_LIB_FLAG", + "QMAKE_LINK_SHLIB_CMD", + "QMAKE_LN_SHLIB", + "QMAKE_POST_LINK", + "QMAKE_PRE_LINK", + "QMAKE_PROJECT_NAME", + "QMAKE_MAC_SDK", + "QMAKE_MACOSX_DEPLOYMENT_TARGET", + "QMAKE_MAKEFILE", + "QMAKE_MOC_SRC", + "QMAKE_QMAKE", + "QMAKE_QT_DLL", + "QMAKE_RESOURCE_FLAGS", + "QMAKE_RPATH", + "QMAKE_RPATHDIR", + "QMAKE_RUN_CC", + "QMAKE_RUN_CC_IMP", + "QMAKE_RUN_CXX", + "QMAKE_RUN_CXX_IMP", + "QMAKE_TARGET", + "QMAKE_UIC", + "QT", + "QTPLUGIN", + "QT_VERSION", + "QT_MAJOR_VERSION", + "QT_MINOR_VERSION", + "QT_PATCH_VERSION", + "RCC_DIR", + "RC_FILE", + "REQUIRES", + "RESOURCES", + "RES_FILE", + "RSS_RULES", + "SIGNATURE_FILE", + "SOURCES", + "SRCMOC", + "STATECHARTS", + "SUBDIRS", + "TARGET", + "TEMPLATE", + "TRANSLATIONS", + "UICIMPLS", + "UICOBJECTS", + "UI_DIR", + "UI_HEADERS_DIR", + "UI_SOURCES_DIR", + "VER_MAJ", + "VER_MIN", + "VER_PAT", + "VERSION", + "VPATH", + "YACCIMPLS", + "YACCOBJECTS", + "YACCSOURCES", + "_PRO_FILE_", + "_PRO_FILE_PWD_", + 0 +}; + +static const char *const functionKeywords[] = { + "basename", + "contains", + "count", + "dirname", + "error", + "eval", + "exists", + "find", + "for", + "include", + "infile", + "isEmpty", + "join", + "member", + "message", + "packagesExist", + "prompt", + "quote", + "replace", + "sprintf", + "system", + "unique", + "warning", + 0 +}; // ------------------------------- // ProFileCompletionAssistProvider @@ -103,127 +266,41 @@ void ProFileAssistProposalItem::applyContextualContent(TextEditor::BaseTextEdito ProFileCompletionAssistProvider::ProFileCompletionAssistProvider() {} -ProFileCompletionAssistProvider::~ProFileCompletionAssistProvider() -{} - -bool ProFileCompletionAssistProvider::supportsEditor(const Core::Id &editorId) const -{ - return editorId == Qt4ProjectManager::Constants::PROFILE_EDITOR_ID; -} - -bool ProFileCompletionAssistProvider::isAsynchronous() const -{ - return false; -} - -int ProFileCompletionAssistProvider::activationCharSequenceLength() const +void ProFileCompletionAssistProvider::init() { - return 0; + for (uint i = 0; i < sizeof variableKeywords / sizeof variableKeywords[0] - 1; i++) + m_variables.append(QLatin1String(variableKeywords[i])); + for (uint i = 0; i < sizeof functionKeywords / sizeof functionKeywords[0] - 1; i++) + m_functions.append(QLatin1String(functionKeywords[i])); } -bool ProFileCompletionAssistProvider::isActivationCharSequence(const QString &sequence) const +ProFileCompletionAssistProvider::~ProFileCompletionAssistProvider() { - Q_UNUSED(sequence); - return false; } -bool ProFileCompletionAssistProvider::isContinuationChar(const QChar &c) const +bool ProFileCompletionAssistProvider::supportsEditor(const Core::Id &editorId) const { - return c.isLetterOrNumber() || c == QLatin1Char('_'); + return editorId == Qt4ProjectManager::Constants::PROFILE_EDITOR_ID; } IAssistProcessor *ProFileCompletionAssistProvider::createProcessor() const { - return new ProFileCompletionAssistProcessor; -} - -// -------------------------------- -// ProFileCompletionAssistProcessor -// -------------------------------- -ProFileCompletionAssistProcessor::ProFileCompletionAssistProcessor() - : m_startPosition(-1) - , m_variableIcon(CPlusPlus::Icons().iconForType(CPlusPlus::Icons::VarPublicIconType)) - , m_functionIcon(CPlusPlus::Icons().iconForType(CPlusPlus::Icons::FuncPublicIconType)) -{} - -ProFileCompletionAssistProcessor::~ProFileCompletionAssistProcessor() -{} - -IAssistProposal *ProFileCompletionAssistProcessor::perform(const IAssistInterface *interface) -{ - m_interface.reset(interface); - - if (isInComment()) - return 0; - - if (interface->reason() == IdleEditor && !acceptsIdleEditor()) - return 0; - - if (m_startPosition == -1) - m_startPosition = findStartOfName(); - - QList<TextEditor::BasicProposalItem *> items; - QStringList keywords = ProFileKeywords::variables() + ProFileKeywords::functions(); - for (int i = 0; i < keywords.count(); i++) { - BasicProposalItem *item = new ProFileAssistProposalItem; - item->setText(keywords[i]); - item->setIcon(ProFileKeywords::isFunction(item->text()) ? m_functionIcon : m_variableIcon); - items.append(item); - } - - return new GenericProposal(m_startPosition, new ProFileAssistProposalModel(items)); + if (m_variables.isEmpty()) + const_cast<ProFileCompletionAssistProvider *>(this)->init(); + TextEditor::Keywords keywords = TextEditor::Keywords(m_variables, m_functions, QMap<QString, QStringList>()); + return new KeywordsCompletionAssistProcessor(keywords); } -bool ProFileCompletionAssistProcessor::acceptsIdleEditor() +QStringList ProFileCompletionAssistProvider::variables() const { - const int pos = m_interface->position(); - QChar characterUnderCursor = m_interface->characterAt(pos); - if (!characterUnderCursor.isLetterOrNumber()) { - m_startPosition = findStartOfName(); - if (pos - m_startPosition >= 3 && !isInComment()) - return true; - } - return false; + if (m_variables.isEmpty()) + const_cast<ProFileCompletionAssistProvider *>(this)->init(); + return m_variables; } -int ProFileCompletionAssistProcessor::findStartOfName(int pos) const -{ - if (pos == -1) - pos = m_interface->position(); - QChar chr; - - // Skip to the start of a name - do { - chr = m_interface->characterAt(--pos); - } while (chr.isLetterOrNumber() || chr == QLatin1Char('_')); - - return pos + 1; -} - -bool ProFileCompletionAssistProcessor::isInComment() const -{ - QTextCursor tc(m_interface->textDocument()); - tc.setPosition(m_interface->position()); - tc.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); - const QString &lineBeginning = tc.selectedText(); - if (lineBeginning.contains(QLatin1Char('#'))) - return true; - return false; -} - -// -------------------------- -// ProFileAssistProposalModel -// -------------------------- -ProFileAssistProposalModel::ProFileAssistProposalModel( - const QList<BasicProposalItem *> &items) - : BasicProposalItemListModel(items) -{} - -ProFileAssistProposalModel::~ProFileAssistProposalModel() -{} - -bool ProFileAssistProposalModel::isSortable(const QString &prefix) const +QStringList ProFileCompletionAssistProvider::functions() const { - Q_UNUSED(prefix) - return false; + if (m_functions.isEmpty()) + const_cast<ProFileCompletionAssistProvider *>(this)->init(); + return m_functions; } diff --git a/src/plugins/qt4projectmanager/profilecompletionassist.h b/src/plugins/qt4projectmanager/profilecompletionassist.h index 7b0906333f..e0012fe668 100644 --- a/src/plugins/qt4projectmanager/profilecompletionassist.h +++ b/src/plugins/qt4projectmanager/profilecompletionassist.h @@ -30,71 +30,28 @@ #ifndef PROFILECOMPLETIONASSIST_H #define PROFILECOMPLETIONASSIST_H -#include <texteditor/codeassist/basicproposalitem.h> -#include <texteditor/codeassist/basicproposalitemlistmodel.h> #include <texteditor/codeassist/completionassistprovider.h> -#include <texteditor/codeassist/iassistprocessor.h> -#include <QIcon> +#include <QStringList> namespace Qt4ProjectManager { namespace Internal { -class ProFileAssistProposalItem : public TextEditor::BasicProposalItem -{ -public: - ProFileAssistProposalItem(); - virtual ~ProFileAssistProposalItem(); - - virtual bool prematurelyApplies(const QChar &c) const; - virtual void applyContextualContent(TextEditor::BaseTextEditor *editor, - int basePosition) const; -}; - - class ProFileCompletionAssistProvider : public TextEditor::CompletionAssistProvider { + Q_OBJECT public: ProFileCompletionAssistProvider(); + void init(); virtual ~ProFileCompletionAssistProvider(); virtual bool supportsEditor(const Core::Id &editorId) const; virtual TextEditor::IAssistProcessor *createProcessor() const; - - virtual bool isAsynchronous() const; - virtual int activationCharSequenceLength() const; - virtual bool isActivationCharSequence(const QString &sequence) const; - virtual bool isContinuationChar(const QChar &c) const; -}; - - -class ProFileCompletionAssistProcessor : public TextEditor::IAssistProcessor -{ -public: - ProFileCompletionAssistProcessor(); - virtual ~ProFileCompletionAssistProcessor(); - - virtual TextEditor::IAssistProposal *perform(const TextEditor::IAssistInterface *interface); - + QStringList variables() const; + QStringList functions() const; private: - bool acceptsIdleEditor(); - int findStartOfName(int pos = -1) const; - bool isInComment() const; - - int m_startPosition; - QScopedPointer<const TextEditor::IAssistInterface> m_interface; - const QIcon m_variableIcon; - const QIcon m_functionIcon; -}; - - -class ProFileAssistProposalModel : public TextEditor::BasicProposalItemListModel -{ -public: - ProFileAssistProposalModel(const QList<TextEditor::BasicProposalItem *> &items); - virtual ~ProFileAssistProposalModel(); - - virtual bool isSortable(const QString &prefix) const; + QStringList m_variables; + QStringList m_functions; }; } // Internal diff --git a/src/plugins/qt4projectmanager/profileeditor.cpp b/src/plugins/qt4projectmanager/profileeditor.cpp index 1011805660..7fc68af0a7 100644 --- a/src/plugins/qt4projectmanager/profileeditor.cpp +++ b/src/plugins/qt4projectmanager/profileeditor.cpp @@ -73,7 +73,7 @@ Core::IEditor *ProFileEditor::duplicate(QWidget *parent) Core::Id ProFileEditor::id() const { - return Qt4ProjectManager::Constants::PROFILE_EDITOR_ID; + return Core::Id(Qt4ProjectManager::Constants::PROFILE_EDITOR_ID); } // diff --git a/src/plugins/qt4projectmanager/profileeditorfactory.cpp b/src/plugins/qt4projectmanager/profileeditorfactory.cpp index 406a5767aa..9a140abc76 100644 --- a/src/plugins/qt4projectmanager/profileeditorfactory.cpp +++ b/src/plugins/qt4projectmanager/profileeditorfactory.cpp @@ -68,7 +68,7 @@ ProFileEditorFactory::~ProFileEditorFactory() Core::Id ProFileEditorFactory::id() const { - return Qt4ProjectManager::Constants::PROFILE_EDITOR_ID; + return Core::Id(Qt4ProjectManager::Constants::PROFILE_EDITOR_ID); } QString ProFileEditorFactory::displayName() const diff --git a/src/plugins/qt4projectmanager/profilehighlighter.cpp b/src/plugins/qt4projectmanager/profilehighlighter.cpp index 487dffefb6..ddd480c378 100644 --- a/src/plugins/qt4projectmanager/profilehighlighter.cpp +++ b/src/plugins/qt4projectmanager/profilehighlighter.cpp @@ -28,7 +28,9 @@ ****************************************************************************/ #include "profilehighlighter.h" -#include "profilekeywords.h" +#include "profilecompletionassist.h" + +#include <extensionsystem/pluginmanager.h> #include <QRegExp> #include <QColor> @@ -41,6 +43,9 @@ using namespace Qt4ProjectManager::Internal; ProFileHighlighter::ProFileHighlighter(QTextDocument *document) : TextEditor::SyntaxHighlighter(document) { + ProFileCompletionAssistProvider *pcap + = ExtensionSystem::PluginManager::instance()->getObject<ProFileCompletionAssistProvider>(); + m_keywords = TextEditor::Keywords(pcap->variables(), pcap->functions(), QMap<QString, QStringList>()); } void ProFileHighlighter::highlightBlock(const QString &text) @@ -61,12 +66,12 @@ void ProFileHighlighter::highlightBlock(const QString &text) if (c.isLetter() || c == QLatin1Char('_') || c == QLatin1Char('.') || c.isDigit()) { buf += c; setFormat(i - buf.length()+1, buf.length(), emptyFormat); - if (!buf.isEmpty() && ProFileKeywords::isFunction(buf)) + if (!buf.isEmpty() && m_keywords.isFunction(buf)) setFormat(i - buf.length()+1, buf.length(), m_formats[ProfileFunctionFormat]); - else if (!buf.isEmpty() && ProFileKeywords::isVariable(buf)) + else if (!buf.isEmpty() && m_keywords.isVariable(buf)) setFormat(i - buf.length()+1, buf.length(), m_formats[ProfileVariableFormat]); } else if (c == QLatin1Char('(')) { - if (!buf.isEmpty() && ProFileKeywords::isFunction(buf)) + if (!buf.isEmpty() && m_keywords.isFunction(buf)) setFormat(i - buf.length(), buf.length(), m_formats[ProfileFunctionFormat]); buf.clear(); } else if (c == QLatin1Char('#')) { @@ -74,7 +79,7 @@ void ProFileHighlighter::highlightBlock(const QString &text) setFormat(i, 1, m_formats[ProfileCommentFormat]); buf.clear(); } else { - if (!buf.isEmpty() && ProFileKeywords::isVariable(buf)) + if (!buf.isEmpty() && m_keywords.isVariable(buf)) setFormat(i - buf.length(), buf.length(), m_formats[ProfileVariableFormat]); buf.clear(); } diff --git a/src/plugins/qt4projectmanager/profilehighlighter.h b/src/plugins/qt4projectmanager/profilehighlighter.h index 70147f6f6b..f135d498bf 100644 --- a/src/plugins/qt4projectmanager/profilehighlighter.h +++ b/src/plugins/qt4projectmanager/profilehighlighter.h @@ -31,6 +31,7 @@ #define PROFILEHIGHLIGHTER_H #include <texteditor/syntaxhighlighter.h> +#include <texteditor/codeassist/keywordscompletionassist.h> #include <QtAlgorithms> #include <QSyntaxHighlighter> #include <QTextCharFormat> @@ -61,6 +62,8 @@ public: private: QTextCharFormat m_formats[NumProfileFormats]; + TextEditor::Keywords m_keywords; + }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/profilehoverhandler.cpp b/src/plugins/qt4projectmanager/profilehoverhandler.cpp index 3249d88c14..7e4ca30f3e 100644 --- a/src/plugins/qt4projectmanager/profilehoverhandler.cpp +++ b/src/plugins/qt4projectmanager/profilehoverhandler.cpp @@ -29,7 +29,7 @@ #include "profilehoverhandler.h" #include "profileeditor.h" -#include "profilekeywords.h" +#include "profilecompletionassist.h" #include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/editormanager.h> @@ -53,6 +53,9 @@ ProFileHoverHandler::ProFileHoverHandler(QObject *parent) : BaseHoverHandler(parent), m_manualKind(UnknownManual) { + ProFileCompletionAssistProvider *pcap + = ExtensionSystem::PluginManager::instance()->getObject<ProFileCompletionAssistProvider>(); + m_keywords = TextEditor::Keywords(pcap->variables(), pcap->functions(), QMap<QString, QStringList>()); } ProFileHoverHandler::~ProFileHoverHandler() @@ -111,9 +114,9 @@ void ProFileHoverHandler::identifyQMakeKeyword(const QString &text, int pos) if (checkBuffer) { if (!buf.isEmpty()) { if ((i >= pos) && (i - buf.size() <= pos)) { - if (ProFileKeywords::isFunction(buf)) + if (m_keywords.isFunction(buf)) identifyDocFragment(FunctionManual, buf); - else if (ProFileKeywords::isVariable(buf)) + else if (m_keywords.isVariable(buf)) identifyDocFragment(VariableManual, buf); break; } diff --git a/src/plugins/qt4projectmanager/profilehoverhandler.h b/src/plugins/qt4projectmanager/profilehoverhandler.h index 7a881e694b..086c7db43f 100644 --- a/src/plugins/qt4projectmanager/profilehoverhandler.h +++ b/src/plugins/qt4projectmanager/profilehoverhandler.h @@ -31,6 +31,7 @@ #define PROFILEHOVERHANDLER_H #include <texteditor/basehoverhandler.h> +#include <texteditor/codeassist/keywordscompletionassist.h> #include <QObject> @@ -76,6 +77,7 @@ private: QString m_docFragment; ManualKind m_manualKind; + TextEditor::Keywords m_keywords; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/profilekeywords.cpp b/src/plugins/qt4projectmanager/profilekeywords.cpp deleted file mode 100644 index fce55584a3..0000000000 --- a/src/plugins/qt4projectmanager/profilekeywords.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "profilekeywords.h" - -using namespace Qt4ProjectManager::Internal; - -static const char *const variableKeywords[] = { - "BACKUP_REGISTRATION_FILE_MAEMO", - "CCFLAG", - "CONFIG", - "DEFINES", - "DEF_FILE", - "DEPENDPATH", - "DEPLOYMENT", - "DEPLOYMENT_PLUGIN", - "DESTDIR", - "DESTDIR_TARGET", - "DISTFILES", - "DLLDESTDIR", - "DISTFILES", - "DSP_TEMPLATE", - "FORMS", - "FORMS3", - "GUID", - "HEADERS", - "ICON", - "INCLUDEPATH", - "INSTALLS", - "LEXIMPLS", - "LEXOBJECTS", - "LEXSOURCES", - "LIBS", - "LITERAL_HASH", - "MAKEFILE", - "MAKEFILE_GENERATOR", - "MOBILITY", - "MOC_DIR", - "OBJECTIVE_HEADERS", - "OBJECTIVE_SOURCES", - "OBJECTS", - "OBJECTS_DIR", - "OBJMOC", - "OTHER_FILES", - "PKGCONFIG", - "POST_TARGETDEPS", - "PRE_TARGETDEPS", - "PRECOMPILED_HEADER", - "PWD", - "OUT_PWD", - "QMAKE", - "QMAKESPEC", - "QMAKE_APP_FLAG", - "QMAKE_APP_OR_DLL", - "QMAKE_AR_CMD", - "QMAKE_BUNDLE_DATA", - "QMAKE_BUNDLE_EXTENSION", - "QMAKE_CC", - "QMAKE_CFLAGS_DEBUG", - "QMAKE_CFLAGS_MT", - "QMAKE_CFLAGS_MT_DBG", - "QMAKE_CFLAGS_MT_DLL", - "QMAKE_CFLAGS_MT_DLLDBG", - "QMAKE_CFLAGS_RELEASE", - "QMAKE_CFLAGS_SHLIB", - "QMAKE_CFLAGS_THREAD", - "QMAKE_CFLAGS_WARN_OFF", - "QMAKE_CFLAGS_WARN_ON", - "QMAKE_CLEAN", - "QMAKE_CXX", - "QMAKE_CXXFLAGS", - "QMAKE_CXXFLAGS_DEBUG", - "QMAKE_CXXFLAGS_MT", - "QMAKE_CXXFLAGS_MT_DBG", - "QMAKE_CXXFLAGS_MT_DLL", - "QMAKE_CXXFLAGS_MT_DLLDBG", - "QMAKE_CXXFLAGS_RELEASE", - "QMAKE_CXXFLAGS_SHLIB", - "QMAKE_CXXFLAGS_THREAD", - "QMAKE_CXXFLAGS_WARN_OFF", - "QMAKE_CXXFLAGS_WARN_ON", - "QMAKE_DISTCLEAN", - "QMAKE_EXTENSION_SHLIB", - "QMAKE_EXT_MOC", - "QMAKE_EXT_UI", - "QMAKE_EXT_PRL", - "QMAKE_EXT_LEX", - "QMAKE_EXT_YACC", - "QMAKE_EXT_OBJ", - "QMAKE_EXT_CPP", - "QMAKE_EXT_H", - "QMAKE_EXTRA_COMPILERS", - "QMAKE_EXTRA_TARGETS", - "QMAKE_FAILED_REQUIREMENTS", - "QMAKE_FILETAGS", - "QMAKE_FRAMEWORK_BUNDLE_NAME", - "QMAKE_FRAMEWORK_VERSION", - "QMAKE_INCDIR", - "QMAKE_INCDIR_EGL", - "QMAKE_INCDIR_OPENGL", - "QMAKE_INCDIR_OPENGL_ES1", - "QMAKE_INCDIR_OPENGL_ES2", - "QMAKE_INCDIR_OPENVG", - "QMAKE_INCDIR_QT", - "QMAKE_INCDIR_THREAD", - "QMAKE_INCDIR_X11", - "QMAKE_INFO_PLIST", - "QMAKE_LFLAGS", - "QMAKE_LFLAGS_CONSOLE", - "QMAKE_LFLAGS_CONSOLE_DLL", - "QMAKE_LFLAGS_DEBUG", - "QMAKE_LFLAGS_PLUGIN", - "QMAKE_LFLAGS_RPATH", - "QMAKE_LFLAGS_QT_DLL", - "QMAKE_LFLAGS_RELEASE", - "QMAKE_LFLAGS_SHAPP", - "QMAKE_LFLAGS_SHLIB", - "QMAKE_LFLAGS_SONAME", - "QMAKE_LFLAGS_THREAD", - "QMAKE_LFLAGS_WINDOWS", - "QMAKE_LFLAGS_WINDOWS_DLL", - "QMAKE_LIBDIR", - "QMAKE_LIBDIR_FLAGS", - "QMAKE_LIBDIR_EGL", - "QMAKE_LIBDIR_OPENGL", - "QMAKE_LIBDIR_OPENVG", - "QMAKE_LIBDIR_QT", - "QMAKE_LIBDIR_X11", - "QMAKE_LIBS", - "QMAKE_LIBS_CONSOLE", - "QMAKE_LIBS_EGL", - "QMAKE_LIBS_OPENGL", - "QMAKE_LIBS_OPENGL_QT", - "QMAKE_LIBS_OPENGL_ES1", - "QMAKE_LIBS_OPENGL_ES2", - "QMAKE_LIBS_OPENVG", - "QMAKE_LIBS_QT", - "QMAKE_LIBS_QT_DLL", - "QMAKE_LIBS_QT_OPENGL", - "QMAKE_LIBS_QT_THREAD", - "QMAKE_LIBS_RT", - "QMAKE_LIBS_RTMT", - "QMAKE_LIBS_THREAD", - "QMAKE_LIBS_WINDOWS", - "QMAKE_LIBS_X11", - "QMAKE_LIBS_X11SM", - "QMAKE_LIB_FLAG", - "QMAKE_LINK_SHLIB_CMD", - "QMAKE_LN_SHLIB", - "QMAKE_POST_LINK", - "QMAKE_PRE_LINK", - "QMAKE_PROJECT_NAME", - "QMAKE_MAC_SDK", - "QMAKE_MACOSX_DEPLOYMENT_TARGET", - "QMAKE_MAKEFILE", - "QMAKE_MOC_SRC", - "QMAKE_QMAKE", - "QMAKE_QT_DLL", - "QMAKE_RESOURCE_FLAGS", - "QMAKE_RPATH", - "QMAKE_RPATHDIR", - "QMAKE_RUN_CC", - "QMAKE_RUN_CC_IMP", - "QMAKE_RUN_CXX", - "QMAKE_RUN_CXX_IMP", - "QMAKE_TARGET", - "QMAKE_UIC", - "QT", - "QTPLUGIN", - "QT_VERSION", - "QT_MAJOR_VERSION", - "QT_MINOR_VERSION", - "QT_PATCH_VERSION", - "RCC_DIR", - "RC_FILE", - "REQUIRES", - "RESOURCES", - "RES_FILE", - "RSS_RULES", - "SIGNATURE_FILE", - "SOURCES", - "SRCMOC", - "STATECHARTS", - "SUBDIRS", - "TEMPLATE", - "TRANSLATIONS", - "UICIMPLS", - "UICOBJECTS", - "UI_DIR", - "UI_HEADERS_DIR", - "UI_SOURCES_DIR", - "VER_MAJ", - "VER_MIN", - "VER_PAT", - "VERSION", - "VPATH", - "YACCIMPLS", - "YACCOBJECTS", - "YACCSOURCES", - "_PRO_FILE_", - "_PRO_FILE_PWD_", - 0 -}; - -static const char *const functionKeywords[] = { - "basename", - "contains", - "count", - "dirname", - "error", - "eval", - "exists", - "find", - "for", - "include", - "infile", - "isEmpty", - "join", - "member", - "message", - "packagesExist", - "prompt", - "quote", - "replace", - "sprintf", - "system", - "unique", - "warning", - 0 -}; - -class ProFileKeywordsImplementation -{ -public: - static ProFileKeywordsImplementation *instance(); - QStringList variables(); - QStringList functions(); - bool isVariable(const QString &word); - bool isFunction(const QString &word); -private: - ProFileKeywordsImplementation(); - static ProFileKeywordsImplementation *m_instance; - QStringList m_variables; - QStringList m_functions; -}; - -ProFileKeywordsImplementation *ProFileKeywordsImplementation::m_instance = 0; - -ProFileKeywordsImplementation *ProFileKeywordsImplementation::instance() -{ - if (!m_instance) - m_instance = new ProFileKeywordsImplementation(); - return m_instance; -} - -QStringList ProFileKeywordsImplementation::variables() -{ - return m_variables; -} - -QStringList ProFileKeywordsImplementation::functions() -{ - return m_functions; -} - -bool ProFileKeywordsImplementation::isVariable(const QString &word) -{ - return m_variables.contains(word); -} - -bool ProFileKeywordsImplementation::isFunction(const QString &word) -{ - return m_functions.contains(word); -} - -ProFileKeywordsImplementation::ProFileKeywordsImplementation() -{ - for (uint i = 0; i < sizeof variableKeywords / sizeof variableKeywords[0] - 1; i++) - m_variables.append(QLatin1String(variableKeywords[i])); - for (uint i = 0; i < sizeof functionKeywords / sizeof functionKeywords[0] - 1; i++) - m_functions.append(QLatin1String(functionKeywords[i])); -} - -ProFileKeywords::ProFileKeywords() -{ -} - -QStringList ProFileKeywords::variables() -{ - return ProFileKeywordsImplementation::instance()->variables(); -} - -QStringList ProFileKeywords::functions() -{ - return ProFileKeywordsImplementation::instance()->functions(); -} - -bool ProFileKeywords::isVariable(const QString &word) -{ - return ProFileKeywordsImplementation::instance()->isVariable(word); -} - -bool ProFileKeywords::isFunction(const QString &word) -{ - return ProFileKeywordsImplementation::instance()->isFunction(word); -} diff --git a/src/plugins/qt4projectmanager/qmakekitconfigwidget.cpp b/src/plugins/qt4projectmanager/qmakekitconfigwidget.cpp index d5546f90b1..062bda9c61 100644 --- a/src/plugins/qt4projectmanager/qmakekitconfigwidget.cpp +++ b/src/plugins/qt4projectmanager/qmakekitconfigwidget.cpp @@ -35,34 +35,35 @@ #include <coreplugin/icore.h> #include <projectexplorer/projectexplorerconstants.h> -#include <QHBoxLayout> #include <QLineEdit> namespace Qt4ProjectManager { namespace Internal { -QmakeKitConfigWidget::QmakeKitConfigWidget(ProjectExplorer::Kit *k, QWidget *parent) : - ProjectExplorer::KitConfigWidget(parent), - m_kit(k), +QmakeKitConfigWidget::QmakeKitConfigWidget(ProjectExplorer::Kit *k) : + ProjectExplorer::KitConfigWidget(k), m_lineEdit(new QLineEdit) { - setToolTip(tr("The mkspec to use when building the project with qmake.<br>" - "This setting is ignored when using other build systems.")); - QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); - - m_lineEdit->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_lineEdit); - refresh(); // set up everything according to kit connect(m_lineEdit, SIGNAL(textEdited(QString)), this, SLOT(mkspecWasChanged(QString))); } +QWidget *QmakeKitConfigWidget::mainWidget() const +{ + return m_lineEdit; +} + QString QmakeKitConfigWidget::displayName() const { return tr("Qt mkspec:"); } +QString QmakeKitConfigWidget::toolTip() const +{ + return tr("The mkspec to use when building the project with qmake.<br>" + "This setting is ignored when using other build systems."); +} + void QmakeKitConfigWidget::makeReadOnly() { m_lineEdit->setEnabled(false); diff --git a/src/plugins/qt4projectmanager/qmakekitconfigwidget.h b/src/plugins/qt4projectmanager/qmakekitconfigwidget.h index 0f2f9227e3..af69f4ef03 100644 --- a/src/plugins/qt4projectmanager/qmakekitconfigwidget.h +++ b/src/plugins/qt4projectmanager/qmakekitconfigwidget.h @@ -32,13 +32,11 @@ #include <projectexplorer/kitconfigwidget.h> -QT_FORWARD_DECLARE_CLASS(QLineEdit) - -namespace ProjectExplorer { class Kit; } +QT_BEGIN_NAMESPACE +class QLineEdit; +QT_END_NAMESPACE namespace Qt4ProjectManager { -class BaseQtVersion; - namespace Internal { class QmakeKitConfigWidget : public ProjectExplorer::KitConfigWidget @@ -46,12 +44,13 @@ class QmakeKitConfigWidget : public ProjectExplorer::KitConfigWidget Q_OBJECT public: - explicit QmakeKitConfigWidget(ProjectExplorer::Kit *k, QWidget *parent = 0); + explicit QmakeKitConfigWidget(ProjectExplorer::Kit *k); + QWidget *mainWidget() const; QString displayName() const; + QString toolTip() const; void makeReadOnly(); - void refresh(); private slots: @@ -60,7 +59,6 @@ private slots: private: int findQtVersion(const int id) const; - ProjectExplorer::Kit *m_kit; QLineEdit *m_lineEdit; }; diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp index 310759593e..d9b94300eb 100644 --- a/src/plugins/qt4projectmanager/qmakestep.cpp +++ b/src/plugins/qt4projectmanager/qmakestep.cpp @@ -53,6 +53,7 @@ #include <qtsupport/qtkitinformation.h> #include <qtsupport/qtversionmanager.h> #include <qtsupport/debugginghelperbuildtask.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/qtcprocess.h> @@ -65,14 +66,15 @@ using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; using namespace ProjectExplorer; +using namespace Utils; namespace { -const char * const QMAKE_BS_ID("QtProjectManager.QMakeBuildStep"); +const char QMAKE_BS_ID[] = "QtProjectManager.QMakeBuildStep"; -const char * const QMAKE_ARGUMENTS_KEY("QtProjectManager.QMakeBuildStep.QMakeArguments"); -const char * const QMAKE_FORCED_KEY("QtProjectManager.QMakeBuildStep.QMakeForced"); -const char * const QMAKE_QMLDEBUGLIBAUTO_KEY("QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto"); -const char * const QMAKE_QMLDEBUGLIB_KEY("QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary"); +const char QMAKE_ARGUMENTS_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeArguments"; +const char QMAKE_FORCED_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeForced"; +const char QMAKE_QMLDEBUGLIBAUTO_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto"; +const char QMAKE_QMLDEBUGLIB_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary"; } QMakeStep::QMakeStep(BuildStepList *bsl) : @@ -136,7 +138,7 @@ QString QMakeStep::allArguments(bool shorted) arguments << QLatin1String("-r"); bool userProvidedMkspec = false; - for (Utils::QtcProcess::ConstArgIterator ait(m_userArgs); ait.next(); ) { + for (QtcProcess::ConstArgIterator ait(m_userArgs); ait.next(); ) { if (ait.value() == QLatin1String("-spec")) { if (ait.next()) { userProvidedMkspec = true; @@ -144,7 +146,7 @@ QString QMakeStep::allArguments(bool shorted) } } } - Utils::FileName specArg = mkspec(); + FileName specArg = mkspec(); if (!userProvidedMkspec && !specArg.isEmpty()) arguments << QLatin1String("-spec") << specArg.toUserOutput(); @@ -153,12 +155,12 @@ QString QMakeStep::allArguments(bool shorted) arguments << deducedArguments(); - QString args = Utils::QtcProcess::joinArgs(arguments); + QString args = QtcProcess::joinArgs(arguments); // User arguments - Utils::QtcProcess::addArgs(&args, m_userArgs); + QtcProcess::addArgs(&args, m_userArgs); // moreArgumentsAfter foreach (const QString &arg, deducedArgumentsAfter()) - Utils::QtcProcess::addArg(&args, arg); + QtcProcess::addArg(&args, arg); return args; } @@ -174,11 +176,11 @@ QStringList QMakeStep::deducedArguments() ProjectExplorer::Abi targetAbi; if (tc) targetAbi = tc->targetAbi(); -#if defined(Q_OS_WIN) || defined(Q_OS_MAC) - if ((targetAbi.osFlavor() == ProjectExplorer::Abi::HarmattanLinuxFlavor - || targetAbi.osFlavor() == ProjectExplorer::Abi::MaemoLinuxFlavor)) + if ((HostOsInfo::isWindowsHost() || HostOsInfo::isMacHost()) + && (targetAbi.osFlavor() == ProjectExplorer::Abi::HarmattanLinuxFlavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::MaemoLinuxFlavor)) { arguments << QLatin1String("-unix"); -#endif + } // explicitly add architecture to CONFIG if ((targetAbi.os() == ProjectExplorer::Abi::MacOS) @@ -259,7 +261,7 @@ bool QMakeStep::init() else workingDirectory = qt4bc->buildDirectory(); - Utils::FileName program = qtVersion->qmakeCommand(); + FileName program = qtVersion->qmakeCommand(); QString makefile = workingDirectory; @@ -446,7 +448,7 @@ void QMakeStep::setLinkQmlDebuggingLibrary(bool enable) QStringList QMakeStep::parserArguments() { QStringList result; - for (Utils::QtcProcess::ConstArgIterator ait(allArguments()); ait.next(); ) + for (QtcProcess::ConstArgIterator ait(allArguments()); ait.next(); ) if (ait.isSimple()) result << ait.value(); return result; @@ -457,13 +459,13 @@ QString QMakeStep::userArguments() return m_userArgs; } -Utils::FileName QMakeStep::mkspec() +FileName QMakeStep::mkspec() { QString additionalArguments = m_userArgs; - for (Utils::QtcProcess::ArgIterator ait(&additionalArguments); ait.next(); ) { + for (QtcProcess::ArgIterator ait(&additionalArguments); ait.next(); ) { if (ait.value() == QLatin1String("-spec")) { if (ait.next()) - return Utils::FileName::fromUserInput(ait.value()); + return FileName::fromUserInput(ait.value()); } } diff --git a/src/plugins/qt4projectmanager/qt-desktop/desktopqtversion.cpp b/src/plugins/qt4projectmanager/qt-desktop/desktopqtversion.cpp index d9926c400f..292ae22df7 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/desktopqtversion.cpp +++ b/src/plugins/qt4projectmanager/qt-desktop/desktopqtversion.cpp @@ -28,7 +28,7 @@ ****************************************************************************/ #include "desktopqtversion.h" -#include "qt4projectmanagerconstants.h" +#include "../qt4projectmanagerconstants.h" #include <qtsupport/qtsupportconstants.h> #include <proparser/profileevaluator.h> diff --git a/src/plugins/qt4projectmanager/qt-desktop/desktopqtversionfactory.cpp b/src/plugins/qt4projectmanager/qt-desktop/desktopqtversionfactory.cpp index 8697760557..66dd8a1fdb 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/desktopqtversionfactory.cpp +++ b/src/plugins/qt4projectmanager/qt-desktop/desktopqtversionfactory.cpp @@ -27,8 +27,8 @@ ** ****************************************************************************/ #include "desktopqtversionfactory.h" -#include "qt4projectmanagerconstants.h" #include "desktopqtversion.h" +#include "../qt4projectmanagerconstants.h" #include <qtsupport/qtversionmanager.h> #include <qtsupport/qtsupportconstants.h> diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp index 8a318b6fb8..a14eab2193 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp @@ -29,12 +29,12 @@ #include "qt4runconfiguration.h" -#include "makestep.h" -#include "qt4nodes.h" -#include "qt4project.h" -#include "qt4buildconfiguration.h" -#include "qt4projectmanagerconstants.h" -#include "qmakestep.h" +#include "../makestep.h" +#include "../qt4nodes.h" +#include "../qt4project.h" +#include "../qt4buildconfiguration.h" +#include "../qt4projectmanagerconstants.h" +#include "../qmakestep.h" #include <coreplugin/coreconstants.h> #include <coreplugin/icore.h> @@ -58,6 +58,7 @@ #include <qtsupport/baseqtversion.h> #include <qtsupport/profilereader.h> #include <qtsupport/qtkitinformation.h> +#include <utils/hostosinfo.h> #include <QFormLayout> #include <QInputDialog> @@ -150,7 +151,7 @@ QString Qt4RunConfiguration::disabledReason() const return QString(); } -void Qt4RunConfiguration::kitUpdated(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress) +void Qt4RunConfiguration::proFileUpdated(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress) { if (m_proFilePath != pro->path()) { if (!parseInProgress) { @@ -183,8 +184,8 @@ void Qt4RunConfiguration::ctor() connect(target(), SIGNAL(environmentChanged()), this, SIGNAL(baseEnvironmentChanged())); - connect(target()->project(), SIGNAL(kitUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)), - this, SLOT(kitUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool))); + connect(target()->project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)), + this, SLOT(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool))); connect(target(), SIGNAL(kitChanged()), this, SLOT(kitChanged())); } @@ -261,13 +262,13 @@ Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4Run toplayout->addRow(QString(), m_useTerminalCheck); m_useTerminalCheck->setVisible(!m_qt4RunConfiguration->forcedGuiMode()); -#ifdef Q_OS_MAC - m_usingDyldImageSuffix = new QCheckBox(tr("Use debug version of frameworks (DYLD_IMAGE_SUFFIX=_debug)"), this); - m_usingDyldImageSuffix->setChecked(m_qt4RunConfiguration->isUsingDyldImageSuffix()); - toplayout->addRow(QString(), m_usingDyldImageSuffix); - connect(m_usingDyldImageSuffix, SIGNAL(toggled(bool)), - this, SLOT(usingDyldImageSuffixToggled(bool))); -#endif + if (Utils::HostOsInfo::isMacHost()) { + m_usingDyldImageSuffix = new QCheckBox(tr("Use debug version of frameworks (DYLD_IMAGE_SUFFIX=_debug)"), this); + m_usingDyldImageSuffix->setChecked(m_qt4RunConfiguration->isUsingDyldImageSuffix()); + toplayout->addRow(QString(), m_usingDyldImageSuffix); + connect(m_usingDyldImageSuffix, SIGNAL(toggled(bool)), + this, SLOT(usingDyldImageSuffixToggled(bool))); + } QLabel *environmentLabel = new QLabel(this); environmentLabel->setText(tr("Run Environment")); diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h index 8d2c87437f..edca7d613e 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h @@ -113,7 +113,7 @@ signals: private slots: void kitChanged(); - void kitUpdated(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress); + void proFileUpdated(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress); protected: Qt4RunConfiguration(ProjectExplorer::Target *parent, Qt4RunConfiguration *source); diff --git a/src/plugins/qt4projectmanager/qt4buildconfiguration.cpp b/src/plugins/qt4projectmanager/qt4buildconfiguration.cpp index 5b2b8f247f..3d0542f41c 100644 --- a/src/plugins/qt4projectmanager/qt4buildconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt4buildconfiguration.cpp @@ -43,29 +43,31 @@ #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> #include <projectexplorer/toolchain.h> +#include <projectexplorer/toolchainmanager.h> #include <projectexplorer/kitinformation.h> #include <qtsupport/qtsupportconstants.h> #include <qtsupport/qtversionfactory.h> #include <qtsupport/baseqtversion.h> #include <qtsupport/qtkitinformation.h> #include <qtsupport/qtversionmanager.h> +#include <qt4projectmanager/qmakekitinformation.h> #include <QDebug> #include <QInputDialog> -using namespace Qt4ProjectManager; -using namespace Qt4ProjectManager::Internal; -using namespace ProjectExplorer; +namespace Qt4ProjectManager { -namespace { -const char * const QT4_BC_ID("Qt4ProjectManager.Qt4BuildConfiguration"); +using namespace Internal; +using namespace ProjectExplorer; +using namespace QtSupport; +using namespace Utils; -const char * const USE_SHADOW_BUILD_KEY("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild"); -const char * const BUILD_DIRECTORY_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory"); -const char * const BUILD_CONFIGURATION_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration"); +const char QT4_BC_ID[] = "Qt4ProjectManager.Qt4BuildConfiguration"; +const char USE_SHADOW_BUILD_KEY[] = "Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild"; +const char BUILD_DIRECTORY_KEY[] = "Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory"; +const char BUILD_CONFIGURATION_KEY[] = "Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration"; enum { debug = 0 }; -} Qt4BuildConfiguration::Qt4BuildConfiguration(Target *target) : BuildConfiguration(target, Core::Id(QT4_BC_ID)), @@ -121,12 +123,18 @@ bool Qt4BuildConfiguration::fromMap(const QVariantMap &map) return false; m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool(); - m_qmakeBuildConfiguration = QtSupport::BaseQtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt()); + m_qmakeBuildConfiguration = BaseQtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt()); m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), defaultShadowBuildDirectory()).toString(); m_lastEmmitedBuildDirectory = buildDirectory(); m_qtVersionSupportsShadowBuilds = supportsShadowBuilds(); + m_lastKitState = LastKitState(target()->kit()); + + connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainUpdated(ProjectExplorer::ToolChain *)), + this, SLOT(toolChainUpdated(ProjectExplorer::ToolChain *))); + connect(QtSupport::QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>,QList<int>,QList<int>)), + this, SLOT(qtVersionsChanged(QList<int>,QList<int>,QList<int>))); return true; } @@ -142,9 +150,27 @@ void Qt4BuildConfiguration::ctor() void Qt4BuildConfiguration::kitChanged() { - emitProFileEvaluateNeeded(); - emit environmentChanged(); - emitBuildDirectoryChanged(); + LastKitState newState = LastKitState(target()->kit()); + if (newState != m_lastKitState) { + // This only checks if the ids have changed! + // For that reason the Qt4BuildConfiguration is also connected + // to the toolchain and qtversion managers + emitProFileEvaluateNeeded(); + emitBuildDirectoryChanged(); + m_lastKitState = newState; + } +} + +void Qt4BuildConfiguration::toolChainUpdated(ProjectExplorer::ToolChain *tc) +{ + if (ToolChainKitInformation::toolChain(target()->kit()) == tc) + emitProFileEvaluateNeeded(); +} + +void Qt4BuildConfiguration::qtVersionsChanged(const QList<int> &,const QList<int> &, const QList<int> &changed) +{ + if (changed.contains(QtKitInformation::qtVersionId(target()->kit()))) + emitProFileEvaluateNeeded(); } void Qt4BuildConfiguration::emitBuildDirectoryChanged() @@ -158,15 +184,9 @@ void Qt4BuildConfiguration::emitBuildDirectoryChanged() } } -Utils::Environment Qt4BuildConfiguration::baseEnvironment() const +NamedWidget *Qt4BuildConfiguration::createConfigWidget() { - Utils::Environment env = BuildConfiguration::baseEnvironment(); - return env; -} - -BuildConfigWidget *Qt4BuildConfiguration::createConfigWidget() -{ - return new Qt4ProjectConfigWidget(target()); + return new Qt4ProjectConfigWidget(this); } QString Qt4BuildConfiguration::defaultShadowBuildDirectory() const @@ -191,7 +211,7 @@ QString Qt4BuildConfiguration::rawBuildDirectory() const return workingDirectory; } -/// returns the build directory +/// Returns the build directory. QString Qt4BuildConfiguration::buildDirectory() const { QString path = QDir::cleanPath(environment().expandVariables(rawBuildDirectory())); @@ -200,14 +220,14 @@ QString Qt4BuildConfiguration::buildDirectory() const bool Qt4BuildConfiguration::supportsShadowBuilds() { - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); return !version || version->supportsShadowBuilds(); } /// If only a sub tree should be build this function returns which sub node /// should be build /// \see Qt4BuildConfiguration::setSubNodeBuild -Qt4ProjectManager::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const +Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const { return m_subNodeBuild; } @@ -218,7 +238,7 @@ Qt4ProjectManager::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const /// calling BuildManager::buildProject( BuildConfiguration * ) /// and reset immediately afterwards /// That is m_subNodesBuild is set only temporarly -void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Qt4ProFileNode *node) +void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProFileNode *node) { m_subNodeBuild = node; } @@ -253,7 +273,7 @@ QString Qt4BuildConfiguration::shadowBuildDirectory() const void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const QString &buildDirectory) { - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); QString directoryToSet = buildDirectory; bool toSet = (shadowBuild && version && version->isValid() && version->supportsShadowBuilds()); if (m_shadowBuild == toSet && m_buildDirectory == directoryToSet) @@ -262,15 +282,14 @@ void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const Q m_shadowBuild = toSet; m_buildDirectory = directoryToSet; - emit environmentChanged(); emitBuildDirectoryChanged(); emitProFileEvaluateNeeded(); } QString Qt4BuildConfiguration::defaultMakeTarget() const { - ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(target()->kit()); - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); + ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit()); + BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); if (!tc || !version) return QString(); @@ -282,12 +301,12 @@ QString Qt4BuildConfiguration::makefile() const return static_cast<Qt4Project *>(target()->project())->rootQt4ProjectNode()->makefile(); } -QtSupport::BaseQtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const +BaseQtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const { return m_qmakeBuildConfiguration; } -void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtSupport::BaseQtVersion::QmakeBuildConfigs config) +void Qt4BuildConfiguration::setQMakeBuildConfiguration(BaseQtVersion::QmakeBuildConfigs config) { if (m_qmakeBuildConfiguration == config) return; @@ -314,17 +333,18 @@ void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged() QStringList Qt4BuildConfiguration::configCommandLineArguments() const { QStringList result; - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); - QtSupport::BaseQtVersion::QmakeBuildConfigs defaultBuildConfiguration = version ? version->defaultBuildConfig() : (QtSupport::BaseQtVersion::DebugBuild | QtSupport::BaseQtVersion::BuildAll); - QtSupport::BaseQtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration; - if ((defaultBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) && !(userBuildConfiguration & QtSupport::BaseQtVersion::BuildAll)) + BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion::QmakeBuildConfigs defaultBuildConfiguration = + version ? version->defaultBuildConfig() : (BaseQtVersion::DebugBuild | BaseQtVersion::BuildAll); + BaseQtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration; + if ((defaultBuildConfiguration & BaseQtVersion::BuildAll) && !(userBuildConfiguration & BaseQtVersion::BuildAll)) result << QLatin1String("CONFIG-=debug_and_release"); - if (!(defaultBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) && (userBuildConfiguration & QtSupport::BaseQtVersion::BuildAll)) + if (!(defaultBuildConfiguration & BaseQtVersion::BuildAll) && (userBuildConfiguration & BaseQtVersion::BuildAll)) result << QLatin1String("CONFIG+=debug_and_release"); - if ((defaultBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild) && !(userBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild)) + if ((defaultBuildConfiguration & BaseQtVersion::DebugBuild) && !(userBuildConfiguration & BaseQtVersion::DebugBuild)) result << QLatin1String("CONFIG+=release"); - if (!(defaultBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild) && (userBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild)) + if (!(defaultBuildConfiguration & BaseQtVersion::DebugBuild) && (userBuildConfiguration & BaseQtVersion::DebugBuild)) result << QLatin1String("CONFIG+=debug"); return result; } @@ -351,19 +371,19 @@ MakeStep *Qt4BuildConfiguration::makeStep() const return 0; } -// returns true if both are equal +// Returns true if both are equal. Qt4BuildConfiguration::MakefileState Qt4BuildConfiguration::compareToImportFrom(const QString &makefile) { QMakeStep *qs = qmakeStep(); if (QFileInfo(makefile).exists() && qs) { - Utils::FileName qmakePath = QtSupport::QtVersionManager::findQMakeBinaryFromMakefile(makefile); - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); + FileName qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(makefile); + BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); if (!version) return MakefileForWrongProject; if (version->qmakeCommand() == qmakePath) { // same qtversion - QPair<QtSupport::BaseQtVersion::QmakeBuildConfigs, QString> result = - QtSupport::QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig()); + QPair<BaseQtVersion::QmakeBuildConfigs, QString> result = + QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig()); if (qmakeBuildConfiguration() == result.first) { // The qmake Build Configuration are the same, // now compare arguments lists @@ -376,17 +396,17 @@ Qt4BuildConfiguration::MakefileState Qt4BuildConfiguration::compareToImportFrom( // are not interested in), splitting them up into individual strings: extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs); actualArgs = qs->deducedArguments() + actualArgs + qs->deducedArgumentsAfter(); - Utils::FileName actualSpec = qs->mkspec(); + FileName actualSpec = qs->mkspec(); QString qmakeArgs = result.second; QStringList parsedArgs; - Utils::FileName parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs); + FileName parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs); if (debug) { - qDebug()<<"Actual args:"<<actualArgs; - qDebug()<<"Parsed args:"<<parsedArgs; - qDebug()<<"Actual spec:"<<actualSpec.toString(); - qDebug()<<"Parsed spec:"<<parsedSpec.toString(); + qDebug() << "Actual args:" << actualArgs; + qDebug() << "Parsed args:" << parsedArgs; + qDebug() << "Actual spec:" << actualSpec.toString(); + qDebug() << "Parsed spec:" << parsedSpec.toString(); } // Comparing the sorted list is obviously wrong @@ -410,20 +430,22 @@ Qt4BuildConfiguration::MakefileState Qt4BuildConfiguration::compareToImportFrom( if (actualSpec == parsedSpec) return MakefileMatches; // Actual spec is the default one -// qDebug()<<"AS vs VS"<<actualSpec<<version->mkspec(); - if ((actualSpec == version->mkspec() || actualSpec == Utils::FileName::fromString(QLatin1String("default"))) - && (parsedSpec == version->mkspec() || parsedSpec == Utils::FileName::fromString(QLatin1String("default")) || parsedSpec.isEmpty())) +// qDebug() << "AS vs VS" << actualSpec << version->mkspec(); + if ((actualSpec == version->mkspec() || actualSpec == FileName::fromString(QLatin1String("default"))) + && (parsedSpec == version->mkspec() || parsedSpec == FileName::fromString(QLatin1String("default")) || parsedSpec.isEmpty())) return MakefileMatches; } return MakefileIncompatible; } else { if (debug) - qDebug()<<"different qmake buildconfigurations buildconfiguration:"<<qmakeBuildConfiguration()<<" Makefile:"<<result.first; + qDebug() << "different qmake buildconfigurations buildconfiguration:" + << qmakeBuildConfiguration() << " Makefile:" << result.first; return MakefileIncompatible; } } else { if (debug) - qDebug() << "different Qt versions, buildconfiguration:" << version->qmakeCommand().toString() << " Makefile:"<< qmakePath.toString(); + qDebug() << "different Qt versions, buildconfiguration:" << version->qmakeCommand().toString() + << " Makefile:"<< qmakePath.toString(); return MakefileForWrongProject; } } @@ -433,7 +455,7 @@ Qt4BuildConfiguration::MakefileState Qt4BuildConfiguration::compareToImportFrom( bool Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args) { bool removedArgument = false; - for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) { + for (QtcProcess::ArgIterator ait(args); ait.next(); ) { const QString arg = ait.value(); if (arg.contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH)) || arg.contains(QLatin1String(Constants::QMAKEVAR_QUICK1_DEBUG)) @@ -445,21 +467,21 @@ bool Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args) return removedArgument; } -Utils::FileName Qt4BuildConfiguration::extractSpecFromArguments(QString *args, - const QString &directory, const QtSupport::BaseQtVersion *version, - QStringList *outArgs) +FileName Qt4BuildConfiguration::extractSpecFromArguments(QString *args, + const QString &directory, const BaseQtVersion *version, + QStringList *outArgs) { - Utils::FileName parsedSpec; + FileName parsedSpec; bool ignoreNext = false; bool nextIsSpec = false; - for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) { + for (QtcProcess::ArgIterator ait(args); ait.next(); ) { if (ignoreNext) { ignoreNext = false; ait.deleteArg(); } else if (nextIsSpec) { nextIsSpec = false; - parsedSpec = Utils::FileName::fromUserInput(ait.value()); + parsedSpec = FileName::fromUserInput(ait.value()); ait.deleteArg(); } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) { nextIsSpec = true; @@ -479,9 +501,9 @@ Utils::FileName Qt4BuildConfiguration::extractSpecFromArguments(QString *args, } if (parsedSpec.isEmpty()) - return Utils::FileName(); + return FileName(); - Utils::FileName baseMkspecDir = Utils::FileName::fromUserInput( + FileName baseMkspecDir = FileName::fromUserInput( version->qmakeProperty("QT_HOST_DATA") + QLatin1String("/mkspecs")); baseMkspecDir = Utils::FileName::fromString(baseMkspecDir.toFileInfo().canonicalFilePath()); @@ -492,23 +514,23 @@ Utils::FileName Qt4BuildConfiguration::extractSpecFromArguments(QString *args, // for the other one we don't need to do anything if (parsedSpec.toFileInfo().isRelative()) { if (QFileInfo(directory + QLatin1Char('/') + parsedSpec.toString()).exists()) { - parsedSpec = Utils::FileName::fromUserInput(directory + QLatin1Char('/') + parsedSpec.toString()); + parsedSpec = FileName::fromUserInput(directory + QLatin1Char('/') + parsedSpec.toString()); } else { - parsedSpec = Utils::FileName::fromUserInput(baseMkspecDir.toString() + QLatin1Char('/') + parsedSpec.toString()); + parsedSpec = FileName::fromUserInput(baseMkspecDir.toString() + QLatin1Char('/') + parsedSpec.toString()); } } QFileInfo f2 = parsedSpec.toFileInfo(); while (f2.isSymLink()) { - parsedSpec = Utils::FileName::fromString(f2.symLinkTarget()); + parsedSpec = FileName::fromString(f2.symLinkTarget()); f2.setFile(parsedSpec.toString()); } if (parsedSpec.isChildOf(baseMkspecDir)) { parsedSpec = parsedSpec.relativeChildPath(baseMkspecDir); } else { - Utils::FileName sourceMkSpecPath = Utils::FileName::fromString(version->sourcePath().toString() - + QLatin1String("/mkspecs")); + FileName sourceMkSpecPath = FileName::fromString(version->sourcePath().toString() + + QLatin1String("/mkspecs")); if (parsedSpec.isChildOf(sourceMkSpecPath)) { parsedSpec = parsedSpec.relativeChildPath(sourceMkSpecPath); } @@ -516,12 +538,6 @@ Utils::FileName Qt4BuildConfiguration::extractSpecFromArguments(QString *args, return parsedSpec; } -ProjectExplorer::IOutputParser *Qt4BuildConfiguration::createOutputParser() const -{ - ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit()); - return tc ? tc->outputParser() : 0; -} - bool Qt4BuildConfiguration::isEnabled() const { return m_isEnabled; @@ -547,11 +563,11 @@ void Qt4BuildConfiguration::setEnabled(bool enabled) */ Qt4BuildConfigurationFactory::Qt4BuildConfigurationFactory(QObject *parent) : - ProjectExplorer::IBuildConfigurationFactory(parent) + IBuildConfigurationFactory(parent) { update(); - QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance(); + QtVersionManager *vm = QtVersionManager::instance(); connect(vm, SIGNAL(qtVersionsChanged(QList<int>,QList<int>,QList<int>)), this, SLOT(update())); } @@ -593,12 +609,12 @@ bool Qt4BuildConfigurationFactory::canCreate(const Target *parent, const Core::I return id == QT4_BC_ID; } -BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target *parent, const Core::Id id, const QString &name) +BuildConfiguration *Qt4BuildConfigurationFactory::create(Target *parent, const Core::Id id, const QString &name) { if (!canCreate(parent, id)) return 0; - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(parent->kit()); + BaseQtVersion *version = QtKitInformation::qtVersion(parent->kit()); Q_ASSERT(version); bool ok = true; @@ -625,7 +641,7 @@ BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target if (buildConfigurationName != version->displayName()) customSecondName = tr("%1 Release").arg(buildConfigurationName); - if (!(version->defaultBuildConfig() & QtSupport::BaseQtVersion::DebugBuild)) { + if (!(version->defaultBuildConfig() & BaseQtVersion::DebugBuild)) { qSwap(defaultFirstName, defaultSecondName); qSwap(customFirstName, customSecondName); } @@ -635,12 +651,12 @@ BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target version->defaultBuildConfig(), QString(), QString(), false); parent->addBuildConfiguration( Qt4BuildConfiguration::setup(parent, defaultSecondName, customSecondName, - (version->defaultBuildConfig() ^ QtSupport::BaseQtVersion::DebugBuild), + (version->defaultBuildConfig() ^ BaseQtVersion::DebugBuild), QString(), QString(), false)); return bc; } -bool Qt4BuildConfigurationFactory::canClone(const Target *parent, ProjectExplorer::BuildConfiguration *source) const +bool Qt4BuildConfigurationFactory::canClone(const Target *parent, BuildConfiguration *source) const { return canHandle(parent) && qobject_cast<Qt4BuildConfiguration *>(source); } @@ -671,20 +687,20 @@ BuildConfiguration *Qt4BuildConfigurationFactory::restore(Target *parent, const return 0; } -QList<BuildConfigurationInfo> Qt4BuildConfigurationFactory::availableBuildConfigurations(const ProjectExplorer::Kit *k, +QList<BuildConfigurationInfo> Qt4BuildConfigurationFactory::availableBuildConfigurations(const Kit *k, const QString &proFilePath) { QList<BuildConfigurationInfo> infoList; - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); + BaseQtVersion *version = QtKitInformation::qtVersion(k); if (!version || !version->isValid()) return infoList; - QtSupport::BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); + BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); BuildConfigurationInfo info = BuildConfigurationInfo(config, QString(), QString(), false); info.directory = Qt4Project::shadowBuildDirectory(proFilePath, k, buildConfigurationDisplayName(info)); infoList.append(info); - info.buildConfig = config ^ QtSupport::BaseQtVersion::DebugBuild; + info.buildConfig = config ^ BaseQtVersion::DebugBuild; info.directory = Qt4Project::shadowBuildDirectory(proFilePath, k, buildConfigurationDisplayName(info)); infoList.append(info); return infoList; @@ -693,7 +709,7 @@ QList<BuildConfigurationInfo> Qt4BuildConfigurationFactory::availableBuildConfig // Return name of a build configuration. QString Qt4BuildConfigurationFactory::buildConfigurationDisplayName(const BuildConfigurationInfo &info) { - return (info.buildConfig & QtSupport::BaseQtVersion::DebugBuild) ? + return (info.buildConfig & BaseQtVersion::DebugBuild) ? //: Name of a debug build configuration to created by a project wizard. We recommend not translating it. tr("Debug") : //: Name of a release build configuration to be created by a project wizard. We recommend not translating it. @@ -702,7 +718,7 @@ QString Qt4BuildConfigurationFactory::buildConfigurationDisplayName(const BuildC BuildConfiguration::BuildType Qt4BuildConfiguration::buildType() const { - if (qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild) + if (qmakeBuildConfiguration() & BaseQtVersion::DebugBuild) return Debug; else return Release; @@ -710,21 +726,19 @@ BuildConfiguration::BuildType Qt4BuildConfiguration::buildType() const Qt4BuildConfiguration *Qt4BuildConfiguration::setup(Target *t, QString defaultDisplayName, QString displayName, - QtSupport::BaseQtVersion::QmakeBuildConfigs qmakeBuildConfiguration, + BaseQtVersion::QmakeBuildConfigs qmakeBuildConfiguration, QString additionalArguments, QString directory, bool importing) { - bool debug = qmakeBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild; + bool debug = qmakeBuildConfiguration & BaseQtVersion::DebugBuild; - // Add the buildconfiguration + // Add the build configuration. Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(t); bc->setDefaultDisplayName(defaultDisplayName); bc->setDisplayName(displayName); - ProjectExplorer::BuildStepList *buildSteps = - bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)); - ProjectExplorer::BuildStepList *cleanSteps = - bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)); + BuildStepList *buildSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)); + BuildStepList *cleanSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)); Q_ASSERT(buildSteps); Q_ASSERT(cleanSteps); @@ -734,7 +748,7 @@ Qt4BuildConfiguration *Qt4BuildConfiguration::setup(Target *t, QString defaultDi MakeStep *makeStep = new MakeStep(buildSteps); buildSteps->insertStep(1, makeStep); - MakeStep* cleanStep = new MakeStep(cleanSteps); + MakeStep *cleanStep = new MakeStep(cleanSteps); cleanStep->setClean(true); cleanStep->setUserArguments(QLatin1String("clean")); cleanSteps->insertStep(0, cleanStep); @@ -746,8 +760,8 @@ Qt4BuildConfiguration *Qt4BuildConfiguration::setup(Target *t, QString defaultDi if (importing) qmakeStep->setLinkQmlDebuggingLibrary(enableQmlDebugger); - // set some options for qmake and make - if (qmakeBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) // debug_and_release => explicit targets + // Set some options for qmake and make. + if (qmakeBuildConfiguration & BaseQtVersion::BuildAll) // debug_and_release => explicit targets makeStep->setUserArguments(debug ? QLatin1String("debug") : QLatin1String("release")); bc->setQMakeBuildConfiguration(qmakeBuildConfiguration); @@ -757,3 +771,34 @@ Qt4BuildConfiguration *Qt4BuildConfiguration::setup(Target *t, QString defaultDi return bc; } + +Qt4BuildConfiguration::LastKitState::LastKitState() +{ + +} + +Qt4BuildConfiguration::LastKitState::LastKitState(Kit *k) + : m_qtVersion(QtKitInformation::qtVersionId(k)), + m_sysroot(SysRootKitInformation::sysRoot(k).toString()), + m_mkspec(QmakeKitInformation::mkspec(k).toString()) +{ + ToolChain *tc = ToolChainKitInformation::toolChain(k); + m_toolchain = tc ? tc->id() : QString(); +} + +bool Qt4BuildConfiguration::LastKitState::operator ==(const LastKitState &other) +{ + return m_qtVersion == other.m_qtVersion + && m_toolchain == other.m_toolchain + && m_sysroot == other.m_sysroot + && m_mkspec == other.m_mkspec; +} + +bool Qt4BuildConfiguration::LastKitState::operator !=(const LastKitState &other) +{ + return !operator ==(other); +} + + + +} // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt4buildconfiguration.h b/src/plugins/qt4projectmanager/qt4buildconfiguration.h index a9b787a62f..4a79296613 100644 --- a/src/plugins/qt4projectmanager/qt4buildconfiguration.h +++ b/src/plugins/qt4projectmanager/qt4buildconfiguration.h @@ -55,9 +55,7 @@ public: explicit Qt4BuildConfiguration(ProjectExplorer::Target *target); ~Qt4BuildConfiguration(); - Utils::Environment baseEnvironment() const; - - ProjectExplorer::BuildConfigWidget *createConfigWidget(); + ProjectExplorer::NamedWidget *createConfigWidget(); QString buildDirectory() const; bool shadowBuild() const; QString shadowBuildDirectory() const; @@ -100,8 +98,6 @@ public: QVariantMap toMap() const; - ProjectExplorer::IOutputParser *createOutputParser() const; - virtual bool isEnabled() const; virtual QString disabledReason() const; /// \internal For Qt4Project, since that manages the parsing information @@ -129,6 +125,8 @@ signals: private slots: void kitChanged(); + void toolChainUpdated(ProjectExplorer::ToolChain *tc); + void qtVersionsChanged(const QList<int> &, const QList<int> &, const QList<int> &changed); void emitBuildDirectoryChanged(); protected: @@ -141,6 +139,21 @@ private: QString rawBuildDirectory() const; QString defaultShadowBuildDirectory() const; + class LastKitState + { + public: + LastKitState(); + explicit LastKitState(ProjectExplorer::Kit *k); + bool operator ==(const LastKitState &other); + bool operator !=(const LastKitState &other); + private: + int m_qtVersion; + QString m_toolchain; + QString m_sysroot; + QString m_mkspec; + }; + LastKitState m_lastKitState; + bool m_shadowBuild; bool m_isEnabled; QString m_buildDirectory; diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index 02b573e2b5..86dab2615a 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -57,6 +57,7 @@ #include <qtsupport/qtkitinformation.h> #include <qtsupport/qtsupportconstants.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/stringutils.h> #include <utils/fileutils.h> @@ -337,10 +338,8 @@ struct InternalNode fileWithoutPrefix = file; } QStringList parts = fileWithoutPrefix.toString().split(separator, QString::SkipEmptyParts); -#ifndef Q_OS_WIN - if (!isRelative && parts.count() > 0) + if (!Utils::HostOsInfo::isWindowsHost() && !isRelative && parts.count() > 0) parts[0].prepend(separator); -#endif QStringListIterator it(parts); InternalNode *currentNode = this; QString path = (isRelative ? (projectDirFileName.toString() + QLatin1Char('/')) : QString()); @@ -1391,28 +1390,19 @@ TargetInformation Qt4ProFileNode::targetInformation(const QString &fileName) con QString Qt4ProFileNode::makefile() const { - if (m_varValues[Makefile].isEmpty()) - return QString(); - return m_varValues[Makefile].first(); + return singleVariableValue(Makefile); } QString Qt4ProFileNode::objectExtension() const { - if (m_varValues[ObjectExt].isEmpty()) { -#ifdef Q_OS_WIN - return QLatin1String(".obj"); -#else - return QLatin1String(".o"); -#endif - } + if (m_varValues[ObjectExt].isEmpty()) + return Utils::HostOsInfo::isWindowsHost() ? QLatin1String(".obj") : QLatin1String(".o"); return m_varValues[ObjectExt].first(); } QString Qt4ProFileNode::objectsDirectory() const { - if (m_varValues[ObjectsDir].isEmpty()) - return QString(); - return m_varValues[ObjectsDir].first(); + return singleVariableValue(ObjectsDir); } QByteArray Qt4ProFileNode::cxxDefines() const @@ -1494,10 +1484,9 @@ bool Qt4ProFileNode::isParent(Qt4ProFileNode *node) void Qt4ProFileNode::buildStateChanged(ProjectExplorer::Project *project) { - if (project == m_project && !ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager()->isBuilding(m_project)) { - QStringList filesToUpdate = updateUiFiles(); - updateCodeModelSupportFromBuild(filesToUpdate); - } + if (project == m_project + && !ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager()->isBuilding(m_project)) + updateCodeModelSupportFromBuild(); } bool Qt4ProFileNode::hasBuildTargets() const @@ -1532,11 +1521,16 @@ QString Qt4ProFileNode::singleVariableValue(const Qt4Variable var) const return values.isEmpty() ? QString() : values.first(); } +QStringList Qt4ProFileNode::uiFiles() const +{ + return m_uiHeaderFiles; +} + void Qt4ProFileNode::emitProFileUpdatedRecursive() { foreach (ProjectExplorer::NodesWatcher *watcher, watchers()) if (Internal::Qt4NodesWatcher *qt4Watcher = qobject_cast<Internal::Qt4NodesWatcher*>(watcher)) - emit qt4Watcher->kitUpdated(this, m_validParse, m_parseInProgress); + emit qt4Watcher->proFileUpdated(this, m_validParse, m_parseInProgress); foreach (ProjectNode *subNode, subProjectNodes()) { if (Qt4ProFileNode *node = qobject_cast<Qt4ProFileNode *>(subNode)) { @@ -1562,7 +1556,7 @@ void Qt4ProFileNode::setParseInProgress(bool b) m_parseInProgress = b; foreach (ProjectExplorer::NodesWatcher *watcher, watchers()) if (Internal::Qt4NodesWatcher *qt4Watcher = qobject_cast<Internal::Qt4NodesWatcher*>(watcher)) - emit qt4Watcher->kitUpdated(this, m_validParse, m_parseInProgress); + emit qt4Watcher->proFileUpdated(this, m_validParse, m_parseInProgress); } void Qt4ProFileNode::setValidParseRecursive(bool b) @@ -1919,7 +1913,6 @@ void Qt4ProFileNode::applyEvaluate(EvalResult evalResult, bool async) m_subProjectsNotToDeploy = subProjectsNotToDeploy; setupInstallsList(m_readerExact); - setupProjectVersion(m_readerExact); // update other variables QHash<Qt4Variable, QStringList> newVarValues; @@ -1983,7 +1976,6 @@ void Qt4ProFileNode::applyEvaluate(EvalResult evalResult, bool async) setParseInProgress(false); createUiCodeModelSupport(); - updateUiFiles(); m_project->destroyProFileReader(m_readerExact); m_project->destroyProFileReader(m_readerCumulative); @@ -2015,114 +2007,6 @@ QStringList Qt4ProFileNode::fileListForVar(QtSupport::ProFileReader *readerExact return result; } -// This function is triggered after a build, and updates the state ui files -// It does so by storing a modification time for each ui file we know about. -QStringList Qt4ProFileNode::updateUiFiles() -{ -// qDebug()<<"Qt4ProFileNode::updateUiFiles()"; - // Only those two project types can have ui files for us - if (m_projectType != ApplicationTemplate - && m_projectType != LibraryTemplate) - return QStringList(); - - // Find all ui files - FindUiFileNodesVisitor uiFilesVisitor; - this->accept(&uiFilesVisitor); - const QList<ProjectExplorer::FileNode*> uiFiles = uiFilesVisitor.uiFileNodes; - - // Find the UiDir, there can only ever be one - QString uiDir = buildDir(); - QStringList tmp = m_varValues[UiDirVar]; - if (tmp.size() != 0) - uiDir = tmp.first(); - - // Collect all existing generated files - QList<ProjectExplorer::FileNode*> existingFileNodes; - foreach (ProjectExplorer::FileNode *file, fileNodes()) { - if (file->isGenerated()) - existingFileNodes << file; - } - - // Convert uiFile to uiHeaderFilePath, find all headers that correspond - // and try to find them in uiDir - QStringList newFilePaths; - foreach (ProjectExplorer::FileNode *uiFile, uiFiles) { - const QString uiHeaderFilePath - = QString::fromLatin1("%1/ui_%2.h").arg(uiDir, QFileInfo(uiFile->path()).completeBaseName()); - if (QFileInfo(uiHeaderFilePath).exists()) - newFilePaths << uiHeaderFilePath; - } - - // Create a diff between those lists - QList<ProjectExplorer::FileNode*> toRemove; - QList<ProjectExplorer::FileNode*> toAdd; - // The list of files for which we call updateSourceFile - QStringList toUpdate; - - qSort(newFilePaths); - qSort(existingFileNodes.begin(), existingFileNodes.end(), sortNodesByPath); - - QList<ProjectExplorer::FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin(); - QList<QString>::const_iterator newPathIter = newFilePaths.constBegin(); - while (existingNodeIter != existingFileNodes.constEnd() - && newPathIter != newFilePaths.constEnd()) { - if ((*existingNodeIter)->path() < *newPathIter) { - toRemove << *existingNodeIter; - ++existingNodeIter; - } else if ((*existingNodeIter)->path() > *newPathIter) { - toAdd << new ProjectExplorer::FileNode(*newPathIter, ProjectExplorer::HeaderType, true); - ++newPathIter; - } else { // *existingNodeIter->path() == *newPathIter - QString fileName = (*existingNodeIter)->path(); - QMap<QString, QDateTime>::const_iterator it = m_uitimestamps.find(fileName); - QDateTime lastModified = QFileInfo(fileName).lastModified(); - if (it == m_uitimestamps.constEnd() || it.value() < lastModified) { - toUpdate << fileName; - m_uitimestamps[fileName] = lastModified; - } - ++existingNodeIter; - ++newPathIter; - } - } - while (existingNodeIter != existingFileNodes.constEnd()) { - toRemove << *existingNodeIter; - ++existingNodeIter; - } - while (newPathIter != newFilePaths.constEnd()) { - toAdd << new ProjectExplorer::FileNode(*newPathIter, ProjectExplorer::HeaderType, true); - ++newPathIter; - } - - // Update project tree - if (!toRemove.isEmpty()) { - foreach (ProjectExplorer::FileNode *file, toRemove) - m_uitimestamps.remove(file->path()); - removeFileNodes(toRemove, this); - } - - CPlusPlus::CppModelManagerInterface *modelManager = - CPlusPlus::CppModelManagerInterface::instance(); - - if (!toAdd.isEmpty()) { - foreach (ProjectExplorer::FileNode *file, toAdd) { - m_uitimestamps.insert(file->path(), QFileInfo(file->path()).lastModified()); - toUpdate << file->path(); - - // Also adding files depending on that - // We only need to do that for files that were newly created - QString fileName = QFileInfo(file->path()).fileName(); - foreach (CPlusPlus::Document::Ptr doc, modelManager->snapshot()) { - if (doc->includedFiles().contains(fileName)) { - if (!toUpdate.contains(doc->fileName())) - toUpdate << doc->fileName(); - } - } - } - addFileNodes(toAdd, this); - } - return toUpdate; -} - QString Qt4ProFileNode::uiDirPath(QtSupport::ProFileReader *reader) const { QString path = reader->value(QLatin1String("UI_DIR")); @@ -2228,65 +2112,89 @@ TargetInformation Qt4ProFileNode::targetInformation(QtSupport::ProFileReader *re if (!reader) return result; + QtSupport::ProFileReader *readerBP = 0; + QStringList builds = reader->values("BUILDS"); + QString buildTarget; + if (!builds.isEmpty()) { + QString build = builds.first(); + buildTarget = reader->value(build + ".target"); + + QHash<QString, QStringList> basevars; + QStringList basecfgs = reader->values(build + QLatin1String(".CONFIG")); + basecfgs += build; + basecfgs += "build_pass"; + basevars["BUILD_PASS"] = QStringList(build); + QStringList buildname = reader->values(build + QLatin1String(".name")); + basevars["BUILD_NAME"] = (buildname.isEmpty() ? QStringList(build) : buildname); + + readerBP = m_project->createProFileReader(this); + readerBP->setExtraVars(basevars); + readerBP->setExtraConfigs(basecfgs); + + EvalResult evalResult = EvalOk; + if (ProFile *pro = readerBP->parsedProFile(m_projectFilePath)) { + if (!readerBP->accept(pro, QMakeEvaluator::LoadAll)) + evalResult = EvalPartial; + pro->deref(); + } else { + evalResult = EvalFail; + } + + if (evalResult != EvalOk) + return result; + + reader = readerBP; + } + + // BUILD DIR result.buildDir = buildDir(); const QString baseDir = result.buildDir; // qDebug() << "base build dir is:"<<baseDir; - // Working Directory - const QString destDir = QLatin1String("DESTDIR"); - if (reader->contains(destDir)) { - //qDebug() << "reader contains destdir:" << reader->value("DESTDIR"); - result.workingDir = reader->value(destDir); - if (QDir::isRelativePath(result.workingDir)) { - result.workingDir = baseDir + QLatin1Char('/') + result.workingDir; - //qDebug() << "was relative and expanded to" << result.workingDir; - } + QString destDir; + if (reader->contains(QLatin1String("DESTDIR"))) { + destDir = reader->value(QLatin1String("DESTDIR")); + bool workingDirIsBaseDir = false; + if (destDir == buildTarget) // special case for "debug" or "release" + workingDirIsBaseDir = true; + + if (QDir::isRelativePath(destDir)) + destDir = baseDir + QLatin1Char('/') + destDir; + + if (workingDirIsBaseDir) + result.workingDir = baseDir; + else + result.workingDir = destDir; } else { - //qDebug() << "reader didn't contain DESTDIR, setting to " << baseDir; + destDir = baseDir; result.workingDir = baseDir; } + // Target result.target = reader->value(QLatin1String("TARGET")); if (result.target.isEmpty()) result.target = QFileInfo(m_projectFilePath).baseName(); -#if defined (Q_OS_MAC) - if (reader->values(QLatin1String("CONFIG")).contains(QLatin1String("app_bundle"))) { - result.workingDir += QLatin1Char('/') - + result.target - + QLatin1String(".app/Contents/MacOS"); + if (Utils::HostOsInfo::isMacHost() + && reader->values(QLatin1String("CONFIG")).contains(QLatin1String("app_bundle"))) { + const QString infix = QLatin1Char('/') + result.target + + QLatin1String(".app/Contents/MacOS"); + result.workingDir += infix; + destDir += infix; } -#endif result.workingDir = QDir::cleanPath(result.workingDir); - QString wd = result.workingDir; - if ( (!reader->contains(destDir) || reader->value(destDir) == QLatin1String("."))) { - const QStringList configValues = reader->values(QLatin1String("CONFIG")); - if (configValues.contains(QLatin1String("debug_and_release")) - && configValues.contains(QLatin1String("debug_and_release_target"))) { - // If we don't have a destdir and debug and release is set - // then the executable is in a debug/release folder - //qDebug() << "reader has debug_and_release_target"; - - // Hmm can we find out whether it's debug or release in a saner way? - // Theoretically it's in CONFIG - QString qmakeBuildConfig = QLatin1String("release"); - ProjectExplorer::Target *target = m_project->activeTarget(); - Qt4BuildConfiguration *bc = target ? qobject_cast<Qt4BuildConfiguration *>(target->activeBuildConfiguration()) : 0; - if (!target || !bc || bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild) - qmakeBuildConfig = QLatin1String("debug"); - wd += QLatin1Char('/') + qmakeBuildConfig; - } - } - - result.executable = QDir::cleanPath(wd + QLatin1Char('/') + result.target); + /// should this really be in this method? + result.executable = QDir::cleanPath(destDir + QLatin1Char('/') + result.target); //qDebug() << "##### updateTarget sets:" << result.workingDir << result.executable; -#if defined (Q_OS_WIN) - result.executable += QLatin1String(".exe"); -#endif + Utils::HostOsInfo::appendExecutableSuffix(result.executable); result.valid = true; + + if (readerBP) + m_project->destroyProFileReader(readerBP); + return result; } @@ -2343,59 +2251,6 @@ void Qt4ProFileNode::setupInstallsList(const QtSupport::ProFileReader *reader) } } -void Qt4ProFileNode::setupProjectVersion(const QtSupport::ProFileReader *reader) -{ - m_projectVersion.major = m_projectVersion.minor = m_projectVersion.patch = -1; - bool ok; - int val = reader->value(QLatin1String("VER_MAJ")).toInt(&ok); - if (ok) - m_projectVersion.major = val; - val = reader->value(QLatin1String("VER_MIN")).toInt(&ok); - if (ok) - m_projectVersion.minor = val; - val = reader->value(QLatin1String("VER_PAT")).toInt(&ok); - if (ok) - m_projectVersion.patch = val; - if (m_projectVersion.major != -1 && m_projectVersion.minor != -1 - && m_projectVersion.patch != -1) { - return; - } - - const QString &version = reader->value(QLatin1String("VERSION")); - const QChar dot(QLatin1Char('.')); - int dotIndex = version.indexOf(dot); - if (m_projectVersion.major == -1) { - val = version.left(dotIndex).toInt(&ok); - if (ok) - m_projectVersion.major = val; - } - if (dotIndex != -1) { - int numberStartIndex = dotIndex + 1; - dotIndex = version.indexOf(dot, numberStartIndex); - if (m_projectVersion.minor == -1) { - val = version.mid(numberStartIndex, dotIndex - numberStartIndex).toInt(&ok); - if (ok) - m_projectVersion.minor = val; - } - } - if (dotIndex != -1) { - int numberStartIndex = dotIndex + 1; - dotIndex = version.indexOf(dot, numberStartIndex); - if (m_projectVersion.patch == -1) { - val = version.mid(numberStartIndex, dotIndex - numberStartIndex).toInt(&ok); - if (ok) - m_projectVersion.patch= val; - } - } - - if (m_projectVersion.major == -1) - m_projectVersion.major = 1; - if (m_projectVersion.minor == -1) - m_projectVersion.minor = 0; - if (m_projectVersion.patch == -1) - m_projectVersion.patch = 0; -} - InstallsList Qt4ProFileNode::installsList() const { return m_installsList; @@ -2417,16 +2272,12 @@ QString Qt4ProFileNode::buildDir(Qt4BuildConfiguration *bc) const return QDir(bc->buildDirectory()).absoluteFilePath(relativeDir); } -void Qt4ProFileNode::updateCodeModelSupportFromBuild(const QStringList &files) +void Qt4ProFileNode::updateCodeModelSupportFromBuild() { - foreach (const QString &file, files) { - QMap<QString, Internal::Qt4UiCodeModelSupport *>::const_iterator it, end; - end = m_uiCodeModelSupport.constEnd(); - for (it = m_uiCodeModelSupport.constBegin(); it != end; ++it) { - if (it.value()->fileName() == file) - it.value()->updateFromBuild(); - } - } + QMap<QString, Internal::Qt4UiCodeModelSupport *>::const_iterator it, end; + end = m_uiCodeModelSupport.constEnd(); + for (it = m_uiCodeModelSupport.constBegin(); it != end; ++it) + it.value()->updateFromBuild(); } void Qt4ProFileNode::updateCodeModelSupportFromEditor(const QString &uiFileName, @@ -2469,6 +2320,8 @@ void Qt4ProFileNode::createUiCodeModelSupport() oldCodeModelSupport = m_uiCodeModelSupport; m_uiCodeModelSupport.clear(); + m_uiHeaderFiles.clear(); + // Only those two project types can have ui files for us if (m_projectType == ApplicationTemplate || m_projectType == LibraryTemplate) { // Find all ui files @@ -2480,6 +2333,7 @@ void Qt4ProFileNode::createUiCodeModelSupport() const QString uiDir = uiDirectory(); foreach (const ProjectExplorer::FileNode *uiFile, uiFiles) { const QString uiHeaderFilePath = uiHeaderFile(uiDir, uiFile->path()); + m_uiHeaderFiles << uiHeaderFilePath; // qDebug()<<"code model support for "<<uiFile->path()<<" "<<uiHeaderFilePath; QMap<QString, Internal::Qt4UiCodeModelSupport *>::iterator it = oldCodeModelSupport.find(uiFile->path()); if (it != oldCodeModelSupport.end()) { diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h index 609b8333d9..cc106ecd4a 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.h +++ b/src/plugins/qt4projectmanager/qt4nodes.h @@ -257,7 +257,7 @@ signals: const QHash<Qt4Variable, QStringList> &oldValues, const QHash<Qt4Variable, QStringList> &newValues); - void kitUpdated(Qt4ProjectManager::Qt4ProFileNode *projectNode, bool success, bool parseInProgress); + void proFileUpdated(Qt4ProjectManager::Qt4ProFileNode *projectNode, bool success, bool parseInProgress); private: // let them emit signals @@ -367,7 +367,7 @@ public: return !m_subProjectsNotToDeploy.contains(filePath); } - void updateCodeModelSupportFromBuild(const QStringList &files); + void updateCodeModelSupportFromBuild(); void updateCodeModelSupportFromEditor(const QString &uiFileName, const QString &contents); QString sourceDir() const; @@ -375,13 +375,13 @@ public: QString uiDirectory() const; static QString uiHeaderFile(const QString &uiDir, const QString &formFile); + QStringList uiFiles() const; const Qt4ProFileNode *findProFileFor(const QString &string) const; TargetInformation targetInformation(const QString &fileName) const; TargetInformation targetInformation() const; InstallsList installsList() const; - ProjectVersion projectVersion() const { return m_projectVersion; } QString makefile() const; QString objectExtension() const; @@ -422,7 +422,6 @@ private: typedef QHash<Qt4Variable, QStringList> Qt4VariablesHash; void createUiCodeModelSupport(); - QStringList updateUiFiles(); QStringList fileListForVar(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative, const QString &varName, const QString &projectDir, FileType type) const; @@ -434,7 +433,6 @@ private: TargetInformation targetInformation(QtSupport::ProFileReader *reader) const; void setupInstallsList(const QtSupport::ProFileReader *reader); - void setupProjectVersion(const QtSupport::ProFileReader *reader); Qt4ProjectType m_projectType; Qt4VariablesHash m_varValues; @@ -445,12 +443,13 @@ private: QString m_resolvedMkspecPath; QStringList m_subProjectsNotToDeploy; InstallsList m_installsList; - ProjectVersion m_projectVersion; friend class Qt4NodeHierarchy; bool m_validParse; bool m_parseInProgress; + QStringList m_uiHeaderFiles; + // Async stuff QFutureWatcher<EvalResult> m_parseFutureWatcher; QtSupport::ProFileReader *m_readerExact; diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index f9d33f6505..4b60ccc7d4 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -46,6 +46,8 @@ #include <coreplugin/messagemanager.h> #include <coreplugin/coreconstants.h> #include <coreplugin/progressmanager/progressmanager.h> +#include <coreplugin/documentmanager.h> +#include <coreplugin/variablemanager.h> #include <extensionsystem/pluginmanager.h> #include <cpptools/ModelManagerInterface.h> #include <qmljs/qmljsmodelmanagerinterface.h> @@ -54,7 +56,6 @@ #include <projectexplorer/toolchain.h> #include <projectexplorer/headerpath.h> #include <projectexplorer/target.h> -#include <projectexplorer/buildenvironmentwidget.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorerconstants.h> @@ -67,6 +68,7 @@ #include <qtsupport/qtsupportconstants.h> #include <qtsupport/qtversionmanager.h> #include <utils/QtConcurrentTools> +#include <utils/stringutils.h> #include <QDebug> #include <QDir> @@ -115,6 +117,53 @@ QString sanitize(const QString &input) return result; } +class Qt4ProjectExpander : public Utils::AbstractQtcMacroExpander +{ +public: + Qt4ProjectExpander(const QString &proFilePath, const Kit *k, const QString &bcName) : + m_proFile(proFilePath), m_kit(k), m_bcName(bcName) + { } + + bool resolveMacro(const QString &name, QString *ret) + { + QString result; + bool found = false; + if (name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTPROJECT_NAME)) { + result = m_proFile.baseName(); + found = true; + } else if (name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTPROJECT_PATH)) { + result = m_proFile.absolutePath(); + found = true; + } else if (name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTPROJECT_FILEPATH)) { + result = m_proFile.absoluteFilePath(); + found = true; + } else if (m_kit && name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTKIT_NAME)) { + result = m_kit->displayName(); + found = true; + } else if (m_kit && name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTKIT_FILESYSTEMNAME)) { + result = m_kit->fileSystemFriendlyName(); + found = true; + } else if (m_kit && name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTKIT_ID)) { + result = m_kit->id().toString(); + found = true; + } else if (name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTBUILD_NAME)) { + result = m_bcName; + found = true; + } else { + result = Core::VariableManager::instance()->value(name.toUtf8(), &found); + } + if (ret) + *ret = result; + return found; + } + +private: + QFileInfo m_proFile; + const Kit *m_kit; + QString m_bcName; + Utils::AbstractMacroExpander *m_expander; +}; + } // namespace namespace Qt4ProjectManager { @@ -359,7 +408,6 @@ Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) : m_pendingEvaluateFuturesCount(0), m_asyncUpdateState(NoState), m_cancelEvaluate(false), - m_codeModelCanceled(false), m_centralizedFolderWatcher(0), m_activeTarget(0) { @@ -397,6 +445,32 @@ void Qt4Project::updateFileList() } } +bool Qt4Project::setupTarget(ProjectExplorer::Target *t) +{ + QList<BuildConfigurationInfo> infoList + = Qt4BuildConfigurationFactory::availableBuildConfigurations(t->kit(), m_fileInfo->fileName()); + setupTarget(t, infoList); + return true; +} + +void Qt4Project::setupTarget(ProjectExplorer::Target *t, const QList<BuildConfigurationInfo> &infoList) +{ + // Build Configurations: + foreach (const BuildConfigurationInfo &info, infoList) { + QString name = info.buildConfig & QtSupport::BaseQtVersion::DebugBuild + ? tr("Debug") : tr("Release"); + Qt4BuildConfiguration *bc + = Qt4BuildConfiguration::setup(t, name, name, + info.buildConfig, info.additionalArguments, + info.directory, info.importing); + t->addBuildConfiguration(bc); + } + + // Deploy Configurations: + t->updateDefaultDeployConfigurations(); + // Do not create Run Configurations: Those will be generated later anyway. +} + bool Qt4Project::fromMap(const QVariantMap &map) { if (!Project::fromMap(map)) @@ -423,8 +497,8 @@ bool Qt4Project::fromMap(const QVariantMap &map) updateCodeModels(); // We have the profile nodes now, so we know the runconfigs! - connect(m_nodesWatcher, SIGNAL(kitUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)), - this, SIGNAL(kitUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool))); + connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)), + this, SIGNAL(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool))); // Now we emit update once :) m_rootProjectNode->emitProFileUpdatedRecursive(); @@ -516,9 +590,11 @@ void Qt4Project::updateCppCodeModel() ProjectPart::Ptr part(new ProjectPart); part->qtVersion = qtVersionForPart; + QStringList cxxflags = pro->variableValue(CppFlagsVar); + // part->defines if (tc) - part->defines = tc->predefinedMacros(pro->variableValue(CppFlagsVar)); + part->defines = tc->predefinedMacros(cxxflags); part->defines += pro->cxxDefines(); // part->includePaths @@ -526,7 +602,7 @@ void Qt4Project::updateCppCodeModel() QList<HeaderPath> headers; if (tc) - headers = tc->systemHeaderPaths(SysRootKitInformation::sysRoot(k)); // todo pass cxxflags? + headers = tc->systemHeaderPaths(cxxflags, SysRootKitInformation::sysRoot(k)); if (qtVersion) { headers.append(qtVersion->systemHeaderPathes(k)); } @@ -557,6 +633,7 @@ void Qt4Project::updateCppCodeModel() part->sourceFiles = pro->variableValue(CppSourceVar); part->sourceFiles += pro->variableValue(CppHeaderVar); + part->sourceFiles += pro->uiFiles(); part->sourceFiles.prepend(QLatin1String("<configuration>")); pinfo.appendProjectPart(part); @@ -712,7 +789,6 @@ void Qt4Project::scheduleAsyncUpdate(Qt4ProFileNode *node) // Cancel running code model update m_codeModelFuture.cancel(); - m_codeModelCanceled = true; } else if (m_asyncUpdateState == AsyncUpdateInProgress) { // A update is in progress // And this slot only gets called if a file changed on disc @@ -761,7 +837,6 @@ void Qt4Project::scheduleAsyncUpdate() // Cancel running code model update m_codeModelFuture.cancel(); - m_codeModelCanceled = true; } @@ -789,6 +864,7 @@ void Qt4Project::decrementPendingEvaluateFutures() // We are done! if (debug) qDebug()<<" reporting finished"; + m_asyncUpdateFutureInterface->reportFinished(); delete m_asyncUpdateFutureInterface; m_asyncUpdateFutureInterface = 0; @@ -934,10 +1010,10 @@ void Qt4Project::proFileParseError(const QString &errorMessage) Core::ICore::messageManager()->printToOutputPanePopup(errorMessage); } -QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc) +QtSupport::ProFileReader *Qt4Project::createProFileReader(const Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc) { if (!m_qmakeGlobals) { - m_qmakeGlobals = new QMakeGlobals; + m_qmakeGlobals = new ProFileGlobals; m_qmakeGlobalsRefCnt = 0; Kit *k; @@ -949,12 +1025,10 @@ QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4Pro if (bc) { k = bc->target()->kit(); env = bc->environment(); - if (bc->qmakeStep()) { + if (bc->qmakeStep()) qmakeArgs = bc->qmakeStep()->parserArguments(); - m_qmakeGlobals->qmakespec = m_qmakeGlobals->xqmakespec = bc->qmakeStep()->mkspec().toString(); - } else { + else qmakeArgs = bc->configCommandLineArguments(); - } } else { k = KitManager::instance()->defaultKit(); } @@ -974,7 +1048,7 @@ QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4Pro for (; eit != eend; ++eit) m_qmakeGlobals->environment.insert(env.key(eit), env.value(eit)); - m_qmakeGlobals->setCommandLineArguments(qmakeArgs); + m_qmakeGlobals->setCommandLineArguments(m_rootProjectNode->buildDir(), qmakeArgs); QtSupport::ProFileCacheManager::instance()->incRefCount(); } @@ -987,7 +1061,7 @@ QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4Pro return reader; } -QMakeGlobals *Qt4Project::qmakeGlobals() +ProFileGlobals *Qt4Project::qmakeGlobals() { return m_qmakeGlobals; } @@ -1033,13 +1107,6 @@ bool Qt4Project::parseInProgress(const QString &proFilePath) const return node && node->parseInProgress(); } -QList<BuildConfigWidget*> Qt4Project::subConfigWidgets() -{ - QList<BuildConfigWidget*> subWidgets; - subWidgets << new BuildEnvironmentWidget; - return subWidgets; -} - void Qt4Project::collectAllfProFiles(QList<Qt4ProFileNode *> &list, Qt4ProFileNode *node) { list.append(node); @@ -1393,19 +1460,20 @@ QString Qt4Project::disabledReasonForRunConfiguration(const QString &proFilePath .arg(QFileInfo(proFilePath).fileName()); } -QString Qt4Project::shadowBuildDirectory(const QString &profilePath, const Kit *k, const QString &suffix) +QString Qt4Project::shadowBuildDirectory(const QString &proFilePath, const Kit *k, const QString &suffix) { - if (profilePath.isEmpty()) + if (proFilePath.isEmpty()) return QString(); - QFileInfo info(profilePath); + QFileInfo info(proFilePath); QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); if (version && !version->supportsShadowBuilds()) return info.absolutePath(); - QString base = QDir::cleanPath(projectDirectory(profilePath) + QLatin1String("/../") - + info.baseName() + QLatin1String("-build-")); - return base + buildNameFor(k) + QLatin1String("-") + sanitize(suffix); + Qt4ProjectExpander expander(proFilePath, k, suffix); + QDir projectDir = QDir(projectDirectory(proFilePath)); + QString buildPath = Utils::expandMacros(Core::DocumentManager::buildDirectory(), &expander); + return QDir::cleanPath(projectDir.absoluteFilePath(buildPath)); } QString Qt4Project::buildNameFor(const Kit *k) @@ -1422,22 +1490,7 @@ Target *Qt4Project::createTarget(Kit *k, const QList<BuildConfigurationInfo> &in return 0; Target *t = new Target(this, k); - - // Build Configurations: - foreach (const BuildConfigurationInfo &info, infoList) { - QString name = info.buildConfig & QtSupport::BaseQtVersion::DebugBuild - ? tr("Debug") : tr("Release"); - Qt4BuildConfiguration *bc - = Qt4BuildConfiguration::setup(t, name, name, - info.buildConfig, info.additionalArguments, - info.directory, info.importing); - t->addBuildConfiguration(bc); - } - - // Deploy Configurations: - t->updateDefaultDeployConfigurations(); - // Do not create Run Configurations: Those will be generated later anyway. - + setupTarget(t, infoList); return t; } diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h index a814cbce1d..58863844d7 100644 --- a/src/plugins/qt4projectmanager/qt4project.h +++ b/src/plugins/qt4projectmanager/qt4project.h @@ -42,7 +42,7 @@ #include <QFuture> QT_BEGIN_NAMESPACE -class QMakeGlobals; +class ProFileGlobals; QT_END_NAMESPACE namespace ProjectExplorer { class DeploymentData; } @@ -92,8 +92,6 @@ public: virtual QStringList files(FilesMode fileMode) const; virtual QString generatedUiHeader(const QString &formFile) const; - QList<ProjectExplorer::BuildConfigWidget*> subConfigWidgets(); - QList<Qt4ProFileNode *> allProFiles() const; QList<Qt4ProFileNode *> applicationProFiles() const; bool hasApplicationProFile(const QString &path) const; @@ -102,9 +100,9 @@ public: void notifyChanged(const QString &name); /// \internal - QtSupport::ProFileReader *createProFileReader(Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc = 0); + QtSupport::ProFileReader *createProFileReader(const Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc = 0); /// \internal - QMakeGlobals *qmakeGlobals(); + ProFileGlobals *qmakeGlobals(); /// \internal void destroyProFileReader(QtSupport::ProFileReader *reader); @@ -144,7 +142,7 @@ public: void emitBuildDirectoryInitialized(); signals: - void kitUpdated(Qt4ProjectManager::Qt4ProFileNode *node, bool, bool); + void proFileUpdated(Qt4ProjectManager::Qt4ProFileNode *node, bool, bool); void buildDirectoryInitialized(); void proFilesEvaluated(); @@ -155,6 +153,8 @@ public slots: protected: bool fromMap(const QVariantMap &map); + bool setupTarget(ProjectExplorer::Target *t); + void setupTarget(ProjectExplorer::Target *t, const QList<BuildConfigurationInfo> &infoList); private slots: void asyncUpdate(); @@ -195,7 +195,7 @@ private: Internal::Qt4ProjectFiles *m_projectFiles; // cached data during project rescan - QMakeGlobals *m_qmakeGlobals; + ProFileGlobals *m_qmakeGlobals; int m_qmakeGlobalsRefCnt; QTimer m_asyncUpdateTimer; @@ -204,7 +204,6 @@ private: enum AsyncUpdateState { NoState, Base, AsyncFullUpdatePending, AsyncPartialUpdatePending, AsyncUpdateInProgress, ShuttingDown }; AsyncUpdateState m_asyncUpdateState; bool m_cancelEvaluate; - bool m_codeModelCanceled; QList<Qt4ProFileNode *> m_partialEvaluate; QFuture<void> m_codeModelFuture; diff --git a/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp b/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp index 8f89331089..6379d5736c 100644 --- a/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp +++ b/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp @@ -58,17 +58,13 @@ #include <QPushButton> #include <utils/detailswidget.h> -namespace { -bool debug = false; -} - using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; using namespace ProjectExplorer; -Qt4ProjectConfigWidget::Qt4ProjectConfigWidget(ProjectExplorer::Target *target) - : BuildConfigWidget(), - m_buildConfiguration(0), +Qt4ProjectConfigWidget::Qt4ProjectConfigWidget(Qt4BuildConfiguration *bc) + : NamedWidget(), + m_buildConfiguration(bc), m_ignoreChange(false) { QVBoxLayout *vbox = new QVBoxLayout(this); @@ -95,11 +91,24 @@ Qt4ProjectConfigWidget::Qt4ProjectConfigWidget(ProjectExplorer::Target *target) connect(m_ui->shadowBuildDirEdit, SIGNAL(changed(QString)), this, SLOT(shadowBuildEdited())); - Qt4Project *project = static_cast<Qt4Project *>(target->project()); + Qt4Project *project = static_cast<Qt4Project *>(bc->target()->project()); connect(project, SIGNAL(environmentChanged()), this, SLOT(environmentChanged())); connect(project, SIGNAL(buildDirectoryInitialized()), this, SLOT(updateProblemLabel())); - connect(target, SIGNAL(kitChanged()), this, SLOT(updateProblemLabel())); + connect(bc->target(), SIGNAL(kitChanged()), this, SLOT(updateProblemLabel())); + + m_ui->shadowBuildDirEdit->setEnvironment(m_buildConfiguration->environment()); + + connect(m_buildConfiguration, SIGNAL(buildDirectoryChanged()), + this, SLOT(buildDirectoryChanged())); + connect(m_buildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()), + this, SLOT(updateProblemLabel())); + + m_ui->shadowBuildDirEdit->setBaseDirectory(m_buildConfiguration->target()->project()->projectDirectory()); + + buildDirectoryChanged(); + + setDisplayName(tr("General")); } Qt4ProjectConfigWidget::~Qt4ProjectConfigWidget() @@ -126,37 +135,6 @@ void Qt4ProjectConfigWidget::environmentChanged() m_ui->shadowBuildDirEdit->setEnvironment(m_buildConfiguration->environment()); } -QString Qt4ProjectConfigWidget::displayName() const -{ - return tr("General"); -} - -void Qt4ProjectConfigWidget::init(ProjectExplorer::BuildConfiguration *bc) -{ - QTC_ASSERT(bc, return); - - if (debug) - qDebug() << "Qt4ProjectConfigWidget::init() for" << bc->displayName(); - - if (m_buildConfiguration) { - disconnect(m_buildConfiguration, SIGNAL(buildDirectoryChanged()), - this, SLOT(buildDirectoryChanged())); - disconnect(m_buildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()), - this, SLOT(updateProblemLabel())); - } - m_buildConfiguration = static_cast<Qt4BuildConfiguration *>(bc); - m_ui->shadowBuildDirEdit->setEnvironment(m_buildConfiguration->environment()); - - connect(m_buildConfiguration, SIGNAL(buildDirectoryChanged()), - this, SLOT(buildDirectoryChanged())); - connect(m_buildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()), - this, SLOT(updateProblemLabel())); - - m_ui->shadowBuildDirEdit->setBaseDirectory(m_buildConfiguration->target()->project()->projectDirectory()); - - buildDirectoryChanged(); -} - void Qt4ProjectConfigWidget::buildDirectoryChanged() { if (m_ignoreChange) diff --git a/src/plugins/qt4projectmanager/qt4projectconfigwidget.h b/src/plugins/qt4projectmanager/qt4projectconfigwidget.h index 16d26c13bd..fdaddce3d7 100644 --- a/src/plugins/qt4projectmanager/qt4projectconfigwidget.h +++ b/src/plugins/qt4projectmanager/qt4projectconfigwidget.h @@ -30,7 +30,7 @@ #ifndef QT4PROJECTCONFIGWIDGET_H #define QT4PROJECTCONFIGWIDGET_H -#include <projectexplorer/buildstep.h> +#include <projectexplorer/namedwidget.h> QT_BEGIN_NAMESPACE class QAbstractButton; @@ -49,16 +49,13 @@ namespace Ui { class Qt4ProjectConfigWidget; } -class Qt4ProjectConfigWidget : public ProjectExplorer::BuildConfigWidget +class Qt4ProjectConfigWidget : public ProjectExplorer::NamedWidget { Q_OBJECT public: - Qt4ProjectConfigWidget(ProjectExplorer::Target *target); + Qt4ProjectConfigWidget(Qt4BuildConfiguration *bc); ~Qt4ProjectConfigWidget(); - QString displayName() const; - void init(ProjectExplorer::BuildConfiguration *bc); - private slots: // User changes in our widgets void shadowBuildClicked(bool checked); diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.cpp b/src/plugins/qt4projectmanager/qt4projectmanager.cpp index 3bb7066808..b217ac05e3 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.cpp +++ b/src/plugins/qt4projectmanager/qt4projectmanager.cpp @@ -45,7 +45,6 @@ #include <coreplugin/id.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/ieditor.h> -#include <coreplugin/variablemanager.h> #include <projectexplorer/projectexplorer.h> #include <projectexplorer/buildmanager.h> #include <projectexplorer/session.h> @@ -76,9 +75,6 @@ using ProjectExplorer::FormType; using ProjectExplorer::ResourceType; using ProjectExplorer::UnknownFileType; -static const char kHostBins[] = "CurrentProject:QT_HOST_BINS"; -static const char kInstallBins[] = "CurrentProject:QT_INSTALL_BINS"; - // Known file types of a Qt 4 project static const char *qt4FileTypes[] = { "CppHeaderFiles", @@ -138,15 +134,6 @@ void Qt4Manager::init() connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), this, SLOT(editorChanged(Core::IEditor*))); - - Core::VariableManager *vm = Core::VariableManager::instance(); - vm->registerVariable(kHostBins, - tr("Full path to the host bin directory of the current project's Qt version.")); - vm->registerVariable(kInstallBins, - tr("Full path to the target bin directory of the current project's Qt version." - " You probably want %1 instead.").arg(QString::fromLatin1(kHostBins))); - connect(vm, SIGNAL(variableUpdateRequested(QByteArray)), - this, SLOT(updateVariable(QByteArray))); } void Qt4Manager::editorChanged(Core::IEditor *editor) @@ -188,27 +175,6 @@ void Qt4Manager::editorAboutToClose(Core::IEditor *editor) } } -void Qt4Manager::updateVariable(const QByteArray &variable) -{ - if (variable == kHostBins || variable == kInstallBins) { - Qt4Project *qt4pro = qobject_cast<Qt4Project *>(ProjectExplorer::ProjectExplorerPlugin::currentProject()); - if (!qt4pro) { - Core::VariableManager::instance()->remove(variable); - return; - } - QString value; - const QtSupport::BaseQtVersion *qtv = 0; - if (ProjectExplorer::Target *t = qt4pro->activeTarget()) - qtv = QtSupport::QtKitInformation::qtVersion(t->kit()); - else - qtv = QtSupport::QtKitInformation::qtVersion(ProjectExplorer::KitManager::instance()->defaultKit()); - - if (qtv) - value = qtv->qmakeProperty(variable == kHostBins ? "QT_HOST_BINS" : "QT_INSTALL_BINS"); - Core::VariableManager::instance()->insert(variable, value); - } -} - void Qt4Manager::uiEditorContentsChanged() { // cast sender, get filename diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.h b/src/plugins/qt4projectmanager/qt4projectmanager.h index 4c98027e28..63465d77a1 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.h +++ b/src/plugins/qt4projectmanager/qt4projectmanager.h @@ -106,7 +106,6 @@ private slots: void editorAboutToClose(Core::IEditor *editor); void uiEditorContentsChanged(); void editorChanged(Core::IEditor*); - void updateVariable(const QByteArray &variable); private: QList<Qt4Project *> m_projects; diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.pro b/src/plugins/qt4projectmanager/qt4projectmanager.pro index ae1b4ff64d..9b228041cb 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.pro +++ b/src/plugins/qt4projectmanager/qt4projectmanager.pro @@ -63,7 +63,6 @@ HEADERS += \ librarydetailscontroller.h \ findqt4profiles.h \ qt4projectmanager_global.h \ - profilekeywords.h \ qt4targetsetupwidget.h \ buildconfigurationinfo.h \ winceqtversionfactory.h \ @@ -127,7 +126,6 @@ SOURCES += \ addlibrarywizard.cpp \ librarydetailscontroller.cpp \ findqt4profiles.cpp \ - profilekeywords.cpp \ qt4targetsetupwidget.cpp \ winceqtversionfactory.cpp \ winceqtversion.cpp \ diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.qbs b/src/plugins/qt4projectmanager/qt4projectmanager.qbs index b70d5f4d1e..57502c1d0e 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.qbs +++ b/src/plugins/qt4projectmanager/qt4projectmanager.qbs @@ -16,35 +16,30 @@ QtcPlugin { Depends { name: "TextEditor" } Depends { name: "cpp" } - cpp.defines: { - return base.concat([ - "PROPARSER_AS_LIBRARY", - "PROPARSER_THREAD_SAFE", - "PROEVALUATOR_THREAD_SAFE", - "PROEVALUATOR_CUMULATIVE" - ]) - } - cpp.includePaths: [ - ".", - "..", - buildDirectory, + cpp.defines: base.concat([ + "PROPARSER_AS_LIBRARY", + "PROPARSER_THREAD_SAFE", + "PROEVALUATOR_THREAD_SAFE", + "PROEVALUATOR_CUMULATIVE" + ]) + cpp.includePaths: base.concat([ "customwidgetwizard", - "../../libs", "../../shared", - ] + ]) files: [ "Qt4ProjectManager.mimetypes.xml", - "librarydetailswidget.ui", - "qt4projectmanager.qrc", "addlibrarywizard.cpp", "addlibrarywizard.h", + "buildconfigurationinfo.h", "externaleditors.cpp", "externaleditors.h", "findqt4profiles.cpp", "findqt4profiles.h", "librarydetailscontroller.cpp", "librarydetailscontroller.h", + "librarydetailswidget.ui", + "makestep.cpp", "makestep.h", "makestep.ui", "profilecompletionassist.cpp", @@ -57,14 +52,14 @@ QtcPlugin { "profilehighlighter.h", "profilehoverhandler.cpp", "profilehoverhandler.h", - "profilekeywords.cpp", - "profilekeywords.h", "qmakeparser.cpp", "qmakeparser.h", "qmakekitconfigwidget.cpp", "qmakekitconfigwidget.h", "qmakekitinformation.cpp", "qmakekitinformation.h", + "qmakeparser.cpp", + "qmakeparser.h", "qmakerunconfigurationfactory.cpp", "qmakerunconfigurationfactory.h", "qmakestep.cpp", @@ -72,12 +67,16 @@ QtcPlugin { "qmakestep.ui", "qt4buildconfiguration.cpp", "qt4buildconfiguration.h", + "qt4nodes.cpp", "qt4nodes.h", "qt4project.cpp", "qt4project.h", "qt4projectconfigwidget.cpp", "qt4projectconfigwidget.h", "qt4projectconfigwidget.ui", + "qt4projectmanager.cpp", + "qt4projectmanager.h", + "qt4projectmanager.qrc", "qt4projectmanager_global.h", "qt4projectmanagerconstants.h", "qt4projectmanagerplugin.cpp", @@ -94,22 +93,17 @@ QtcPlugin { "winceqtversion.h", "winceqtversionfactory.cpp", "winceqtversionfactory.h", - "buildconfigurationinfo.h", - "makestep.cpp", - "qt4nodes.cpp", - "qt4projectmanager.cpp", - "qt4projectmanager.h", - "customwidgetwizard/classdefinition.ui", - "customwidgetwizard/customwidgetpluginwizardpage.ui", - "customwidgetwizard/customwidgetwidgetswizardpage.ui", "customwidgetwizard/classdefinition.cpp", "customwidgetwizard/classdefinition.h", + "customwidgetwizard/classdefinition.ui", "customwidgetwizard/classlist.cpp", "customwidgetwizard/classlist.h", "customwidgetwizard/customwidgetpluginwizardpage.cpp", "customwidgetwizard/customwidgetpluginwizardpage.h", + "customwidgetwizard/customwidgetpluginwizardpage.ui", "customwidgetwizard/customwidgetwidgetswizardpage.cpp", "customwidgetwizard/customwidgetwidgetswizardpage.h", + "customwidgetwizard/customwidgetwidgetswizardpage.ui", "customwidgetwizard/customwidgetwizard.cpp", "customwidgetwizard/customwidgetwizard.h", "customwidgetwizard/customwidgetwizarddialog.cpp", @@ -136,8 +130,6 @@ QtcPlugin { "qt-desktop/simulatorqtversion.h", "qt-desktop/simulatorqtversionfactory.cpp", "qt-desktop/simulatorqtversionfactory.h", - "wizards/testwizardpage.ui", - "wizards/wizards.qrc", "wizards/abstractmobileapp.cpp", "wizards/abstractmobileapp.h", "wizards/abstractmobileappwizard.cpp", @@ -163,6 +155,9 @@ QtcPlugin { "wizards/html5appwizardpages.cpp", "wizards/html5appwizardpages.h", "wizards/html5appwizardsourcespage.ui", + "wizards/importwidget.cpp", + "wizards/importwidget.h", + "wizards/libraryparameters.cpp", "wizards/libraryparameters.h", "wizards/librarywizard.cpp", "wizards/librarywizard.h", @@ -201,19 +196,18 @@ QtcPlugin { "wizards/subdirsprojectwizarddialog.h", "wizards/targetsetuppage.cpp", "wizards/targetsetuppage.h", - "wizards/importwidget.cpp", - "wizards/importwidget.h", "wizards/testwizard.cpp", "wizards/testwizard.h", "wizards/testwizarddialog.cpp", "wizards/testwizarddialog.h", "wizards/testwizardpage.cpp", "wizards/testwizardpage.h", - "wizards/libraryparameters.cpp", + "wizards/testwizardpage.ui", + "wizards/wizards.qrc", "wizards/images/console.png", "wizards/images/gui.png", "wizards/images/html5app.png", "wizards/images/lib.png", - "wizards/images/qtquickapp.png" + "wizards/images/qtquickapp.png", ] } diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp index 20cbcff62b..9605936575 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp +++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp @@ -77,6 +77,7 @@ #include <texteditor/texteditoractionhandler.h> #include <texteditor/texteditorconstants.h> #include <texteditor/texteditorsettings.h> +#include <utils/hostosinfo.h> #include <utils/parameteraction.h> #ifdef WITH_TESTS @@ -152,11 +153,10 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString * addAutoReleasedObject(new Qt4BuildConfigurationFactory); addAutoReleasedObject(new Qt4RunConfigurationFactory); -#ifdef Q_OS_MAC - addAutoReleasedObject(new MacDesignerExternalEditor); -#else - addAutoReleasedObject(new DesignerExternalEditor); -#endif + if (Utils::HostOsInfo::isMacHost()) + addAutoReleasedObject(new MacDesignerExternalEditor); + else + addAutoReleasedObject(new DesignerExternalEditor); addAutoReleasedObject(new LinguistExternalEditor); addAutoReleasedObject(new DesktopQtVersionFactory); diff --git a/src/plugins/qt4projectmanager/qt4targetsetupwidget.cpp b/src/plugins/qt4projectmanager/qt4targetsetupwidget.cpp index e70200ca6d..13d3027c24 100644 --- a/src/plugins/qt4projectmanager/qt4targetsetupwidget.cpp +++ b/src/plugins/qt4projectmanager/qt4targetsetupwidget.cpp @@ -41,6 +41,7 @@ #include <utils/detailsbutton.h> #include <utils/detailswidget.h> +#include <utils/hostosinfo.h> #include <utils/pathchooser.h> #include <QCheckBox> @@ -92,9 +93,8 @@ Qt4TargetSetupWidget::Qt4TargetSetupWidget(ProjectExplorer::Kit *k, QWidget *w = new QWidget; m_newBuildsLayout = new QGridLayout; m_newBuildsLayout->setMargin(0); -#ifdef Q_OS_MAC - m_newBuildsLayout->setSpacing(0); -#endif + if (Utils::HostOsInfo::isMacHost()) + m_newBuildsLayout->setSpacing(0); w->setLayout(m_newBuildsLayout); layout->addWidget(w); diff --git a/src/plugins/qt4projectmanager/unconfiguredprojectpanel.cpp b/src/plugins/qt4projectmanager/unconfiguredprojectpanel.cpp index bff2fe53b2..affb09b46c 100644 --- a/src/plugins/qt4projectmanager/unconfiguredprojectpanel.cpp +++ b/src/plugins/qt4projectmanager/unconfiguredprojectpanel.cpp @@ -43,10 +43,12 @@ #include <projectexplorer/kitmanager.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorer.h> +#include <projectexplorer/session.h> #include <QLabel> #include <QVBoxLayout> #include <QPushButton> +#include <QDialogButtonBox> using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; @@ -115,9 +117,18 @@ TargetSetupPageWrapper::TargetSetupPageWrapper(ProjectExplorer::Project *project layout->addLayout(hbox); layout->setMargin(0); hbox->addStretch(); + + QDialogButtonBox *box = new QDialogButtonBox(this); + m_configureButton = new QPushButton(this); m_configureButton->setText(tr("Configure Project")); - hbox->addWidget(m_configureButton); + box->addButton(m_configureButton, QDialogButtonBox::AcceptRole); + + m_cancelButton = new QPushButton(this); + m_cancelButton->setText(tr("Cancel")); + box->addButton(m_cancelButton, QDialogButtonBox::RejectRole); + + hbox->addWidget(box); layout->addStretch(10); @@ -125,6 +136,8 @@ TargetSetupPageWrapper::TargetSetupPageWrapper(ProjectExplorer::Project *project connect(m_configureButton, SIGNAL(clicked()), this, SLOT(done())); + connect(m_cancelButton, SIGNAL(clicked()), + this, SLOT(cancel())); connect(m_targetSetupPage, SIGNAL(completeChanged()), this, SLOT(completeChanged())); connect(ProjectExplorer::KitManager::instance(), SIGNAL(defaultkitChanged()), @@ -184,6 +197,13 @@ void TargetSetupPageWrapper::keyReleaseEvent(QKeyEvent *event) } } +void TargetSetupPageWrapper::cancel() +{ + ProjectExplorer::ProjectExplorerPlugin::instance()->unloadProject(m_project); + if (ProjectExplorer::ProjectExplorerPlugin::instance()->session()->projects().isEmpty()) + Core::ICore::instance()->modeManager()->activateMode(Core::Constants::MODE_WELCOME); +} + void TargetSetupPageWrapper::done() { m_targetSetupPage->setupProject(m_project); diff --git a/src/plugins/qt4projectmanager/unconfiguredprojectpanel.h b/src/plugins/qt4projectmanager/unconfiguredprojectpanel.h index 022b4b91f0..d2f0564645 100644 --- a/src/plugins/qt4projectmanager/unconfiguredprojectpanel.h +++ b/src/plugins/qt4projectmanager/unconfiguredprojectpanel.h @@ -66,6 +66,7 @@ protected: void keyPressEvent(QKeyEvent *event); private slots: void done(); + void cancel(); void kitUpdated(ProjectExplorer::Kit *k); void updateNoteText(); void completeChanged(); @@ -74,6 +75,7 @@ private: Qt4Project *m_project; TargetSetupPage *m_targetSetupPage; QPushButton *m_configureButton; + QPushButton *m_cancelButton; }; } diff --git a/src/plugins/qt4projectmanager/wizards/abstractmobileapp.cpp b/src/plugins/qt4projectmanager/wizards/abstractmobileapp.cpp index 1e7185f8cd..5cb66b1d7a 100644 --- a/src/plugins/qt4projectmanager/wizards/abstractmobileapp.cpp +++ b/src/plugins/qt4projectmanager/wizards/abstractmobileapp.cpp @@ -279,8 +279,8 @@ QByteArray AbstractMobileApp::generateProFile(QString *errorMessage) const out << line << endl; }; - proFileContent.replace("../shared/" + DeploymentPriFileName.toAscii(), - DeploymentPriFileName.toAscii()); + proFileContent.replace("../shared/" + DeploymentPriFileName.toLatin1(), + DeploymentPriFileName.toLatin1()); return proFileContent; } @@ -437,7 +437,7 @@ QByteArray AbstractMobileApp::generateFile(int fileType, const QString versionLine = comment + sep + FileChecksum + sep + checkSumString + sep + FileStubVersion + sep + versionString + QLatin1Char('\x0A'); - return versionLine.toAscii() + data; + return versionLine.toLatin1() + data; } int AbstractMobileApp::makeStubVersion(int minor) diff --git a/src/plugins/qt4projectmanager/wizards/guiappwizard.cpp b/src/plugins/qt4projectmanager/wizards/guiappwizard.cpp index 23eb04d381..d75461aad3 100644 --- a/src/plugins/qt4projectmanager/wizards/guiappwizard.cpp +++ b/src/plugins/qt4projectmanager/wizards/guiappwizard.cpp @@ -149,7 +149,7 @@ static inline bool generateFormClass(const GuiAppParameters ¶ms, } } if (headerContents.isEmpty() || sourceContents.isEmpty()) { - *errorMessage = QString::fromAscii("Failed to obtain Designer plugin code generation service."); + *errorMessage = QString::fromLatin1("Failed to obtain Designer plugin code generation service."); return false; } diff --git a/src/plugins/qt4projectmanager/wizards/mobileappwizardpages.cpp b/src/plugins/qt4projectmanager/wizards/mobileappwizardpages.cpp index 2d3d164664..d523123ca0 100644 --- a/src/plugins/qt4projectmanager/wizards/mobileappwizardpages.cpp +++ b/src/plugins/qt4projectmanager/wizards/mobileappwizardpages.cpp @@ -153,7 +153,7 @@ public: saver.setAutoRemove(false); if (!saver.hasError()) saver.setResult(m_pixmap.save( - saver.file(), QFileInfo(m_iconPath).suffix().toAscii().constData())); + saver.file(), QFileInfo(m_iconPath).suffix().toLatin1().constData())); if (!saver.finalize()) { QMessageBox::critical(QApplication::activeWindow(), tr("File Error"), diff --git a/src/plugins/qt4projectmanager/wizards/qtquickapp.cpp b/src/plugins/qt4projectmanager/wizards/qtquickapp.cpp index ff60f2a076..9044a7f501 100644 --- a/src/plugins/qt4projectmanager/wizards/qtquickapp.cpp +++ b/src/plugins/qt4projectmanager/wizards/qtquickapp.cpp @@ -42,53 +42,6 @@ namespace Qt4ProjectManager { namespace Internal { -const QString qmldir(QLatin1String("qmldir")); -const QString qmldir_plugin(QLatin1String("plugin")); - -QmlModule::QmlModule(const QString &uri, const QFileInfo &rootDir, const QFileInfo &qmldir, - bool isExternal, QtQuickApp *qtQuickApp) - : uri(uri) - , rootDir(rootDir) - , qmldir(qmldir) - , isExternal(isExternal) - , qtQuickApp(qtQuickApp) -{} - -QString QmlModule::path(Path path) const -{ - switch (path) { - case Root: { - return rootDir.canonicalFilePath(); - } - case ContentDir: { - const QDir proFile(qtQuickApp->path(QtQuickApp::AppProPath)); - return proFile.relativeFilePath(qmldir.canonicalPath()); - } - case ContentBase: { - const QString localRoot = rootDir.canonicalFilePath() + QLatin1Char('/'); - QDir contentDir = qmldir.dir(); - contentDir.cdUp(); - const QString localContentDir = contentDir.canonicalPath(); - return localContentDir.right(localContentDir.length() - localRoot.length()); - } - case DeployedContentBase: { - const QString modulesDir = qtQuickApp->path(QtQuickApp::ModulesDir); - return modulesDir + QLatin1Char('/') + this->path(ContentBase); - } - default: qFatal("QmlModule::path() needs more work"); - } - return QString(); -} - -QmlCppPlugin::QmlCppPlugin(const QString &name, const QFileInfo &path, - const QmlModule *module, const QFileInfo &proFile) - : name(name) - , path(path) - , module(module) - , proFile(proFile) -{ -} - QtQuickApp::QtQuickApp() : AbstractMobileApp() , m_mainQmlMode(ModeGenerate) @@ -97,11 +50,6 @@ QtQuickApp::QtQuickApp() m_canSupportMeegoBooster = true; } -QtQuickApp::~QtQuickApp() -{ - clearModulesAndPlugins(); -} - void QtQuickApp::setComponentSet(ComponentSet componentSet) { m_componentSet = componentSet; @@ -124,47 +72,6 @@ QtQuickApp::Mode QtQuickApp::mainQmlMode() const return m_mainQmlMode; } -bool QtQuickApp::setExternalModules(const QStringList &uris, - const QStringList &importPaths) -{ - clearModulesAndPlugins(); - m_importPaths.clear(); - foreach (const QFileInfo &importPath, importPaths) { - if (!importPath.exists()) { - m_error = QCoreApplication::translate( - "Qt4ProjectManager::Internal::QtQuickApp", - "The QML import path '%1' cannot be found.") - .arg(QDir::toNativeSeparators(importPath.filePath())); - return false; - } else { - m_importPaths.append(importPath.canonicalFilePath()); - } - } - foreach (const QString &uri, uris) { - QString uriPath = uri; - uriPath.replace(QLatin1Char('.'), QLatin1Char('/')); - const int modulesCount = m_modules.count(); - foreach (const QFileInfo &importPath, m_importPaths) { - const QFileInfo qmlDirFile( - importPath.absoluteFilePath() + QLatin1Char('/') - + uriPath + QLatin1Char('/') + qmldir); - if (qmlDirFile.exists()) { - if (!addExternalModule(uri, importPath, qmlDirFile)) - return false; - break; - } - } - if (modulesCount == m_modules.count()) { // no module was added - m_error = QCoreApplication::translate( - "Qt4ProjectManager::Internal::QtQuickApp", - "The QML module '%1' cannot be found.").arg(uri); - return false; - } - } - m_error.clear(); - return true; -} - QString QtQuickApp::pathExtended(int fileType) const { const bool importQmlFile = m_mainQmlMode == ModeImport; @@ -199,7 +106,6 @@ QString QtQuickApp::pathExtended(int fileType) const case QmlDir: return pathBase + qmlSubDir; case QmlDirProFileRelative: return importQmlFile ? appProFilePath.relativeFilePath(m_mainQmlFile.canonicalPath()) : QString(qmlSubDir).remove(qmlSubDir.length() - 1, 1); - case ModulesDir: return QLatin1String("modules"); default: qFatal("QtQuickApp::pathExtended() needs more work"); } return QString(); @@ -220,14 +126,9 @@ bool QtQuickApp::adaptCurrentMainCppTemplateLine(QString &line) const { const QLatin1Char quote('"'); - if (line.contains(QLatin1String("// MAINQML"))) { + if (line.contains(QLatin1String("// MAINQML"))) insertParameter(line, quote + path(MainQmlDeployed) + quote); - } else if (line.contains(QLatin1String("// ADDIMPORTPATH"))) { - if (m_modules.isEmpty()) - return false; - else - insertParameter(line, quote + path(ModulesDir) + quote); - } + return true; } @@ -240,17 +141,7 @@ void QtQuickApp::handleCurrentProFileTemplateLine(const QString &line, QString nextLine = proFileTemplate.readLine(); // eats 'QML_IMPORT_PATH =' if (!nextLine.startsWith(QLatin1String("QML_IMPORT_PATH ="))) return; - - proFile << nextLine; - - const QLatin1String separator(" \\\n "); - const QDir proPath(path(AppProPath)); - foreach (const QString &importPath, m_importPaths) { - const QString relativePath = proPath.relativeFilePath(importPath); - proFile << separator << relativePath; - } - - proFile << endl; + proFile << nextLine << endl; } else if (line.contains(QLatin1String("# HARMATTAN_BOOSTABLE"))) { QString nextLine = proFileTemplate.readLine(); // eats '# CONFIG += qdeclarative-boostable' if (supportsMeegoBooster()) @@ -259,83 +150,6 @@ void QtQuickApp::handleCurrentProFileTemplateLine(const QString &line, } } -void QtQuickApp::clearModulesAndPlugins() -{ - qDeleteAll(m_modules); - m_modules.clear(); - qDeleteAll(m_cppPlugins); - m_cppPlugins.clear(); -} - -bool QtQuickApp::addCppPlugin(const QString &qmldirLine, QmlModule *module) -{ - const QStringList qmldirLineElements = - qmldirLine.split(QLatin1Char(' '), QString::SkipEmptyParts); - if (qmldirLineElements.count() < 2) { - m_error = QCoreApplication::translate( - "Qt4ProjectManager::Internal::QtQuickApp", - "Invalid '%1' entry in '%2' of module '%3'.") - .arg(qmldir_plugin).arg(qmldir).arg(module->uri); - return false; - } - const QString name = qmldirLineElements.at(1); - const QFileInfo path(module->qmldir.dir(), qmldirLineElements.value(2, QString())); - - // TODO: Add more magic to find a good .pro file.. - const QString proFileName = name + QLatin1String(".pro"); - const QFileInfo proFile_guess1(module->qmldir.dir(), proFileName); - const QFileInfo proFile_guess2(QString(module->qmldir.dir().absolutePath() + QLatin1String("/../")), - proFileName); - const QFileInfo proFile_guess3(module->qmldir.dir(), - QFileInfo(module->qmldir.path()).fileName() + QLatin1String(".pro")); - const QFileInfo proFile_guess4(proFile_guess3.absolutePath() + QLatin1String("/../") - + proFile_guess3.fileName()); - - QFileInfo foundProFile; - if (proFile_guess1.exists()) { - foundProFile = proFile_guess1.canonicalFilePath(); - } else if (proFile_guess2.exists()) { - foundProFile = proFile_guess2.canonicalFilePath(); - } else if (proFile_guess3.exists()) { - foundProFile = proFile_guess3.canonicalFilePath(); - } else if (proFile_guess4.exists()) { - foundProFile = proFile_guess4.canonicalFilePath(); - } else { - m_error = QCoreApplication::translate( - "Qt4ProjectManager::Internal::QtQuickApp", - "No .pro file for plugin '%1' can be found.").arg(name); - return false; - } - QmlCppPlugin *plugin = - new QmlCppPlugin(name, path, module, foundProFile); - m_cppPlugins.append(plugin); - module->cppPlugins.insert(name, plugin); - return true; -} - -bool QtQuickApp::addCppPlugins(QmlModule *module) -{ - QFile qmlDirFile(module->qmldir.absoluteFilePath()); - if (qmlDirFile.open(QIODevice::ReadOnly)) { - QTextStream in(&qmlDirFile); - QString line; - while (!(line = in.readLine()).isNull()) { - line = line.trimmed(); - if (line.startsWith(qmldir_plugin) && !addCppPlugin(line, module)) - return false; - }; - } - return true; -} - -bool QtQuickApp::addExternalModule(const QString &name, const QFileInfo &dir, - const QFileInfo &contentDir) -{ - QmlModule *module = new QmlModule(name, dir, contentDir, true, this); - m_modules.append(module); - return addCppPlugins(module); -} - #ifndef CREATORLESSTEST Core::GeneratedFiles QtQuickApp::generateFiles(QString *errorMessage) const { @@ -360,11 +174,6 @@ bool QtQuickApp::useExistingMainQml() const return !m_mainQmlFile.filePath().isEmpty(); } -const QList<QmlModule*> QtQuickApp::modules() const -{ - return m_modules; -} - QString QtQuickApp::appViewerBaseName() const { return QLatin1String(m_componentSet == QtQuick20Components ? @@ -454,9 +263,6 @@ QList<DeploymentFolder> QtQuickApp::deploymentFolders() const { QList<DeploymentFolder> result; result.append(DeploymentFolder(path(QmlDirProFileRelative), QLatin1String("qml"))); - foreach (const QmlModule *module, m_modules) - if (module->isExternal) - result.append(DeploymentFolder(module->path(QmlModule::ContentDir), module->path(QmlModule::DeployedContentBase))); return result; } diff --git a/src/plugins/qt4projectmanager/wizards/qtquickapp.h b/src/plugins/qt4projectmanager/wizards/qtquickapp.h index 98d9524807..33bd7a4a25 100644 --- a/src/plugins/qt4projectmanager/wizards/qtquickapp.h +++ b/src/plugins/qt4projectmanager/wizards/qtquickapp.h @@ -38,42 +38,6 @@ namespace Qt4ProjectManager { namespace Internal { -class QtQuickApp; -struct QmlCppPlugin; - -struct QmlModule -{ - enum Path { - // Example: Module "com.foo.bar" in "c:/modules/". - // "qmldir" file is in "c:/modules/com/foo/bar/". - // Application .pro file is "c:/app/app.pro". - Root, // "c:/modules/" (absolute) - ContentDir, // "../modules/com/foo/bar" (relative form .pro file) - ContentBase, // "com/foo/" - DeployedContentBase // "<qmlmodules>/com/foo" (on deploy target) - }; - - QmlModule(const QString &name, const QFileInfo &rootDir, const QFileInfo &qmldir, - bool isExternal, QtQuickApp *qtQuickApp); - QString path(Path path) const; - const QString uri; // "com.foo.bar" - const QFileInfo rootDir; // Location of "com/" - const QFileInfo qmldir; // 'qmldir' file. - const bool isExternal; // Either external or inside a source paths - const QtQuickApp *qtQuickApp; - QHash<QString, QmlCppPlugin *> cppPlugins; // Just as info. No ownership. -}; - -struct QmlCppPlugin -{ - QmlCppPlugin(const QString &name, const QFileInfo &path, - const QmlModule *module, const QFileInfo &proFile); - const QString name; // Original name - const QFileInfo path; // Plugin path where qmldir points to - const QmlModule *module; - const QFileInfo proFile; // .pro file for the plugin -}; - struct QtQuickAppGeneratedFileInfo : public AbstractGeneratedFileInfo { enum ExtendedFileType { @@ -102,7 +66,6 @@ public: AppViewerHOrigin, QmlDir, QmlDirProFileRelative, - ModulesDir, MainPageQml, MainPageQmlOrigin }; @@ -119,14 +82,12 @@ public: }; QtQuickApp(); - virtual ~QtQuickApp(); void setComponentSet(ComponentSet componentSet); ComponentSet componentSet() const; void setMainQml(Mode mode, const QString &file = QString()); Mode mainQmlMode() const; - bool setExternalModules(const QStringList &uris, const QStringList &importPaths); #ifndef CREATORLESSTEST virtual Core::GeneratedFiles generateFiles(QString *errorMessage) const; @@ -134,7 +95,6 @@ public: bool generateFiles(QString *errorMessage) const; #endif // CREATORLESSTEST bool useExistingMainQml() const; - const QList<QmlModule*> modules() const; static const int StubVersion; @@ -157,18 +117,10 @@ private: QList<AbstractGeneratedFileInfo> updateableFiles(const QString &mainProFile) const; QList<DeploymentFolder> deploymentFolders() const; - bool addExternalModule(const QString &uri, const QFileInfo &dir, - const QFileInfo &contentDir); - bool addCppPlugins(QmlModule *module); - bool addCppPlugin(const QString &qmldirLine, QmlModule *module); - void clearModulesAndPlugins(); QString componentSetDir(ComponentSet componentSet) const; QFileInfo m_mainQmlFile; Mode m_mainQmlMode; - QStringList m_importPaths; - QList<QmlModule *> m_modules; - QList<QmlCppPlugin *> m_cppPlugins; ComponentSet m_componentSet; }; diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index ec781d717a..97499cfcda 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -47,6 +47,7 @@ #include <utils/persistentsettings.h> #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <utils/synchronousprocess.h> #include <QDir> @@ -57,6 +58,7 @@ using namespace QtSupport; using namespace QtSupport::Internal; +using namespace Utils; static const char QTVERSIONID[] = "Id"; static const char QTVERSIONNAME[] = "Name"; @@ -163,7 +165,7 @@ int BaseQtVersion::getUniqueId() return QtVersionManager::instance()->getUniqueId(); } -BaseQtVersion::BaseQtVersion(const Utils::FileName &qmakeCommand, bool isAutodetected, const QString &autodetectionSource) +BaseQtVersion::BaseQtVersion(const FileName &qmakeCommand, bool isAutodetected, const QString &autodetectionSource) : m_id(getUniqueId()), m_isAutodetected(isAutodetected), m_autodetectionSource(autodetectionSource), @@ -203,10 +205,10 @@ BaseQtVersion::BaseQtVersion() m_hasDocumentation(false), m_qmakeIsExecutable(true) { - ctor(Utils::FileName()); + ctor(FileName()); } -void BaseQtVersion::ctor(const Utils::FileName &qmakePath) +void BaseQtVersion::ctor(const FileName &qmakePath) { m_qmakeCommand = qmakePath; m_designerCommand.clear(); @@ -224,7 +226,7 @@ BaseQtVersion::~BaseQtVersion() { } -QString BaseQtVersion::defaultDisplayName(const QString &versionString, const Utils::FileName &qmakePath, +QString BaseQtVersion::defaultDisplayName(const QString &versionString, const FileName &qmakePath, bool fromPath) { QString location; @@ -317,7 +319,7 @@ QList<ProjectExplorer::Task> BaseQtVersion::validateKit(const ProjectExplorer::K version->displayName(), qtAbiString); result << ProjectExplorer::Task(ProjectExplorer::Task::Error, - message, Utils::FileName(), -1, + message, FileName(), -1, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); } // Abi mismatch return result; @@ -340,7 +342,7 @@ void BaseQtVersion::fromMap(const QVariantMap &map) QString string = map.value(QLatin1String(QTVERSIONQMAKEPATH)).toString(); if (string.startsWith(QLatin1Char('~'))) string.remove(0, 1).prepend(QDir::homePath()); - ctor(Utils::FileName::fromString(string)); + ctor(FileName::fromString(string)); } QVariantMap BaseQtVersion::toMap() const @@ -399,9 +401,9 @@ QStringList BaseQtVersion::warningReason() const return ret; } -ProjectExplorer::ToolChain *BaseQtVersion::preferredToolChain(const Utils::FileName &ms) const +ProjectExplorer::ToolChain *BaseQtVersion::preferredToolChain(const FileName &ms) const { - const Utils::FileName spec = ms.isEmpty() ? mkspec() : ms; + const FileName spec = ms.isEmpty() ? mkspec() : ms; QList<ProjectExplorer::ToolChain *> tcList = ProjectExplorer::ToolChainManager::instance()->toolChains(); ProjectExplorer::ToolChain *possibleTc = 0; foreach (ProjectExplorer::ToolChain *tc, tcList) { @@ -415,7 +417,7 @@ ProjectExplorer::ToolChain *BaseQtVersion::preferredToolChain(const Utils::FileN return possibleTc; } -Utils::FileName BaseQtVersion::qmakeCommand() const +FileName BaseQtVersion::qmakeCommand() const { return m_qmakeCommand; } @@ -570,10 +572,10 @@ void BaseQtVersion::updateSourcePath() const } } } - m_sourcePath = Utils::FileName::fromUserInput(sourcePath); + m_sourcePath = FileName::fromUserInput(sourcePath); } -Utils::FileName BaseQtVersion::sourcePath() const +FileName BaseQtVersion::sourcePath() const { updateSourcePath(); return m_sourcePath; @@ -652,46 +654,43 @@ QString BaseQtVersion::findQtBinary(Binaries binary) const QStringList possibleCommands; switch (binary) { case QmlScene: { -#if defined(Q_OS_WIN) - possibleCommands << QLatin1String("qmlscene.exe"); -#else - possibleCommands << QLatin1String("qmlscene"); -#endif + if (HostOsInfo::isWindowsHost()) + possibleCommands << QLatin1String("qmlscene.exe"); + else + possibleCommands << QLatin1String("qmlscene"); } case QmlViewer: { -#if defined(Q_OS_WIN) - possibleCommands << QLatin1String("qmlviewer.exe"); -#elif defined(Q_OS_MAC) - possibleCommands << QLatin1String("QMLViewer.app/Contents/MacOS/QMLViewer"); -#else - possibleCommands << QLatin1String("qmlviewer"); -#endif + if (HostOsInfo::isWindowsHost()) + possibleCommands << QLatin1String("qmlviewer.exe"); + else if (HostOsInfo::isMacHost()) + possibleCommands << QLatin1String("QMLViewer.app/Contents/MacOS/QMLViewer"); + else + possibleCommands << QLatin1String("qmlviewer"); } break; case Designer: -#if defined(Q_OS_WIN) - possibleCommands << QLatin1String("designer.exe"); -#elif defined(Q_OS_MAC) - possibleCommands << QLatin1String("Designer.app/Contents/MacOS/Designer"); -#else - possibleCommands << QLatin1String("designer"); -#endif + if (HostOsInfo::isWindowsHost()) + possibleCommands << QLatin1String("designer.exe"); + else if (HostOsInfo::isMacHost()) + possibleCommands << QLatin1String("Designer.app/Contents/MacOS/Designer"); + else + possibleCommands << QLatin1String("designer"); break; case Linguist: -#if defined(Q_OS_WIN) - possibleCommands << QLatin1String("linguist.exe"); -#elif defined(Q_OS_MAC) - possibleCommands << QLatin1String("Linguist.app/Contents/MacOS/Linguist"); -#else - possibleCommands << QLatin1String("linguist"); -#endif + if (HostOsInfo::isWindowsHost()) + possibleCommands << QLatin1String("linguist.exe"); + else if (HostOsInfo::isMacHost()) + possibleCommands << QLatin1String("Linguist.app/Contents/MacOS/Linguist"); + else + possibleCommands << QLatin1String("linguist"); break; case Uic: -#ifdef Q_OS_WIN - possibleCommands << QLatin1String("uic.exe"); -#else - possibleCommands << QLatin1String("uic-qt4") << QLatin1String("uic4") << QLatin1String("uic"); -#endif + if (HostOsInfo::isWindowsHost()) { + possibleCommands << QLatin1String("uic.exe"); + } else { + possibleCommands << QLatin1String("uic-qt4") << QLatin1String("uic4") + << QLatin1String("uic"); + } break; default: Q_ASSERT(false); @@ -726,13 +725,13 @@ void BaseQtVersion::updateMkspec() const if (m_mkspecFullPath.isEmpty()) return; - Utils::FileName baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo()); + FileName baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo()); if (m_mkspec.isChildOf(baseMkspecDir)) { m_mkspec = m_mkspec.relativeChildPath(baseMkspecDir); // qDebug() << "Setting mkspec to"<<mkspec; } else { - Utils::FileName sourceMkSpecPath = sourcePath().appendPath(QLatin1String("mkspecs")); + FileName sourceMkSpecPath = sourcePath().appendPath(QLatin1String("mkspecs")); if (m_mkspec.isChildOf(sourceMkSpecPath)) { m_mkspec = m_mkspec.relativeChildPath(sourceMkSpecPath); } else { @@ -750,7 +749,7 @@ void BaseQtVersion::ensureMkSpecParsed() const if (mkspecPath().isEmpty()) return; - QMakeGlobals option; + ProFileGlobals option; option.setProperties(versionInfo()); ProMessageHandler msgHandler(true); ProFileCacheManager::instance()->incRefCount(); @@ -783,22 +782,22 @@ void BaseQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const m_mkspecValues.insert(declarativeBins, evaluator->value(declarativeBins)); } -Utils::FileName BaseQtVersion::mkspec() const +FileName BaseQtVersion::mkspec() const { updateMkspec(); return m_mkspec; } -Utils::FileName BaseQtVersion::mkspecFor(ProjectExplorer::ToolChain *tc) const +FileName BaseQtVersion::mkspecFor(ProjectExplorer::ToolChain *tc) const { Utils::FileName versionSpec = mkspec(); if (!tc) return versionSpec; - const QList<Utils::FileName> tcSpecList = tc->suggestedMkspecList(); + const QList<FileName> tcSpecList = tc->suggestedMkspecList(); if (tcSpecList.contains(versionSpec)) return versionSpec; - foreach (const Utils::FileName &tcSpec, tcSpecList) { + foreach (const FileName &tcSpec, tcSpecList) { if (hasMkspec(tcSpec)) return tcSpec; } @@ -806,13 +805,13 @@ Utils::FileName BaseQtVersion::mkspecFor(ProjectExplorer::ToolChain *tc) const return versionSpec; } -Utils::FileName BaseQtVersion::mkspecPath() const +FileName BaseQtVersion::mkspecPath() const { updateMkspec(); return m_mkspecFullPath; } -bool BaseQtVersion::hasMkspec(const Utils::FileName &spec) const +bool BaseQtVersion::hasMkspec(const FileName &spec) const { updateVersionInfo(); QFileInfo fi; @@ -867,7 +866,7 @@ void BaseQtVersion::updateVersionInfo() const m_hasQmlDebuggingLibrary = false; m_hasQmlObserver = false; - if (!queryQMakeVariables(qmakeCommand(), &m_versionInfo, &m_qmakeIsExecutable)) + if (!queryQMakeVariables(qmakeCommand(), qmakeRunEnvironment(), &m_versionInfo, &m_qmakeIsExecutable)) return; const QString qtInstallData = qmakeProperty("QT_INSTALL_DATA"); @@ -966,12 +965,11 @@ QString BaseQtVersion::demosPath() const QString BaseQtVersion::frameworkInstallPath() const { -#ifdef Q_OS_MAC - updateVersionInfo(); - return m_versionInfo.value(QLatin1String("QT_INSTALL_LIBS")); -#else + if (HostOsInfo::isMacHost()) { + updateVersionInfo(); + return m_versionInfo.value(QLatin1String("QT_INSTALL_LIBS")); + } return QString(); -#endif } bool BaseQtVersion::hasExamples() const @@ -994,13 +992,23 @@ QList<ProjectExplorer::HeaderPath> BaseQtVersion::systemHeaderPathes(const Proje return result; } -void BaseQtVersion::addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const +void BaseQtVersion::addToEnvironment(const ProjectExplorer::Kit *k, Environment &env) const { Q_UNUSED(k); env.set(QLatin1String("QTDIR"), QDir::toNativeSeparators(qmakeProperty("QT_HOST_DATA"))); env.prependOrSetPath(qmakeProperty("QT_HOST_BINS")); } +// Some Qt versions may require environment settings for qmake to work +// +// One such example is Blackberry which for some reason decided to always use the same +// qmake and use environment variables embedded in their mkspecs to make that point to +// the different Qt installations. +Utils::Environment BaseQtVersion::qmakeRunEnvironment() const +{ + return Utils::Environment::systemEnvironment(); +} + bool BaseQtVersion::hasGdbDebuggingHelper() const { updateVersionInfo(); @@ -1038,10 +1046,10 @@ bool BaseQtVersion::hasQmlObserver() const return m_hasQmlObserver; } -Utils::Environment BaseQtVersion::qmlToolsEnvironment() const +Environment BaseQtVersion::qmlToolsEnvironment() const { // FIXME: This seems broken! - Utils::Environment environment = Utils::Environment::systemEnvironment(); + Environment environment = Environment::systemEnvironment(); #if 0 // FIXME: Fix this! addToEnvironment(environment); #endif @@ -1127,7 +1135,7 @@ QList<ProjectExplorer::Task> BaseQtVersion::reportIssuesImpl(const QString &proF if (!isValid()) { //: %1: Reason for being invalid const QString msg = QCoreApplication::translate("Qt4ProjectManager::QtVersion", "The Qt version is invalid: %1").arg(invalidReason()); - results.append(ProjectExplorer::Task(ProjectExplorer::Task::Error, msg, Utils::FileName(), -1, + results.append(ProjectExplorer::Task(ProjectExplorer::Task::Error, msg, FileName(), -1, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM))); } @@ -1137,7 +1145,7 @@ QList<ProjectExplorer::Task> BaseQtVersion::reportIssuesImpl(const QString &proF //: %1: Path to qmake executable const QString msg = QCoreApplication::translate("Qt4ProjectManager::QtVersion", "The qmake command \"%1\" was not found or is not executable.").arg(qmakeCommand().toUserOutput()); - results.append(ProjectExplorer::Task(ProjectExplorer::Task::Error, msg, Utils::FileName(), -1, + results.append(ProjectExplorer::Task(ProjectExplorer::Task::Error, msg, FileName(), -1, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM))); } @@ -1148,13 +1156,13 @@ QList<ProjectExplorer::Task> BaseQtVersion::reportIssuesImpl(const QString &proF if ((tmpBuildDir.startsWith(sourcePath)) && (tmpBuildDir != sourcePath)) { const QString msg = QCoreApplication::translate("Qt4ProjectManager::QtVersion", "Qmake does not support build directories below the source directory."); - results.append(ProjectExplorer::Task(ProjectExplorer::Task::Warning, msg, Utils::FileName(), -1, + results.append(ProjectExplorer::Task(ProjectExplorer::Task::Warning, msg, FileName(), -1, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM))); } else if (tmpBuildDir.count(slash) != sourcePath.count(slash) && qtVersion() < QtVersionNumber(4,8, 0)) { const QString msg = QCoreApplication::translate("Qt4ProjectManager::QtVersion", "The build directory needs to be at the same level as the source directory."); - results.append(ProjectExplorer::Task(ProjectExplorer::Task::Warning, msg, Utils::FileName(), -1, + results.append(ProjectExplorer::Task(ProjectExplorer::Task::Warning, msg, FileName(), -1, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM))); } @@ -1169,23 +1177,19 @@ BaseQtVersion::reportIssues(const QString &proFile, const QString &buildDir) con return results; } -ProjectExplorer::IOutputParser *BaseQtVersion::createOutputParser() const -{ - return new ProjectExplorer::GnuMakeParser; -} - QtConfigWidget *BaseQtVersion::createConfigurationWidget() const { return 0; } -bool BaseQtVersion::queryQMakeVariables(const Utils::FileName &binary, QHash<QString, QString> *versionInfo) +bool BaseQtVersion::queryQMakeVariables(const FileName &binary, const Utils::Environment &env, + QHash<QString, QString> *versionInfo) { bool qmakeIsExecutable; - return BaseQtVersion::queryQMakeVariables(binary, versionInfo, &qmakeIsExecutable); + return BaseQtVersion::queryQMakeVariables(binary, env, versionInfo, &qmakeIsExecutable); } -static QByteArray runQmakeQuery(const Utils::FileName &binary, const Utils::Environment &env, +static QByteArray runQmakeQuery(const FileName &binary, const Environment &env, bool *isExecutable) { const int timeOutMS = 30000; // Might be slow on some machines. @@ -1200,7 +1204,7 @@ static QByteArray runQmakeQuery(const Utils::FileName &binary, const Utils::Envi return QByteArray(); } if (!process.waitForFinished(timeOutMS)) { - Utils::SynchronousProcess::stopProcess(process); + SynchronousProcess::stopProcess(process); *isExecutable = true; qWarning("Timeout running '%s' (%dms).", qPrintable(binary.toUserOutput()), timeOutMS); return QByteArray(); @@ -1215,8 +1219,8 @@ static QByteArray runQmakeQuery(const Utils::FileName &binary, const Utils::Envi return process.readAllStandardOutput(); } -bool BaseQtVersion::queryQMakeVariables(const Utils::FileName &binary, QHash<QString, QString> *versionInfo, - bool *qmakeIsExecutable) +bool BaseQtVersion::queryQMakeVariables(const FileName &binary, const Environment &env, + QHash<QString, QString> *versionInfo, bool *qmakeIsExecutable) { const QFileInfo qmake = binary.toFileInfo(); *qmakeIsExecutable = qmake.exists() && qmake.isExecutable() && !qmake.isDir(); @@ -1224,7 +1228,7 @@ bool BaseQtVersion::queryQMakeVariables(const Utils::FileName &binary, QHash<QSt return false; QByteArray output; - output = runQmakeQuery(binary, Utils::Environment::systemEnvironment(), qmakeIsExecutable); + output = runQmakeQuery(binary, env, qmakeIsExecutable); if (output.isNull() && !qmakeIsExecutable) { // Note: Don't rerun if we were able to execute the binary before. @@ -1237,9 +1241,9 @@ bool BaseQtVersion::queryQMakeVariables(const Utils::FileName &binary, QHash<QSt foreach (ProjectExplorer::ToolChain *tc, tcList) { if (!abiList.contains(tc->targetAbi())) continue; - Utils::Environment env = Utils::Environment::systemEnvironment(); - tc->addToEnvironment(env); - output = runQmakeQuery(binary, env, qmakeIsExecutable); + Environment realEnv = env; + tc->addToEnvironment(realEnv); + output = runQmakeQuery(binary, realEnv, qmakeIsExecutable); if (qmakeIsExecutable) break; } @@ -1278,19 +1282,19 @@ bool BaseQtVersion::queryQMakeVariables(const Utils::FileName &binary, QHash<QSt return true; } -Utils::FileName BaseQtVersion::mkspecDirectoryFromVersionInfo(const QHash<QString, QString> &versionInfo) +FileName BaseQtVersion::mkspecDirectoryFromVersionInfo(const QHash<QString, QString> &versionInfo) { QString dataDir = qmakeProperty(versionInfo, "QT_HOST_DATA"); if (dataDir.isEmpty()) - return Utils::FileName(); - return Utils::FileName::fromUserInput(dataDir + QLatin1String("/mkspecs")); + return FileName(); + return FileName::fromUserInput(dataDir + QLatin1String("/mkspecs")); } -Utils::FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<QString, QString> &versionInfo) +FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<QString, QString> &versionInfo) { - Utils::FileName baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo); + FileName baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo); if (baseMkspecDir.isEmpty()) - return Utils::FileName(); + return FileName(); bool qt5 = false; QString theSpec = qmakeProperty(versionInfo, "QMAKE_XSPEC"); @@ -1299,67 +1303,66 @@ Utils::FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<QString, QStrin else qt5 = true; - Utils::FileName mkspecFullPath = baseMkspecDir; + FileName mkspecFullPath = baseMkspecDir; mkspecFullPath.appendPath(theSpec); // qDebug() << "default mkspec is located at" << mkspecFullPath; -#ifdef Q_OS_WIN - if (!qt5) { - QFile f2(mkspecFullPath.toString() + QLatin1String("/qmake.conf")); - if (f2.exists() && f2.open(QIODevice::ReadOnly)) { - while (!f2.atEnd()) { - QByteArray line = f2.readLine(); - if (line.startsWith("QMAKESPEC_ORIGINAL")) { - const QList<QByteArray> &temp = line.split('='); - if (temp.size() == 2) { - QString possibleFullPath = QString::fromLocal8Bit(temp.at(1).trimmed().constData()); - // We sometimes get a mix of different slash styles here... - possibleFullPath = possibleFullPath.replace(QLatin1Char('\\'), QLatin1Char('/')); - if (QFileInfo(possibleFullPath).exists()) // Only if the path exists - mkspecFullPath = Utils::FileName::fromUserInput(possibleFullPath); + if (HostOsInfo::isWindowsHost()) { + if (!qt5) { + QFile f2(mkspecFullPath.toString() + QLatin1String("/qmake.conf")); + if (f2.exists() && f2.open(QIODevice::ReadOnly)) { + while (!f2.atEnd()) { + QByteArray line = f2.readLine(); + if (line.startsWith("QMAKESPEC_ORIGINAL")) { + const QList<QByteArray> &temp = line.split('='); + if (temp.size() == 2) { + QString possibleFullPath = QString::fromLocal8Bit(temp.at(1).trimmed().constData()); + // We sometimes get a mix of different slash styles here... + possibleFullPath = possibleFullPath.replace(QLatin1Char('\\'), QLatin1Char('/')); + if (QFileInfo(possibleFullPath).exists()) // Only if the path exists + mkspecFullPath = FileName::fromUserInput(possibleFullPath); + } + break; } - break; } + f2.close(); } - f2.close(); } - } -#else -# ifdef Q_OS_MAC - QFile f2(mkspecFullPath.toString() + QLatin1String("/qmake.conf")); - if (f2.exists() && f2.open(QIODevice::ReadOnly)) { - while (!f2.atEnd()) { - QByteArray line = f2.readLine(); - if (line.startsWith("MAKEFILE_GENERATOR")) { - const QList<QByteArray> &temp = line.split('='); - if (temp.size() == 2) { - const QByteArray &value = temp.at(1); - if (value.contains("XCODE")) { - // we don't want to generate xcode projects... -// qDebug() << "default mkspec is xcode, falling back to g++"; - return baseMkspecDir.appendPath(QLatin1String("macx-g++")); + } else { + if (HostOsInfo::isMacHost()) { + QFile f2(mkspecFullPath.toString() + QLatin1String("/qmake.conf")); + if (f2.exists() && f2.open(QIODevice::ReadOnly)) { + while (!f2.atEnd()) { + QByteArray line = f2.readLine(); + if (line.startsWith("MAKEFILE_GENERATOR")) { + const QList<QByteArray> &temp = line.split('='); + if (temp.size() == 2) { + const QByteArray &value = temp.at(1); + if (value.contains("XCODE")) { + // we don't want to generate xcode projects... + // qDebug() << "default mkspec is xcode, falling back to g++"; + return baseMkspecDir.appendPath(QLatin1String("macx-g++")); + } + } + break; } } - break; + f2.close(); } } - f2.close(); - } -# endif - if (!qt5) { - //resolve mkspec link - QString rspec = mkspecFullPath.toFileInfo().readLink(); - if (!rspec.isEmpty()) - mkspecFullPath = Utils::FileName::fromUserInput( - QDir(baseMkspecDir.toString()).absoluteFilePath(rspec)); + if (!qt5) { + //resolve mkspec link + QString rspec = mkspecFullPath.toFileInfo().readLink(); + if (!rspec.isEmpty()) + mkspecFullPath = FileName::fromUserInput( + QDir(baseMkspecDir.toString()).absoluteFilePath(rspec)); + } } -#endif - return mkspecFullPath; } -Utils::FileName BaseQtVersion::qtCorePath(const QHash<QString,QString> &versionInfo, const QString &versionString) +FileName BaseQtVersion::qtCorePath(const QHash<QString,QString> &versionInfo, const QString &versionString) { QStringList dirs; dirs << qmakeProperty(versionInfo, "QT_INSTALL_LIBS") @@ -1377,7 +1380,7 @@ Utils::FileName BaseQtVersion::qtCorePath(const QHash<QString,QString> &versionI && file.startsWith(QLatin1String("QtCore")) && file.endsWith(QLatin1String(".framework"))) { // handle Framework - Utils::FileName lib(info); + FileName lib(info); lib.appendPath(file.left(file.lastIndexOf(QLatin1Char('.')))); return lib; } @@ -1393,18 +1396,18 @@ Utils::FileName BaseQtVersion::qtCorePath(const QHash<QString,QString> &versionI || file.endsWith(QString::fromLatin1(".so.") + versionString) || file.endsWith(QLatin1String(".so")) || file.endsWith(QLatin1Char('.') + versionString + QLatin1String(".dylib"))) - return Utils::FileName(info); + return FileName(info); } } } } // Return path to first static library found: if (!staticLibs.isEmpty()) - return Utils::FileName(staticLibs.at(0)); - return Utils::FileName(); + return FileName(staticLibs.at(0)); + return FileName(); } -QList<ProjectExplorer::Abi> BaseQtVersion::qtAbisFromLibrary(const Utils::FileName &coreLibrary) +QList<ProjectExplorer::Abi> BaseQtVersion::qtAbisFromLibrary(const FileName &coreLibrary) { return ProjectExplorer::Abi::abisOfBinary(coreLibrary); } diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h index f9fc3ff573..261ff50e10 100644 --- a/src/plugins/qtsupport/baseqtversion.h +++ b/src/plugins/qtsupport/baseqtversion.h @@ -131,6 +131,7 @@ public: static QString qmakeProperty(const QHash<QString,QString> &versionInfo, const QByteArray &name); QString qmakeProperty(const QByteArray &name) const; virtual void addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const; + virtual Utils::Environment qmakeRunEnvironment() const; virtual Utils::FileName sourcePath() const; // used by QtUiCodeModelSupport @@ -185,10 +186,11 @@ public: /// warnings and finally info items. QList<ProjectExplorer::Task> reportIssues(const QString &proFile, const QString &buildDir) const; - virtual ProjectExplorer::IOutputParser *createOutputParser() const; - - static bool queryQMakeVariables(const Utils::FileName &binary, QHash<QString, QString> *versionInfo); - static bool queryQMakeVariables(const Utils::FileName &binary, QHash<QString, QString> *versionInfo, bool *qmakeIsExecutable); + static bool queryQMakeVariables(const Utils::FileName &binary, const Utils::Environment &env, + QHash<QString, QString> *versionInfo); + static bool queryQMakeVariables(const Utils::FileName &binary, const Utils::Environment &env, + QHash<QString, QString> *versionInfo, + bool *qmakeIsExecutable); static Utils::FileName mkspecDirectoryFromVersionInfo(const QHash<QString, QString> &versionInfo); static Utils::FileName mkspecFromVersionInfo(const QHash<QString, QString> &versionInfo); diff --git a/src/plugins/qtsupport/customexecutablerunconfiguration.cpp b/src/plugins/qtsupport/customexecutablerunconfiguration.cpp index a21288ca34..8848ee74cf 100644 --- a/src/plugins/qtsupport/customexecutablerunconfiguration.cpp +++ b/src/plugins/qtsupport/customexecutablerunconfiguration.cpp @@ -54,14 +54,14 @@ using namespace QtSupport; using namespace QtSupport::Internal; namespace { -const char * const CUSTOM_EXECUTABLE_ID("ProjectExplorer.CustomExecutableRunConfiguration"); - -const char * const EXECUTABLE_KEY("ProjectExplorer.CustomExecutableRunConfiguration.Executable"); -const char * const ARGUMENTS_KEY("ProjectExplorer.CustomExecutableRunConfiguration.Arguments"); -const char * const WORKING_DIRECTORY_KEY("ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory"); -const char * const USE_TERMINAL_KEY("ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal"); -const char * const USER_ENVIRONMENT_CHANGES_KEY("ProjectExplorer.CustomExecutableRunConfiguration.UserEnvironmentChanges"); -const char * const BASE_ENVIRONMENT_BASE_KEY("ProjectExplorer.CustomExecutableRunConfiguration.BaseEnvironmentBase"); +const char CUSTOM_EXECUTABLE_ID[] = "ProjectExplorer.CustomExecutableRunConfiguration"; + +const char EXECUTABLE_KEY[] = "ProjectExplorer.CustomExecutableRunConfiguration.Executable"; +const char ARGUMENTS_KEY[] = "ProjectExplorer.CustomExecutableRunConfiguration.Arguments"; +const char WORKING_DIRECTORY_KEY[] = "ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory"; +const char USE_TERMINAL_KEY[] = "ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal"; +const char USER_ENVIRONMENT_CHANGES_KEY[] = "ProjectExplorer.CustomExecutableRunConfiguration.UserEnvironmentChanges"; +const char BASE_ENVIRONMENT_BASE_KEY[] = "ProjectExplorer.CustomExecutableRunConfiguration.BaseEnvironmentBase"; } void CustomExecutableRunConfiguration::ctor() diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp index fbc5a159dd..2d562ab065 100644 --- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp +++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp @@ -51,7 +51,7 @@ #include <QMutex> #include <QThread> #include <QMutexLocker> -#include <QWeakPointer> +#include <QPointer> #include <QWaitCondition> #include <QDir> #include <QBuffer> @@ -71,14 +71,16 @@ #include <QDeclarativeContext> #include <QDesktopServices> +using namespace Utils; + namespace QtSupport { namespace Internal { const char C_FALLBACK_ROOT[] = "ProjectsFallbackRoot"; -QWeakPointer<ExamplesListModel> &examplesModelStatic() +QPointer<ExamplesListModel> &examplesModelStatic() { - static QWeakPointer<ExamplesListModel> s_examplesModel; + static QPointer<ExamplesListModel> s_examplesModel; return s_examplesModel; } @@ -175,7 +177,7 @@ public: Q_UNUSED(size) QMutexLocker lock(&m_mutex); - QUrl url = QUrl::fromEncoded(id.toAscii()); + QUrl url = QUrl::fromEncoded(id.toLatin1()); if (!m_fetcher.asynchronousFetchData(url)) return QImage(); @@ -336,9 +338,9 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI .arg(nativeProjectDir)); lay->addWidget(descrLbl, 0, 0, 1, 2); QLabel *txt = new QLabel(tr("&Location:")); - Utils::PathChooser *chooser = new Utils::PathChooser; + PathChooser *chooser = new PathChooser; txt->setBuddy(chooser); - chooser->setExpectedKind(Utils::PathChooser::ExistingDirectory); + chooser->setExpectedKind(PathChooser::ExistingDirectory); QSettings *settings = Core::ICore::settings(); chooser->setPath(settings->value(QString::fromLatin1(C_FALLBACK_ROOT), Core::DocumentManager::projectsDirectory()).toString()); @@ -367,15 +369,18 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI } else { QString error; QString targetDir = destBaseDir + QLatin1Char('/') + exampleDirName; - if (Utils::FileUtils::copyRecursively(projectDir, targetDir, &error)) { + if (FileUtils::copyRecursively(FileName::fromString(projectDir), + FileName::fromString(targetDir), &error)) { // set vars to new location const QStringList::Iterator end = filesToOpen.end(); for (QStringList::Iterator it = filesToOpen.begin(); it != end; ++it) it->replace(projectDir, targetDir); foreach (const QString &dependency, dependencies) { - QString dirName = QDir(dependency).dirName(); - if (!Utils::FileUtils::copyRecursively(dependency, targetDir + QDir::separator()+ dirName, &error)) { + FileName targetFile = FileName::fromString(targetDir); + targetFile.appendPath(QDir(dependency).dirName()); + if (!FileUtils::copyRecursively(FileName::fromString(dependency), targetFile, + &error)) { QMessageBox::warning(Core::ICore::mainWindow(), tr("Cannot Copy Project"), error); // do not fail, just warn; } diff --git a/src/plugins/qtsupport/profilereader.cpp b/src/plugins/qtsupport/profilereader.cpp index c37e629a1f..5b909d5882 100644 --- a/src/plugins/qtsupport/profilereader.cpp +++ b/src/plugins/qtsupport/profilereader.cpp @@ -39,8 +39,10 @@ using namespace QtSupport; static QString format(const QString &fileName, int lineNo, const QString &msg) { - if (lineNo) + if (lineNo > 0) return QString::fromLatin1("%1(%2): %3").arg(fileName, QString::number(lineNo), msg); + else if (lineNo) + return QString::fromLatin1("%1: %3").arg(fileName, msg); else return msg; } @@ -65,7 +67,7 @@ void ProMessageHandler::fileMessage(const QString &) } -ProFileReader::ProFileReader(QMakeGlobals *option) +ProFileReader::ProFileReader(ProFileGlobals *option) : QMakeParser(ProFileCacheManager::instance()->cache(), this) , ProFileEvaluator(option, this, this) , m_ignoreLevel(0) diff --git a/src/plugins/qtsupport/profilereader.h b/src/plugins/qtsupport/profilereader.h index 0e6ca9b098..f51b71e0fd 100644 --- a/src/plugins/qtsupport/profilereader.h +++ b/src/plugins/qtsupport/profilereader.h @@ -70,7 +70,7 @@ class QTSUPPORT_EXPORT ProFileReader : public ProMessageHandler, public QMakePar Q_OBJECT public: - ProFileReader(QMakeGlobals *option); + ProFileReader(ProFileGlobals *option); ~ProFileReader(); QList<ProFile*> includeFiles() const; diff --git a/src/plugins/qtsupport/qmldumptool.cpp b/src/plugins/qtsupport/qmldumptool.cpp index 5d86596f8f..701862882e 100644 --- a/src/plugins/qtsupport/qmldumptool.cpp +++ b/src/plugins/qtsupport/qmldumptool.cpp @@ -41,6 +41,7 @@ #include <projectexplorer/runconfiguration.h> #include <utils/runextensions.h> #include <qmljs/qmljsmodelmanagerinterface.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDesktopServices> #include <QCoreApplication> @@ -244,9 +245,8 @@ static QStringList sourceFileNames() files << QLatin1String("main.cpp") << QLatin1String("qmldump.pro") << QLatin1String("qmlstreamwriter.cpp") << QLatin1String("qmlstreamwriter.h") << QLatin1String("LICENSE.LGPL") << QLatin1String("LGPL_EXCEPTION.TXT"); -#ifdef Q_OS_MAC - files << QLatin1String("Info.plist"); -#endif + if (Utils::HostOsInfo::isMacHost()) + files << QLatin1String("Info.plist"); return files; } diff --git a/src/plugins/qtsupport/qtkitconfigwidget.cpp b/src/plugins/qtsupport/qtkitconfigwidget.cpp index 64b02115b7..c5a3fb033a 100644 --- a/src/plugins/qtsupport/qtkitconfigwidget.cpp +++ b/src/plugins/qtsupport/qtkitconfigwidget.cpp @@ -45,34 +45,21 @@ namespace QtSupport { namespace Internal { -QtKitConfigWidget::QtKitConfigWidget(ProjectExplorer::Kit *k, QWidget *parent) : - ProjectExplorer::KitConfigWidget(parent), - m_kit(k), - m_combo(new QComboBox), - m_manageButton(new QPushButton(this)) +QtKitConfigWidget::QtKitConfigWidget(ProjectExplorer::Kit *k) : + KitConfigWidget(k) { - setToolTip(tr("The Qt library to use for all projects using this kit.<br>" - "A Qt version is required for qmake-based projects and optional when using other build systems.")); - QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); - - m_combo->setContentsMargins(0, 0, 0, 0); - m_combo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - layout->addWidget(m_combo); - - m_manageButton->setContentsMargins(0, 0, 0, 0); - m_manageButton->setText(tr("Manage...")); + m_combo = new QComboBox; + m_combo->addItem(tr("None"), -1); QtVersionManager *mgr = QtVersionManager::instance(); - - // initially populate combobox: - m_combo->addItem(tr("None"), -1); QList<BaseQtVersion *> versions = mgr->validVersions(); QList<int> versionIds; foreach (BaseQtVersion *v, versions) versionIds.append(v->uniqueId()); versionsChanged(versionIds, QList<int>(), QList<int>()); + m_manageButton = new QPushButton(tr("Manage...")); + refresh(); connect(m_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(currentWasChanged(int))); @@ -87,6 +74,13 @@ QString QtKitConfigWidget::displayName() const return tr("Qt version:"); } +QString QtKitConfigWidget::toolTip() const +{ + return tr("The Qt library to use for all projects using this kit.<br>" + "A Qt version is required for qmake-based projects " + "and optional when using other build systems."); +} + void QtKitConfigWidget::makeReadOnly() { m_combo->setEnabled(false); @@ -97,6 +91,11 @@ void QtKitConfigWidget::refresh() m_combo->setCurrentIndex(findQtVersion(QtKitInformation::qtVersionId(m_kit))); } +QWidget *QtKitConfigWidget::mainWidget() const +{ + return m_combo; +} + QWidget *QtKitConfigWidget::buttonWidget() const { return m_manageButton; diff --git a/src/plugins/qtsupport/qtkitconfigwidget.h b/src/plugins/qtsupport/qtkitconfigwidget.h index 0ee01d6838..d163998df7 100644 --- a/src/plugins/qtsupport/qtkitconfigwidget.h +++ b/src/plugins/qtsupport/qtkitconfigwidget.h @@ -32,14 +32,12 @@ #include <projectexplorer/kitconfigwidget.h> -QT_FORWARD_DECLARE_CLASS(QComboBox) -QT_FORWARD_DECLARE_CLASS(QPushButton) - -namespace ProjectExplorer { class Kit; } +QT_BEGIN_NAMESPACE +class QComboBox; +class QPushButton; +QT_END_NAMESPACE namespace QtSupport { -class BaseQtVersion; - namespace Internal { class QtKitConfigWidget : public ProjectExplorer::KitConfigWidget @@ -47,14 +45,16 @@ class QtKitConfigWidget : public ProjectExplorer::KitConfigWidget Q_OBJECT public: - explicit QtKitConfigWidget(ProjectExplorer::Kit *k, QWidget *parent = 0); + explicit QtKitConfigWidget(ProjectExplorer::Kit *k); QString displayName() const; void makeReadOnly(); void refresh(); + QWidget *mainWidget() const; QWidget *buttonWidget() const; + QString toolTip() const; private slots: void versionsChanged(const QList<int> &added, const QList<int> &removed, const QList<int> &changed); @@ -64,7 +64,6 @@ private slots: private: int findQtVersion(const int id) const; - ProjectExplorer::Kit *m_kit; QComboBox *m_combo; QPushButton *m_manageButton; }; diff --git a/src/plugins/qtsupport/qtkitinformation.cpp b/src/plugins/qtsupport/qtkitinformation.cpp index 40fef3c0aa..b742a7e6dc 100644 --- a/src/plugins/qtsupport/qtkitinformation.cpp +++ b/src/plugins/qtsupport/qtkitinformation.cpp @@ -32,6 +32,7 @@ #include "qtkitconfigwidget.h" #include "qtsupportconstants.h" #include "qtversionmanager.h" +#include "qtparser.h" #include <utils/environment.h> @@ -126,6 +127,13 @@ void QtKitInformation::addToEnvironment(const ProjectExplorer::Kit *k, Utils::En version->addToEnvironment(k, env); } +ProjectExplorer::IOutputParser *QtKitInformation::createOutputParser(const ProjectExplorer::Kit *k) const +{ + if (qtVersion(k)) + return new QtParser; + return 0; +} + int QtKitInformation::qtVersionId(const ProjectExplorer::Kit *k) { if (!k) diff --git a/src/plugins/qtsupport/qtkitinformation.h b/src/plugins/qtsupport/qtkitinformation.h index ac788e4745..508c21f246 100644 --- a/src/plugins/qtsupport/qtkitinformation.h +++ b/src/plugins/qtsupport/qtkitinformation.h @@ -61,6 +61,7 @@ public: ItemList toUserOutput(ProjectExplorer::Kit *k) const; void addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const; + ProjectExplorer::IOutputParser *createOutputParser(const ProjectExplorer::Kit *k) const; static int qtVersionId(const ProjectExplorer::Kit *k); static void setQtVersionId(ProjectExplorer::Kit *k, const int id); diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index af5d0480bc..8cfc89763d 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -48,6 +48,7 @@ #include <projectexplorer/toolchainmanager.h> #include <projectexplorer/toolchain.h> #include <projectexplorer/projectexplorerconstants.h> +#include <utils/hostosinfo.h> #include <utils/runextensions.h> #include <QDir> @@ -616,16 +617,14 @@ static QString filterForQmakeFileDialog() for (int i = 0; i < commands.size(); ++i) { if (i) filter += QLatin1Char(' '); -#ifdef Q_OS_MAC - // work around QTBUG-7739 that prohibits filters that don't start with * - filter += QLatin1Char('*'); -#endif + if (Utils::HostOsInfo::isMacHost()) + // work around QTBUG-7739 that prohibits filters that don't start with * + filter += QLatin1Char('*'); filter += commands.at(i); -#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) - // kde bug, we need at least one wildcard character - // see QTCREATORBUG-7771 - filter += QLatin1Char('*'); -#endif + if (Utils::HostOsInfo::isAnyUnixHost() && !Utils::HostOsInfo::isMacHost()) + // kde bug, we need at least one wildcard character + // see QTCREATORBUG-7771 + filter += QLatin1Char('*'); } filter += QLatin1Char(')'); return filter; diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp index fec46be1e5..d670d5a0bd 100644 --- a/src/plugins/qtsupport/qtoutputformatter.cpp +++ b/src/plugins/qtsupport/qtoutputformatter.cpp @@ -43,8 +43,7 @@ using namespace QtSupport; QtOutputFormatter::QtOutputFormatter(ProjectExplorer::Project *project) : OutputFormatter() - , m_qmlError(QLatin1String("^(?:\\[Qt Message\\] )?" // '[Qt Message] ' prefix (optional, on Symbian) - "(file:///.+" // file url + , m_qmlError(QLatin1String("^(file:///.+" // file url ":\\d+" // colon, line "(?::\\d+)?)" // colon, column (optional) ":")) // colon diff --git a/src/plugins/qtsupport/qtoutputformatter.h b/src/plugins/qtsupport/qtoutputformatter.h index 141c471b02..47665bd772 100644 --- a/src/plugins/qtsupport/qtoutputformatter.h +++ b/src/plugins/qtsupport/qtoutputformatter.h @@ -36,7 +36,7 @@ #include <utils/fileinprojectfinder.h> #include <QRegExp> -#include <QWeakPointer> +#include <QPointer> QT_FORWARD_DECLARE_CLASS(QTextCursor) @@ -80,7 +80,7 @@ private: mutable QRegExp m_qtAssert; mutable QRegExp m_qtAssertX; mutable QRegExp m_qtTestFail; - QWeakPointer<ProjectExplorer::Project> m_project; + QPointer<ProjectExplorer::Project> m_project; QString m_lastLine; Utils::FileInProjectFinder m_projectFinder; }; diff --git a/src/plugins/qtsupport/qtparser.cpp b/src/plugins/qtsupport/qtparser.cpp index 56d03ee547..975e84407c 100644 --- a/src/plugins/qtsupport/qtparser.cpp +++ b/src/plugins/qtsupport/qtparser.cpp @@ -41,7 +41,7 @@ using ProjectExplorer::Task; #define FILE_PATTERN "^(([A-Za-z]:)?[^:]+\\.[^:]+)" QtParser::QtParser() : - m_mocRegExp(QLatin1String(FILE_PATTERN"[:\\(](\\d+)\\)?:\\s(Warning|Error):\\s(.+)$")) + m_mocRegExp(QLatin1String(FILE_PATTERN"[:\\(](\\d+)\\)?:\\s([Ww]arning|[Ee]rror):\\s(.+)$")) { setObjectName(QLatin1String("QtParser")); m_mocRegExp.setMinimal(true); @@ -60,7 +60,7 @@ void QtParser::stdError(const QString &line) Utils::FileName::fromUserInput(m_mocRegExp.cap(1)) /* filename */, lineno, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)); - if (m_mocRegExp.cap(4) == QLatin1String("Warning")) + if (m_mocRegExp.cap(4).compare(QLatin1String("Warning"), Qt::CaseInsensitive) == 0) task.type = Task::Warning; emit addTask(task); return; @@ -116,6 +116,15 @@ void QtSupportPlugin::testQtOutputParser_data() "../../scriptbug/main.cpp:22: instantiated from here\n") << QList<ProjectExplorer::Task>() << QString(); + QTest::newRow("qdoc warning") + << QString::fromLatin1("/home/user/dev/qt5/qtscript/src/script/api/qscriptengine.cpp:295: warning: Can't create link to 'Object Trees & Ownership'") + << OutputParserTester::STDERR + << QString() << QString() + << (QList<ProjectExplorer::Task>() << Task(Task::Warning, + QLatin1String("Can't create link to 'Object Trees & Ownership'"), + Utils::FileName::fromUserInput(QLatin1String("/home/user/dev/qt5/qtscript/src/script/api/qscriptengine.cpp")), 295, + Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_COMPILE))) + << QString(); QTest::newRow("moc warning") << QString::fromLatin1("..\\untitled\\errorfile.h:0: Warning: No relevant classes found. No output generated.") << OutputParserTester::STDERR diff --git a/src/plugins/qtsupport/qtsupport.pri b/src/plugins/qtsupport/qtsupport.pri index a419733faf..e4de26c4ca 100644 --- a/src/plugins/qtsupport/qtsupport.pri +++ b/src/plugins/qtsupport/qtsupport.pri @@ -5,3 +5,4 @@ DEFINES *= QMAKE_AS_LIBRARY DEFINES *= PROPARSER_THREAD_SAFE DEFINES *= PROEVALUATOR_THREAD_SAFE DEFINES *= PROEVALUATOR_CUMULATIVE +DEFINES *= PROEVALUATOR_SETENV diff --git a/src/plugins/qtsupport/qtsupport.pro b/src/plugins/qtsupport/qtsupport.pro index c1a2ad0be6..701aa5dd0e 100644 --- a/src/plugins/qtsupport/qtsupport.pro +++ b/src/plugins/qtsupport/qtsupport.pro @@ -7,7 +7,7 @@ include(../../qtcreatorplugin.pri) include(qtsupport_dependencies.pri) DEFINES += \ QMAKE_AS_LIBRARY QMAKE_LIBRARY \ - PROPARSER_THREAD_SAFE PROEVALUATOR_THREAD_SAFE PROEVALUATOR_CUMULATIVE + PROPARSER_THREAD_SAFE PROEVALUATOR_THREAD_SAFE PROEVALUATOR_CUMULATIVE PROEVALUATOR_SETENV include(../../shared/proparser/proparser.pri) HEADERS += \ diff --git a/src/plugins/qtsupport/qtsupport.qbs b/src/plugins/qtsupport/qtsupport.qbs index e8aed6c497..d513058452 100644 --- a/src/plugins/qtsupport/qtsupport.qbs +++ b/src/plugins/qtsupport/qtsupport.qbs @@ -12,101 +12,104 @@ QtcPlugin { Depends { name: "QmlJS" } Depends { name: "cpp" } - cpp.includePaths: [ - ".", + cpp.includePaths: base.concat([ "../../shared", - "../../shared/proparser", - "..", - "../../libs", - buildDirectory - ] - cpp.defines: { - return base.concat([ - "QT_NO_CAST_FROM_ASCII", - "QT_NO_CAST_TO_ASCII", - "QMAKE_AS_LIBRARY", - "QMAKE_LIBRARY", - "PROPARSER_THREAD_SAFE", - "PROEVALUATOR_THREAD_SAFE", - "PROEVALUATOR_CUMULATIVE", - "QMAKE_BUILTIN_PRFS" - ]) + "../../shared/proparser" + ]) + + cpp.defines: base.concat([ + "QT_NO_CAST_FROM_ASCII", + "QT_NO_CAST_TO_ASCII", + "QMAKE_AS_LIBRARY", + "QMAKE_LIBRARY", + "PROPARSER_THREAD_SAFE", + "PROEVALUATOR_THREAD_SAFE", + "PROEVALUATOR_CUMULATIVE", + "QMAKE_BUILTIN_PRFS", + "PROEVALUATOR_SETENV" + ]) + + Group { + prefix: "../../shared/proparser/" + files: [ + "ioutils.cpp", + "ioutils.h", + "profileevaluator.cpp", + "profileevaluator.h", + "proitems.cpp", + "proitems.h", + "proparser.qrc", + "prowriter.cpp", + "prowriter.h", + "qmake_global.h", + "qmakebuiltins.cpp", + "qmakeevaluator.cpp", + "qmakeevaluator.h", + "qmakeevaluator_p.h", + "qmakeglobals.cpp", + "qmakeglobals.h", + "qmakeparser.cpp", + "qmakeparser.h", + ] } files: [ - "../../shared/proparser/qmakebuiltins.cpp", - "../../shared/proparser/qmakeevaluator.cpp", - "../../shared/proparser/qmakeevaluator.h", - "../../shared/proparser/qmakeevaluator_p.h", - "../../shared/proparser/qmakeglobals.cpp", - "../../shared/proparser/qmakeglobals.h", - "../../shared/proparser/qmakeparser.cpp", - "../../shared/proparser/qmakeparser.h", - "../../shared/proparser/qmake_global.h", - "../../shared/proparser/profileevaluator.cpp", - "../../shared/proparser/profileevaluator.h", - "../../shared/proparser/proitems.cpp", - "../../shared/proparser/proitems.h", - "../../shared/proparser/prowriter.cpp", - "../../shared/proparser/prowriter.h", - "../../shared/proparser/proparser.qrc", - "../../shared/proparser/ioutils.h", - "../../shared/proparser/ioutils.cpp", - "qtversioninfo.ui", - "qtversionmanager.ui", + "baseqtversion.cpp", "baseqtversion.h", + "customexecutableconfigurationwidget.cpp", + "customexecutableconfigurationwidget.h", + "customexecutablerunconfiguration.cpp", + "customexecutablerunconfiguration.h", "debugginghelper.cpp", "debugginghelper.h", "debugginghelper.ui", + "debugginghelperbuildtask.cpp", "debugginghelperbuildtask.h", + "exampleslistmodel.cpp", "exampleslistmodel.h", + "gettingstartedwelcomepage.cpp", "gettingstartedwelcomepage.h", "profilereader.cpp", "profilereader.h", + "qmldebugginglibrary.cpp", "qmldebugginglibrary.h", + "qmldumptool.cpp", "qmldumptool.h", + "qmlobservertool.cpp", "qmlobservertool.h", - "qtoptionspage.h", - "qtoutputformatter.cpp", - "qtoutputformatter.h", - "qtparser.h", "qtkitconfigwidget.cpp", "qtkitconfigwidget.h", "qtkitinformation.cpp", "qtkitinformation.h", + "qtoptionspage.cpp", + "qtoptionspage.h", + "qtoutputformatter.cpp", + "qtoutputformatter.h", + "qtparser.cpp", + "qtparser.h", "qtsupport_global.h", "qtsupportconstants.h", "qtsupportplugin.cpp", "qtsupportplugin.h", + "qtversionfactory.cpp", "qtversionfactory.h", + "qtversioninfo.ui", + "qtversionmanager.cpp", "qtversionmanager.h", + "qtversionmanager.ui", "screenshotcropper.cpp", "screenshotcropper.h", "showbuildlog.ui", - "baseqtversion.cpp", - "customexecutableconfigurationwidget.cpp", - "customexecutableconfigurationwidget.h", - "customexecutablerunconfiguration.cpp", - "customexecutablerunconfiguration.h", - "debugginghelperbuildtask.cpp", - "exampleslistmodel.cpp", - "gettingstartedwelcomepage.cpp", - "qmldebugginglibrary.cpp", - "qmldumptool.cpp", - "qmlobservertool.cpp", - "qtoptionspage.cpp", - "qtparser.cpp", - "qtversionfactory.cpp", - "qtversionmanager.cpp" ] ProductModule { Depends { name: "cpp" } - cpp.includePaths: [ "../../shared" ] + cpp.includePaths: "../../shared" cpp.defines: [ "QMAKE_AS_LIBRARY", "PROEVALUATOR_THREAD_SAFE", - "QMAKE_BUILTIN_PRFS" + "QMAKE_BUILTIN_PRFS", + "PROEVALUATOR_SETENV" ] } } diff --git a/src/plugins/qtsupport/qtsupportplugin.cpp b/src/plugins/qtsupport/qtsupportplugin.cpp index 1b773d1215..08007f9d45 100644 --- a/src/plugins/qtsupport/qtsupportplugin.cpp +++ b/src/plugins/qtsupport/qtsupportplugin.cpp @@ -38,12 +38,19 @@ #include "gettingstartedwelcomepage.h" +#include <coreplugin/variablemanager.h> #include <extensionsystem/pluginmanager.h> #include <projectexplorer/kitmanager.h> +#include <projectexplorer/project.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/target.h> #include <QtPlugin> #include <QMenu> +static const char kHostBins[] = "CurrentProject:QT_HOST_BINS"; +static const char kInstallBins[] = "CurrentProject:QT_INSTALL_BINS"; + using namespace QtSupport; using namespace QtSupport::Internal; @@ -81,6 +88,15 @@ bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMes void QtSupportPlugin::extensionsInitialized() { + Core::VariableManager *vm = Core::VariableManager::instance(); + vm->registerVariable(kHostBins, + tr("Full path to the host bin directory of the current project's Qt version.")); + vm->registerVariable(kInstallBins, + tr("Full path to the target bin directory of the current project's Qt version." + " You probably want %1 instead.").arg(QString::fromLatin1(kHostBins))); + connect(vm, SIGNAL(variableUpdateRequested(QByteArray)), + this, SLOT(updateVariable(QByteArray))); + QtVersionManager::instance()->extensionsInitialized(); ProjectExplorer::KitManager::instance()->registerKitInformation(new QtKitInformation); } @@ -90,4 +106,25 @@ bool QtSupportPlugin::delayedInitialize() return QtVersionManager::instance()->delayedInitialize(); } +void QtSupportPlugin::updateVariable(const QByteArray &variable) +{ + if (variable != kHostBins && variable != kInstallBins) + return; + + ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::currentProject(); + if (!project || !project->activeTarget()) { + Core::VariableManager::instance()->remove(variable); + return; + } + + const BaseQtVersion *qtVersion = QtKitInformation::qtVersion(project->activeTarget()->kit()); + if (!qtVersion) { + Core::VariableManager::instance()->remove(variable); + return; + } + + QString value = qtVersion->qmakeProperty(variable == kHostBins ? "QT_HOST_BINS" : "QT_INSTALL_BINS"); + Core::VariableManager::instance()->insert(variable, value); +} + Q_EXPORT_PLUGIN(QtSupportPlugin) diff --git a/src/plugins/qtsupport/qtsupportplugin.h b/src/plugins/qtsupport/qtsupportplugin.h index b529c5335a..8a5a24eb79 100644 --- a/src/plugins/qtsupport/qtsupportplugin.h +++ b/src/plugins/qtsupport/qtsupportplugin.h @@ -49,6 +49,8 @@ public: bool delayedInitialize(); private slots: + void updateVariable(const QByteArray &variable); + #ifdef WITH_TESTS void testQtOutputParser_data(); void testQtOutputParser(); diff --git a/src/plugins/qtsupport/qtversionfactory.cpp b/src/plugins/qtsupport/qtversionfactory.cpp index f5422d4b82..a0287bb5b8 100644 --- a/src/plugins/qtsupport/qtversionfactory.cpp +++ b/src/plugins/qtsupport/qtversionfactory.cpp @@ -33,6 +33,8 @@ #include "baseqtversion.h" #include <extensionsystem/pluginmanager.h> +#include <utils/environment.h> + #include <QSettings> using namespace QtSupport; @@ -57,12 +59,13 @@ bool sortByPriority(QtVersionFactory *a, QtVersionFactory *b) BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath(const Utils::FileName &qmakePath, bool isAutoDetected, const QString &autoDetectionSource) { QHash<QString, QString> versionInfo; - bool success = BaseQtVersion::queryQMakeVariables(qmakePath, &versionInfo); + Utils::Environment env = Utils::Environment::systemEnvironment(); + bool success = BaseQtVersion::queryQMakeVariables(qmakePath, env, &versionInfo); if (!success) return 0; Utils::FileName mkspec = BaseQtVersion::mkspecFromVersionInfo(versionInfo); - QMakeGlobals globals; + ProFileGlobals globals; globals.setProperties(versionInfo); ProMessageHandler msgHandler(true); ProFileCacheManager::instance()->incRefCount(); diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index a229e3d570..6159000963 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -473,20 +473,6 @@ bool QtVersionManager::isValidId(int id) const return m_versions.contains(id); } -QString QtVersionManager::popPendingMwcUpdate() -{ - if (m_pendingMwcUpdates.isEmpty()) - return QString(); - return m_pendingMwcUpdates.takeFirst(); -} - -QString QtVersionManager::popPendingGcceUpdate() -{ - if (m_pendingGcceUpdates.isEmpty()) - return QString(); - return m_pendingGcceUpdates.takeFirst(); -} - Core::FeatureSet QtVersionManager::availableFeatures(const QString &platformName) const { Core::FeatureSet features; diff --git a/src/plugins/qtsupport/qtversionmanager.h b/src/plugins/qtsupport/qtversionmanager.h index d391c83323..ea8db4d339 100644 --- a/src/plugins/qtsupport/qtversionmanager.h +++ b/src/plugins/qtsupport/qtversionmanager.h @@ -91,10 +91,6 @@ public: static Utils::FileName findQMakeBinaryFromMakefile(const QString &directory); bool isValidId(int id) const; - // Compatibility with pre-2.2: - QString popPendingMwcUpdate(); - QString popPendingGcceUpdate(); - Core::FeatureSet availableFeatures(const QString &platformName) const; QStringList availablePlatforms() const; QString displayNameForPlatform(const QString &string) const; @@ -122,7 +118,6 @@ private: static BaseQtVersion::QmakeBuildConfigs qmakeBuildConfigFromCmdArgs(QList<QMakeAssignment> *assignments, BaseQtVersion::QmakeBuildConfigs defaultBuildConfig); bool restoreQtVersions(); - bool legacyRestore(); void findSystemQt(); void saveQtVersions(); void updateDocumentation(); @@ -140,10 +135,6 @@ private: // managed by QtProjectManagerPlugin static QtVersionManager *m_self; - // Compatibility with pre-2.2: - QStringList m_pendingMwcUpdates; - QStringList m_pendingGcceUpdates; - Utils::FileSystemWatcher *m_configFileWatcher; QTimer *m_fileWatcherTimer; Utils::PersistentSettingsWriter *m_writer; diff --git a/src/plugins/remotelinux/RemoteLinux.pluginspec.in b/src/plugins/remotelinux/RemoteLinux.pluginspec.in index 26da958bd1..b0c21e145f 100644 --- a/src/plugins/remotelinux/RemoteLinux.pluginspec.in +++ b/src/plugins/remotelinux/RemoteLinux.pluginspec.in @@ -17,6 +17,6 @@ Alternatively, this plugin may be used under the terms of the GNU Lesser General <dependency name=\"Core\" version=\"$$QTCREATOR_VERSION\"/> <dependency name=\"Debugger\" version=\"$$QTCREATOR_VERSION\"/> <dependency name=\"ProjectExplorer\" version=\"$$QTCREATOR_VERSION\"/> - <dependency name=\"Qt4ProjectManager\" version=\"$$QTCREATOR_VERSION\"/> + <dependency name=\"QtSupport\" version=\"$$QTCREATOR_VERSION\"/> </dependencyList> </plugin> diff --git a/src/plugins/remotelinux/abstractpackagingstep.cpp b/src/plugins/remotelinux/abstractpackagingstep.cpp index 46c77d6f09..ed59c5a506 100644 --- a/src/plugins/remotelinux/abstractpackagingstep.cpp +++ b/src/plugins/remotelinux/abstractpackagingstep.cpp @@ -28,12 +28,12 @@ ****************************************************************************/ #include "abstractpackagingstep.h" -#include "deployablefile.h" -#include "deploymentinfo.h" #include "remotelinuxdeployconfiguration.h" #include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/deploymentdata.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/project.h> #include <projectexplorer/target.h> #include <projectexplorer/task.h> #include <utils/fileutils.h> @@ -54,6 +54,7 @@ public: BuildConfiguration *currentBuildConfiguration; QString cachedPackageFilePath; QString cachedPackageDirectory; + bool deploymentDataModified; }; } // namespace Internal @@ -77,8 +78,10 @@ void AbstractPackagingStep::ctor() SLOT(handleBuildConfigurationChanged())); handleBuildConfigurationChanged(); - connect(this, SIGNAL(unmodifyDeploymentInfo()), - this, SLOT(setDeploymentInfoUnmodified())); + connect(target(), SIGNAL(deploymentDataChanged()), SLOT(setDeploymentDataModified())); + setDeploymentDataModified(); + + connect(this, SIGNAL(unmodifyDeploymentData()), this, SLOT(setDeploymentDataUnmodified())); } AbstractPackagingStep::~AbstractPackagingStep() @@ -128,16 +131,16 @@ RemoteLinuxDeployConfiguration *AbstractPackagingStep::deployConfiguration() con bool AbstractPackagingStep::isPackagingNeeded() const { - const DeploymentInfo * const deploymentInfo = deployConfiguration()->deploymentInfo(); QFileInfo packageInfo(packageFilePath()); - if (!packageInfo.exists() || deploymentInfo->isModified()) + if (!packageInfo.exists() || d->deploymentDataModified) return true; - const int deployableCount = deploymentInfo->deployableCount(); - for (int i = 0; i < deployableCount; ++i) { - if (Utils::FileUtils::isFileNewerThan(deploymentInfo->deployableAt(i).localFilePath, - packageInfo.lastModified())) + const DeploymentData &dd = target()->deploymentData(); + for (int i = 0; i < dd.fileCount(); ++i) { + if (Utils::FileUtils::isFileNewerThan(dd.fileAt(i).localFilePath(), + packageInfo.lastModified())) { return true; + } } return false; @@ -158,13 +161,18 @@ void AbstractPackagingStep::setPackagingStarted() void AbstractPackagingStep::setPackagingFinished(bool success) { if (success) - emit unmodifyDeploymentInfo(); + emit unmodifyDeploymentData(); } // called in gui thread -void AbstractPackagingStep::setDeploymentInfoUnmodified() +void AbstractPackagingStep::setDeploymentDataUnmodified() +{ + d->deploymentDataModified = false; +} + +void AbstractPackagingStep::setDeploymentDataModified() { - deployConfiguration()->deploymentInfo()->setUnmodified(); + d->deploymentDataModified = true; } void AbstractPackagingStep::raiseError(const QString &errorMessage) diff --git a/src/plugins/remotelinux/abstractpackagingstep.h b/src/plugins/remotelinux/abstractpackagingstep.h index dc0e7a7200..bde6a58351 100644 --- a/src/plugins/remotelinux/abstractpackagingstep.h +++ b/src/plugins/remotelinux/abstractpackagingstep.h @@ -35,11 +35,8 @@ namespace RemoteLinux { class RemoteLinuxDeployConfiguration; -class DeploymentInfo; -namespace Internal { -class AbstractPackagingStepPrivate; -} +namespace Internal { class AbstractPackagingStepPrivate; } class REMOTELINUX_EXPORT AbstractPackagingStep : public ProjectExplorer::BuildStep { @@ -56,7 +53,7 @@ public: signals: void packageFilePathChanged(); - void unmodifyDeploymentInfo(); + void unmodifyDeploymentData(); protected: void setPackagingStarted(); @@ -71,7 +68,8 @@ protected: private slots: void handleBuildConfigurationChanged(); - void setDeploymentInfoUnmodified(); + void setDeploymentDataUnmodified(); + void setDeploymentDataModified(); private: virtual QString packageFileName() const = 0; diff --git a/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp b/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp index a0d2ad4521..60bde725db 100644 --- a/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp +++ b/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp @@ -29,9 +29,8 @@ #include "abstractremotelinuxdeployservice.h" -#include "deployablefile.h" - #include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/deployablefile.h> #include <projectexplorer/target.h> #include <qtsupport/qtkitinformation.h> #include <utils/qtcassert.h> @@ -159,7 +158,7 @@ bool AbstractRemoteLinuxDeployService::hasChangedSinceLastDeployment(const Deplo const QDateTime &lastDeployed = d->lastDeployed.value(DeployParameters(deployableFile, deviceConfiguration()->sshParameters().host, systemRoot)); return !lastDeployed.isValid() - || QFileInfo(deployableFile.localFilePath).lastModified() > lastDeployed; + || deployableFile.localFilePath().toFileInfo().lastModified() > lastDeployed; } void AbstractRemoteLinuxDeployService::setBuildConfiguration(BuildConfiguration *bc) @@ -235,8 +234,8 @@ QVariantMap AbstractRemoteLinuxDeployService::exportDeployTimes() const QVariantList timeList; typedef QHash<DeployParameters, QDateTime>::ConstIterator DepIt; for (DepIt it = d->lastDeployed.begin(); it != d->lastDeployed.end(); ++it) { - fileList << it.key().file.localFilePath; - remotePathList << it.key().file.remoteDir; + fileList << it.key().file.localFilePath().toString(); + remotePathList << it.key().file.remoteDirectory(); hostList << it.key().host; sysrootList << it.key().sysroot; timeList << it.value(); diff --git a/src/plugins/remotelinux/abstractremotelinuxdeployservice.h b/src/plugins/remotelinux/abstractremotelinuxdeployservice.h index ee11338d2f..15c455680f 100644 --- a/src/plugins/remotelinux/abstractremotelinuxdeployservice.h +++ b/src/plugins/remotelinux/abstractremotelinuxdeployservice.h @@ -41,16 +41,12 @@ namespace QSsh { class SshConnection; } namespace ProjectExplorer { class BuildConfiguration; +class DeployableFile; class Kit; } namespace RemoteLinux { -class DeployableFile; -class DeploymentInfo; - -namespace Internal { -class AbstractRemoteLinuxDeployServicePrivate; -} +namespace Internal { class AbstractRemoteLinuxDeployServicePrivate; } class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployService : public QObject { @@ -82,8 +78,8 @@ protected: ProjectExplorer::IDevice::ConstPtr deviceConfiguration() const; QSsh::SshConnection *connection() const; - void saveDeploymentTimeStamp(const DeployableFile &deployableFile); - bool hasChangedSinceLastDeployment(const DeployableFile &deployableFile) const; + void saveDeploymentTimeStamp(const ProjectExplorer::DeployableFile &deployableFile); + bool hasChangedSinceLastDeployment(const ProjectExplorer::DeployableFile &deployableFile) const; void handleDeviceSetupDone(bool success); void handleDeploymentDone(); diff --git a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp index d0c4d867cb..52735354ef 100644 --- a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp +++ b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp @@ -29,16 +29,18 @@ #include "abstractuploadandinstallpackageservice.h" -#include "deployablefile.h" #include "packageuploader.h" #include "remotelinuxpackageinstaller.h" +#include <projectexplorer/deployablefile.h> #include <utils/qtcassert.h> #include <ssh/sshconnection.h> #include <QFileInfo> #include <QString> +using namespace ProjectExplorer; + namespace RemoteLinux { namespace Internal { namespace { diff --git a/src/plugins/remotelinux/deployablefilesperprofile.cpp b/src/plugins/remotelinux/deployablefilesperprofile.cpp deleted file mode 100644 index 9c7465faea..0000000000 --- a/src/plugins/remotelinux/deployablefilesperprofile.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ -#include "deployablefilesperprofile.h" - -#include "deployablefile.h" - -#include <utils/qtcassert.h> - -#include <QFileInfo> -#include <QDir> -#include <QBrush> - -using namespace Qt4ProjectManager; - -namespace RemoteLinux { -namespace Internal { -class DeployableFilesPerProFilePrivate -{ -public: - DeployableFilesPerProFilePrivate(const Qt4ProFileNode *proFileNode) - : projectType(proFileNode->projectType()), - proFilePath(proFileNode->path()), - projectName(proFileNode->displayName()), - targetInfo(proFileNode->targetInformation()), - installsList(proFileNode->installsList()), - projectVersion(proFileNode->projectVersion()), - config(proFileNode->variableValue(ConfigVar)), - modified(true) - { - } - - const Qt4ProjectType projectType; - const QString proFilePath; - const QString projectName; - const Qt4ProjectManager::TargetInformation targetInfo; - const Qt4ProjectManager::InstallsList installsList; - const Qt4ProjectManager::ProjectVersion projectVersion; - const QStringList config; - QList<DeployableFile> deployables; - bool modified; -}; - -} // namespace Internal - -using namespace Internal; - -DeployableFilesPerProFile::DeployableFilesPerProFile(const Qt4ProFileNode *proFileNode, - const QString &installPrefix, QObject *parent) - : QAbstractTableModel(parent), d(new DeployableFilesPerProFilePrivate(proFileNode)) -{ - if (hasTargetPath()) { - if (d->projectType == ApplicationTemplate) { - d->deployables.prepend(DeployableFile(localExecutableFilePath(), - d->installsList.targetPath, DeployableFile::TypeExecutable)); - } else if (d->projectType == LibraryTemplate) { - foreach (const QString &filePath, localLibraryFilePaths()) { - d->deployables.prepend(DeployableFile(filePath, - d->installsList.targetPath)); - } - } - } - - foreach (const InstallsItem &elem, d->installsList.items) { - foreach (const QString &file, elem.files) - d->deployables << DeployableFile(file, elem.path); - } - - if (!installPrefix.isEmpty()) { - for (int i = 0; i < d->deployables.count(); ++i) - d->deployables[i].remoteDir.prepend(installPrefix + QLatin1Char('/')); - } -} - -DeployableFilesPerProFile::~DeployableFilesPerProFile() -{ - delete d; -} - -DeployableFile DeployableFilesPerProFile::deployableAt(int row) const -{ - Q_ASSERT(row >= 0 && row < rowCount()); - return d->deployables.at(row); -} - -int DeployableFilesPerProFile::rowCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : d->deployables.count(); -} - -int DeployableFilesPerProFile::columnCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : 2; -} - -QVariant DeployableFilesPerProFile::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.row() >= rowCount()) - return QVariant(); - - const DeployableFile &d = deployableAt(index.row()); - if (index.column() == 0 && role == Qt::DisplayRole) - return QDir::toNativeSeparators(d.localFilePath); - if (role == Qt::DisplayRole) - return QDir::cleanPath(d.remoteDir); - return QVariant(); -} - -QVariant DeployableFilesPerProFile::headerData(int section, - Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Vertical || role != Qt::DisplayRole) - return QVariant(); - return section == 0 ? tr("Local File Path") : tr("Remote Directory"); -} - -QString DeployableFilesPerProFile::localExecutableFilePath() const -{ - if (!d->targetInfo.valid || d->projectType != ApplicationTemplate) - return QString(); - return QDir::cleanPath(d->targetInfo.workingDir + '/' + d->targetInfo.target); -} - -QStringList DeployableFilesPerProFile::localLibraryFilePaths() const -{ - QStringList list; - - if (!d->targetInfo.valid || d->projectType != LibraryTemplate) - return list; - QString basePath = d->targetInfo.workingDir + QLatin1String("/lib"); - const bool isStatic = d->config.contains(QLatin1String("static")) - || d->config.contains(QLatin1String("staticlib")); - basePath += d->targetInfo.target + QLatin1String(isStatic ? ".a" : ".so"); - basePath = QDir::cleanPath(basePath); - if (!isStatic && !d->config.contains(QLatin1String("plugin"))) { - const QChar dot(QLatin1Char('.')); - const QString filePathMajor = basePath + dot - + QString::number(d->projectVersion.major); - const QString filePathMinor = filePathMajor + dot - + QString::number(d->projectVersion.minor); - const QString filePathPatch = filePathMinor + dot - + QString::number(d->projectVersion.patch); - list << filePathPatch << filePathMinor << filePathMajor; - } - return list << basePath; -} - -QString DeployableFilesPerProFile::remoteExecutableFilePath() const -{ - return hasTargetPath() && d->projectType == ApplicationTemplate - ? deployableAt(0).remoteDir + QLatin1Char('/') - + QFileInfo(localExecutableFilePath()).fileName() - : QString(); -} - -QString DeployableFilesPerProFile::projectDir() const -{ - return QFileInfo(d->proFilePath).dir().path(); -} - -bool DeployableFilesPerProFile::hasTargetPath() const -{ - return !d->installsList.targetPath.isEmpty(); -} - -bool DeployableFilesPerProFile::isModified() const { return d->modified; } -void DeployableFilesPerProFile::setUnModified() { d->modified = false; } -QString DeployableFilesPerProFile::projectName() const { return d->projectName; } -QString DeployableFilesPerProFile::proFilePath() const { return d->proFilePath; } -Qt4ProjectType DeployableFilesPerProFile::projectType() const { return d->projectType; } -QString DeployableFilesPerProFile::applicationName() const { return d->targetInfo.target; } - -} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/deployablefilesperprofile.h b/src/plugins/remotelinux/deployablefilesperprofile.h deleted file mode 100644 index 3d10eca359..0000000000 --- a/src/plugins/remotelinux/deployablefilesperprofile.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef DEPLOYABLEFILESPERPROFILE_H -#define DEPLOYABLEFILESPERPROFILE_H - -#include "remotelinux_export.h" - -#include <qt4projectmanager/qt4nodes.h> - -#include <QAbstractTableModel> -#include <QList> -#include <QString> - -namespace RemoteLinux { -class DeployableFile; - -namespace Internal { -class DeployableFilesPerProFilePrivate; -} - -class REMOTELINUX_EXPORT DeployableFilesPerProFile : public QAbstractTableModel -{ - Q_OBJECT -public: - DeployableFilesPerProFile(const Qt4ProjectManager::Qt4ProFileNode *proFileNode, - const QString &installPrefix, QObject *parent); - ~DeployableFilesPerProFile(); - - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - - DeployableFile deployableAt(int row) const; - bool isModified() const; - void setUnModified(); - QString localExecutableFilePath() const; - QString remoteExecutableFilePath() const; - QString projectName() const; - QString projectDir() const; - QString proFilePath() const; - Qt4ProjectManager::Qt4ProjectType projectType() const; - bool isApplicationProject() const { return projectType() == Qt4ProjectManager::ApplicationTemplate; } - QString applicationName() const; - bool hasTargetPath() const; - -private: - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, - int role = Qt::DisplayRole) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - - QStringList localLibraryFilePaths() const; - - Internal::DeployableFilesPerProFilePrivate * const d; -}; - -} // namespace RemoteLinux - -#endif // DEPLOYABLEFILESPERPROFILE_H diff --git a/src/plugins/remotelinux/deploymentinfo.cpp b/src/plugins/remotelinux/deploymentinfo.cpp deleted file mode 100644 index c23219798a..0000000000 --- a/src/plugins/remotelinux/deploymentinfo.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "deploymentinfo.h" - -#include "deployablefile.h" -#include "deployablefilesperprofile.h" -#include "remotelinuxdeployconfiguration.h" - -#include <projectexplorer/buildstep.h> -#include <projectexplorer/target.h> -#include <qt4projectmanager/qt4project.h> -#include <qtsupport/qtkitinformation.h> - -#include <QList> -#include <QTimer> - -using namespace Qt4ProjectManager; - -namespace RemoteLinux { -namespace Internal { -class DeploymentInfoPrivate -{ -public: - DeploymentInfoPrivate(const Qt4ProjectManager::Qt4Project *p) : project(p) {} - - QList<DeployableFilesPerProFile *> listModels; - const Qt4ProjectManager::Qt4Project *const project; - QString installPrefix; -}; -} // namespace Internal - -using namespace Internal; - -DeploymentInfo::DeploymentInfo(Qt4ProjectManager::Qt4Project *project, const QString &installPrefix) - : QAbstractListModel(project), d(new DeploymentInfoPrivate(project)) -{ - connect(project, SIGNAL(proFilesEvaluated()), SLOT(createModels())); - setInstallPrefix(installPrefix); -} - -DeploymentInfo::~DeploymentInfo() -{ - delete d; -} - -void DeploymentInfo::createModels() -{ - ProjectExplorer::Target *target = d->project->activeTarget(); - if (!target - || !target->activeDeployConfiguration() - || !qobject_cast<RemoteLinuxDeployConfiguration *>(target->activeDeployConfiguration())) - return; - - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target->kit()); - if (!version || !version->isValid()) { - beginResetModel(); - qDeleteAll(d->listModels); - d->listModels.clear(); - endResetModel(); - return; - } - const Qt4ProFileNode *const rootNode = d->project->rootQt4ProjectNode(); - if (!rootNode || rootNode->parseInProgress()) // Can be null right after project creation by wizard. - return; - disconnect(d->project, SIGNAL(proFilesEvaluated()), this, SLOT(createModels())); - beginResetModel(); - qDeleteAll(d->listModels); - d->listModels.clear(); - createModels(rootNode); - endResetModel(); - connect (d->project, SIGNAL(proFilesEvaluated()), SLOT(createModels())); -} - -void DeploymentInfo::createModels(const Qt4ProFileNode *proFileNode) -{ - switch (proFileNode->projectType()) { - case ApplicationTemplate: - case LibraryTemplate: - case AuxTemplate: - d->listModels << new DeployableFilesPerProFile(proFileNode, d->installPrefix, this); - break; - case SubDirsTemplate: { - const QList<Qt4PriFileNode *> &subProjects = proFileNode->subProjectNodesExact(); - foreach (const ProjectExplorer::ProjectNode * const subProject, subProjects) { - const Qt4ProFileNode * const qt4SubProject - = qobject_cast<const Qt4ProFileNode *>(subProject); - if (!qt4SubProject) - continue; - if (qt4SubProject->path().endsWith(QLatin1String(".pri"))) - continue; - if (!proFileNode->isSubProjectDeployable(subProject->path())) - continue; - createModels(qt4SubProject); - } - } - default: - break; - } -} - -void DeploymentInfo::setUnmodified() -{ - foreach (DeployableFilesPerProFile * const model, d->listModels) - model->setUnModified(); -} - -bool DeploymentInfo::isModified() const -{ - foreach (const DeployableFilesPerProFile * const model, d->listModels) { - if (model->isModified()) - return true; - } - return false; -} - -void DeploymentInfo::setInstallPrefix(const QString &installPrefix) -{ - d->installPrefix = installPrefix; - createModels(); -} - -int DeploymentInfo::deployableCount() const -{ - int count = 0; - foreach (const DeployableFilesPerProFile * const model, d->listModels) - count += model->rowCount(); - return count; -} - -DeployableFile DeploymentInfo::deployableAt(int i) const -{ - foreach (const DeployableFilesPerProFile * const model, d->listModels) { - Q_ASSERT(i >= 0); - if (i < model->rowCount()) - return model->deployableAt(i); - i -= model->rowCount(); - } - - Q_ASSERT(!"Invalid deployable number"); - return DeployableFile(QString(), QString()); -} - -QString DeploymentInfo::remoteExecutableFilePath(const QString &localExecutableFilePath) const -{ - foreach (const DeployableFilesPerProFile * const model, d->listModels) { - if (model->localExecutableFilePath() == localExecutableFilePath) - return model->remoteExecutableFilePath(); - } - return QString(); -} - -int DeploymentInfo::rowCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : modelCount(); -} - -QVariant DeploymentInfo::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.row() < 0 || index.row() >= modelCount() - || index.column() != 0) - return QVariant(); - const DeployableFilesPerProFile * const model = d->listModels.at(index.row()); - if (role == Qt::ForegroundRole && model->projectType() != AuxTemplate - && !model->hasTargetPath()) { - QBrush brush; - brush.setColor(Qt::red); - return brush; - } - if (role == Qt::DisplayRole) - return QFileInfo(model->proFilePath()).fileName(); - return QVariant(); -} - -int DeploymentInfo::modelCount() const { return d->listModels.count(); } -DeployableFilesPerProFile *DeploymentInfo::modelAt(int i) const { return d->listModels.at(i); } - -} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/deploymentsettingsassistant.cpp b/src/plugins/remotelinux/deploymentsettingsassistant.cpp deleted file mode 100644 index 6f77c5e152..0000000000 --- a/src/plugins/remotelinux/deploymentsettingsassistant.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ -#include "deploymentsettingsassistant.h" - -#include "deploymentinfo.h" -#include "deployablefile.h" -#include "deployablefilesperprofile.h" -#include "profilesupdatedialog.h" -#include "remotelinuxdeployconfiguration.h" - -#include <coreplugin/documentmanager.h> -#include <coreplugin/icore.h> -#include <projectexplorer/project.h> -#include <projectexplorer/target.h> -#include <qt4projectmanager/qt4nodes.h> -#include <utils/fileutils.h> -#include <utils/qtcassert.h> - -#include <QDir> -#include <QHash> -#include <QString> - -using namespace Qt4ProjectManager; - -namespace RemoteLinux { -namespace Internal { -namespace { - -enum ProFileUpdateSetting { UpdateProFile, DontUpdateProFile }; -typedef QHash<QString, ProFileUpdateSetting> UpdateSettingsMap; - -} // anonymous namespace - -class DeploymentSettingsAssistantInternal -{ -public: - DeploymentSettingsAssistantInternal(DeploymentInfo *deploymentInfo) - : deploymentInfo(deploymentInfo) - { - } - - DeploymentInfo * const deploymentInfo; - UpdateSettingsMap updateSettings; -}; - -} // namespace Internal - -using namespace Internal; - -DeploymentSettingsAssistant::DeploymentSettingsAssistant(DeploymentInfo *deploymentInfo, - ProjectExplorer::Project *parent) - : QObject(parent), - d(new DeploymentSettingsAssistantInternal(deploymentInfo)) -{ - connect(d->deploymentInfo, SIGNAL(modelReset()), SLOT(handleDeploymentInfoUpdated())); -} - -DeploymentSettingsAssistant::~DeploymentSettingsAssistant() -{ - delete d; -} - -bool DeploymentSettingsAssistant::addDeployableToProFile(const QString &qmakeScope, - const DeployableFilesPerProFile *proFileInfo, const QString &variableName, - const DeployableFile &deployable) -{ - const QString filesLine = variableName + QLatin1String(".files = ") - + QDir(proFileInfo->projectDir()).relativeFilePath(deployable.localFilePath); - const QString pathLine = variableName + QLatin1String(".path = ") + deployable.remoteDir; - const QString installsLine = QLatin1String("INSTALLS += ") + variableName; - return addLinesToProFile(qmakeScope, proFileInfo, - QStringList() << filesLine << pathLine << installsLine); -} - -bool DeploymentSettingsAssistant::addLinesToProFile(const QString &qmakeScope, - const DeployableFilesPerProFile *proFileInfo, - const QStringList &lines) -{ - Core::FileChangeBlocker update(proFileInfo->proFilePath()); - - const QString separator = QLatin1String("\n "); - const QString proFileString = QLatin1Char('\n') + qmakeScope + QLatin1String(" {") - + separator + lines.join(separator) + QLatin1String("\n}\n"); - Utils::FileSaver saver(proFileInfo->proFilePath(), QIODevice::Append); - saver.write(proFileString.toLocal8Bit()); - return saver.finalize(Core::ICore::mainWindow()); -} - -void DeploymentSettingsAssistant::handleDeploymentInfoUpdated() -{ - ProjectExplorer::Project *project = static_cast<ProjectExplorer::Project *>(parent()); - QStringList scopes; - QStringList pathes; - foreach (ProjectExplorer::Target *target, project->targets()) { - foreach (ProjectExplorer::DeployConfiguration *dc, target->deployConfigurations()) { - RemoteLinuxDeployConfiguration *rldc = qobject_cast<RemoteLinuxDeployConfiguration *>(dc); - if (!rldc) - continue; - const QString scope = rldc->qmakeScope(); - if (!scopes.contains(scope)) { - scopes.append(scope); - pathes.append(rldc->installPrefix()); - } - } - } - if (scopes.isEmpty()) - return; - - QList<DeployableFilesPerProFile *> proFilesToAskAbout; - QList<DeployableFilesPerProFile *> proFilesToUpdate; - for (int i = 0; i < d->deploymentInfo->modelCount(); ++i) { - DeployableFilesPerProFile * const proFileInfo = d->deploymentInfo->modelAt(i); - if (proFileInfo->projectType() != AuxTemplate && !proFileInfo->hasTargetPath()) { - const UpdateSettingsMap::ConstIterator it - = d->updateSettings.find(proFileInfo->proFilePath()); - if (it == d->updateSettings.constEnd()) - proFilesToAskAbout << proFileInfo; - else if (it.value() == UpdateProFile) - proFilesToUpdate << proFileInfo; - } - } - - if (!proFilesToAskAbout.isEmpty()) { - ProFilesUpdateDialog dialog(proFilesToAskAbout); - dialog.exec(); - const QList<ProFilesUpdateDialog::UpdateSetting> &settings = dialog.getUpdateSettings(); - foreach (const ProFilesUpdateDialog::UpdateSetting &setting, settings) { - const ProFileUpdateSetting updateSetting = setting.second - ? UpdateProFile : DontUpdateProFile; - d->updateSettings.insert(setting.first->proFilePath(), updateSetting); - if (updateSetting == UpdateProFile) - proFilesToUpdate << setting.first; - } - } - - foreach (const DeployableFilesPerProFile * const proFileInfo, proFilesToUpdate) { - const QString remoteDirSuffix = QLatin1String(proFileInfo->projectType() == LibraryTemplate - ? "/lib" : "/bin"); - for (int i = 0; i < scopes.count(); ++i) { - const QString remoteDir = QLatin1String("target.path = ") + pathes.at(i) - + QLatin1Char('/') + proFileInfo->projectName() + remoteDirSuffix; - const QStringList deployInfo = QStringList() << remoteDir - << QLatin1String("INSTALLS += target"); - addLinesToProFile(scopes.at(i), proFileInfo, deployInfo); - } - } -} - -} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/genericdirectuploadservice.cpp b/src/plugins/remotelinux/genericdirectuploadservice.cpp index 179401ba45..2a48256d3e 100644 --- a/src/plugins/remotelinux/genericdirectuploadservice.cpp +++ b/src/plugins/remotelinux/genericdirectuploadservice.cpp @@ -28,8 +28,7 @@ ****************************************************************************/ #include "genericdirectuploadservice.h" -#include "deployablefile.h" - +#include <projectexplorer/deployablefile.h> #include <utils/qtcassert.h> #include <ssh/sftpchannel.h> #include <ssh/sshconnection.h> @@ -40,6 +39,7 @@ #include <QList> #include <QString> +using namespace ProjectExplorer; using namespace QSsh; namespace RemoteLinux { @@ -163,8 +163,9 @@ void GenericDirectUploadService::handleUploadFinished(QSsh::SftpJobId jobId, con const DeployableFile df = d->filesToUpload.takeFirst(); if (!errorMsg.isEmpty()) { QString errorString = tr("Upload of file '%1' failed. The server said: '%2'.") - .arg(QDir::toNativeSeparators(df.localFilePath), errorMsg); - if (errorMsg == QLatin1String("Failure") && df.remoteDir.contains(QLatin1String("/bin"))) { + .arg(df.localFilePath().toUserOutput(), errorMsg); + if (errorMsg == QLatin1String("Failure") + && df.remoteDirectory().contains(QLatin1String("/bin"))) { errorString += QLatin1Char(' ') + tr("If '%1' is currently running " "on the remote host, you might need to stop it first.").arg(df.remoteFilePath()); } @@ -200,7 +201,7 @@ void GenericDirectUploadService::handleLnFinished(int exitStatus) } const DeployableFile df = d->filesToUpload.takeFirst(); - const QString nativePath = QDir::toNativeSeparators(df.localFilePath); + const QString nativePath = df.localFilePath().toUserOutput(); if (exitStatus != SshRemoteProcess::NormalExit || d->lnProc->exitCode() != 0) { emit errorMessage(tr("Failed to upload file '%1'.").arg(nativePath)); setFinished(); @@ -241,8 +242,8 @@ void GenericDirectUploadService::handleMkdirFinished(int exitStatus) } const DeployableFile &df = d->filesToUpload.first(); - QFileInfo fi(df.localFilePath); - const QString nativePath = QDir::toNativeSeparators(df.localFilePath); + QFileInfo fi = df.localFilePath().toFileInfo(); + const QString nativePath = df.localFilePath().toUserOutput(); if (exitStatus != SshRemoteProcess::NormalExit || d->mkdirProc->exitCode() != 0) { emit errorMessage(tr("Failed to upload file '%1'.").arg(nativePath)); setFinished(); @@ -252,7 +253,7 @@ void GenericDirectUploadService::handleMkdirFinished(int exitStatus) d->filesToUpload.removeFirst(); uploadNextFile(); } else { - const QString remoteFilePath = df.remoteDir + QLatin1Char('/') + fi.fileName(); + const QString remoteFilePath = df.remoteDirectory() + QLatin1Char('/') + fi.fileName(); if (fi.isSymLink()) { const QString target = fi.dir().relativeFilePath(fi.symLinkTarget()); // see QTBUG-5817. const QString command = QLatin1String("ln -sf ") + target + QLatin1Char(' ') @@ -265,8 +266,8 @@ void GenericDirectUploadService::handleMkdirFinished(int exitStatus) connect(d->lnProc.data(), SIGNAL(readyReadStandardError()), SLOT(handleStdErrData())); d->lnProc->start(); } else { - const SftpJobId job = d->uploader->uploadFile(df.localFilePath, remoteFilePath, - SftpOverwriteExisting); + const SftpJobId job = d->uploader->uploadFile(df.localFilePath().toString(), + remoteFilePath, SftpOverwriteExisting); if (job == SftpInvalidJob) { emit errorMessage(tr("Failed to upload file '%1': " "Could not open for reading.").arg(nativePath)); @@ -301,16 +302,16 @@ void GenericDirectUploadService::stopDeployment() void GenericDirectUploadService::checkDeploymentNeeded(const DeployableFile &deployable) const { - QFileInfo fileInfo(deployable.localFilePath); + QFileInfo fileInfo = deployable.localFilePath().toFileInfo(); if (fileInfo.isDir()) { - const QStringList files = QDir(deployable.localFilePath) + const QStringList files = QDir(deployable.localFilePath().toString()) .entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); if (files.isEmpty() && (!d->incremental || hasChangedSinceLastDeployment(deployable))) d->filesToUpload << deployable; foreach (const QString &fileName, files) { - const QString localFilePath = deployable.localFilePath + const QString localFilePath = deployable.localFilePath().toString() + QLatin1Char('/') + fileName; - const QString remoteDir = deployable.remoteDir + QLatin1Char('/') + const QString remoteDir = deployable.remoteDirectory() + QLatin1Char('/') + fileInfo.fileName(); checkDeploymentNeeded(DeployableFile(localFilePath, remoteDir)); } @@ -343,16 +344,16 @@ void GenericDirectUploadService::uploadNextFile() } const DeployableFile &df = d->filesToUpload.first(); - QString dirToCreate = df.remoteDir; + QString dirToCreate = df.remoteDirectory(); if (dirToCreate.isEmpty()) { emit warningMessage(tr("Warning: No remote path set for local file '%1'. Skipping upload.") - .arg(QDir::toNativeSeparators(df.localFilePath))); + .arg(df.localFilePath().toUserOutput())); d->filesToUpload.takeFirst(); uploadNextFile(); return; } - QFileInfo fi(df.localFilePath); + QFileInfo fi = df.localFilePath().toFileInfo(); if (fi.isDir()) dirToCreate += QLatin1Char('/') + fi.fileName(); const QString command = QLatin1String("mkdir -p ") + dirToCreate; @@ -361,7 +362,7 @@ void GenericDirectUploadService::uploadNextFile() connect(d->mkdirProc.data(), SIGNAL(readyReadStandardOutput()), SLOT(handleStdOutData())); connect(d->mkdirProc.data(), SIGNAL(readyReadStandardError()), SLOT(handleStdErrData())); emit progressMessage(tr("Uploading file '%1'...") - .arg(QDir::toNativeSeparators(df.localFilePath))); + .arg(df.localFilePath().toUserOutput())); d->mkdirProc->start(); } diff --git a/src/plugins/remotelinux/genericdirectuploadservice.h b/src/plugins/remotelinux/genericdirectuploadservice.h index e20a113fdb..90c6863740 100644 --- a/src/plugins/remotelinux/genericdirectuploadservice.h +++ b/src/plugins/remotelinux/genericdirectuploadservice.h @@ -38,8 +38,9 @@ QT_FORWARD_DECLARE_CLASS(QString) +namespace ProjectExplorer { class DeployableFile; } + namespace RemoteLinux { -class DeployableFile; namespace Internal { class GenericDirectUploadServicePrivate; } class REMOTELINUX_EXPORT GenericDirectUploadService : public AbstractRemoteLinuxDeployService @@ -49,7 +50,7 @@ public: GenericDirectUploadService(QObject *parent = 0); ~GenericDirectUploadService(); - void setDeployableFiles(const QList<DeployableFile> &deployableFiles); + void setDeployableFiles(const QList<ProjectExplorer::DeployableFile> &deployableFiles); void setIncrementalDeployment(bool incremental); protected: @@ -72,7 +73,7 @@ private slots: void handleStdErrData(); private: - void checkDeploymentNeeded(const DeployableFile &file) const; + void checkDeploymentNeeded(const ProjectExplorer::DeployableFile &file) const; void setFinished(); void uploadNextFile(); diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index bfcc05337d..773fbf3fdc 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -28,11 +28,12 @@ ****************************************************************************/ #include "genericdirectuploadstep.h" -#include "deployablefile.h" -#include "deploymentinfo.h" #include "genericdirectuploadservice.h" #include "remotelinuxdeployconfiguration.h" +#include <projectexplorer/deploymentdata.h> +#include <projectexplorer/target.h> + #include <QCheckBox> #include <QVBoxLayout> #include <QList> @@ -108,12 +109,7 @@ BuildStepConfigWidget *GenericDirectUploadStep::createConfigWidget() bool GenericDirectUploadStep::initInternal(QString *error) { - QList<DeployableFile> deployableFiles; - const DeploymentInfo * const deploymentInfo = deployConfiguration()->deploymentInfo(); - const int deployableCount = deploymentInfo->deployableCount(); - for (int i = 0; i < deployableCount; ++i) - deployableFiles << deploymentInfo->deployableAt(i); - deployService()->setDeployableFiles(deployableFiles); + deployService()->setDeployableFiles(target()->deploymentData().allFiles()); deployService()->setIncrementalDeployment(incrementalDeployment()); return deployService()->isDeploymentPossible(error); } diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp index a157dff4c8..0a1cc8ef67 100644 --- a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp @@ -77,6 +77,7 @@ GenericLinuxDeviceConfigurationWizard::~GenericLinuxDeviceConfigurationWizard() IDevice::Ptr GenericLinuxDeviceConfigurationWizard::device() { QSsh::SshConnectionParameters sshParams; + sshParams.options &= ~SshConnectionOptions(SshEnableStrictConformanceChecks); // For older SSH servers. sshParams.host = d->setupPage.hostName(); sshParams.userName = d->setupPage.userName(); sshParams.port = 22; diff --git a/src/plugins/remotelinux/profilesupdatedialog.cpp b/src/plugins/remotelinux/profilesupdatedialog.cpp deleted file mode 100644 index e04014814c..0000000000 --- a/src/plugins/remotelinux/profilesupdatedialog.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ -#include "profilesupdatedialog.h" -#include "ui_profilesupdatedialog.h" - -#include "deployablefilesperprofile.h" - -#include <qt4projectmanager/qt4nodes.h> - -#include <QDir> -#include <QTableWidgetItem> - -namespace RemoteLinux { -namespace Internal { - -ProFilesUpdateDialog::ProFilesUpdateDialog(const QList<DeployableFilesPerProFile *> &models, - QWidget *parent) - : QDialog(parent), - m_models(models), - ui(new Ui::ProFilesUpdateDialog) -{ - ui->setupUi(this); - ui->tableWidget->setRowCount(models.count()); - ui->tableWidget->setHorizontalHeaderItem(0, - new QTableWidgetItem(tr("Updateable Project Files"))); - for (int row = 0; row < models.count(); ++row) { - QTableWidgetItem *const item - = new QTableWidgetItem(QDir::toNativeSeparators(models.at(row)->proFilePath())); - item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - item->setCheckState(Qt::Unchecked); - ui->tableWidget->setItem(row, 0, item); - } - ui->tableWidget->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); - ui->tableWidget->resizeRowsToContents(); - connect(ui->checkAllButton, SIGNAL(clicked()), this, SLOT(checkAll())); - connect(ui->uncheckAllButton, SIGNAL(clicked()), this, SLOT(uncheckAll())); -} - -ProFilesUpdateDialog::~ProFilesUpdateDialog() -{ - delete ui; -} - -void ProFilesUpdateDialog::checkAll() -{ - setCheckStateForAll(Qt::Checked); -} - -void ProFilesUpdateDialog::uncheckAll() -{ - setCheckStateForAll(Qt::Unchecked); -} - -void ProFilesUpdateDialog::setCheckStateForAll(Qt::CheckState checkState) -{ - for (int row = 0; row < ui->tableWidget->rowCount(); ++row) { - ui->tableWidget->item(row, 0)->setCheckState(checkState); - } -} - -QList<ProFilesUpdateDialog::UpdateSetting> ProFilesUpdateDialog::getUpdateSettings() const -{ - QList<UpdateSetting> settings; - for (int row = 0; row < m_models.count(); ++row) { - const bool doUpdate = result() != Rejected - && ui->tableWidget->item(row, 0)->checkState() == Qt::Checked; - settings << UpdateSetting(m_models.at(row), doUpdate); - } - return settings; -} - -} // namespace RemoteLinux -} // namespace Internal diff --git a/src/plugins/remotelinux/profilesupdatedialog.ui b/src/plugins/remotelinux/profilesupdatedialog.ui deleted file mode 100644 index 7885a3f418..0000000000 --- a/src/plugins/remotelinux/profilesupdatedialog.ui +++ /dev/null @@ -1,139 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>RemoteLinux::Internal::ProFilesUpdateDialog</class> - <widget class="QDialog" name="RemoteLinux::Internal::ProFilesUpdateDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>659</width> - <height>494</height> - </rect> - </property> - <property name="windowTitle"> - <string>Maemo Deployment Issue</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="infoLabel"> - <property name="text"> - <string>The project files listed below do not contain deployment information, which means the respective targets cannot be deployed to and/or run on a device. Qt Creator will add the missing information to these files if you check the respective rows below.</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="checkAllButton"> - <property name="text"> - <string>&Check all</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="uncheckAllButton"> - <property name="text"> - <string>&Uncheck All</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="Line" name="line_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QTableWidget" name="tableWidget"> - <property name="showGrid"> - <bool>false</bool> - </property> - <property name="columnCount"> - <number>1</number> - </property> - <attribute name="horizontalHeaderDefaultSectionSize"> - <number>200</number> - </attribute> - <attribute name="horizontalHeaderStretchLastSection"> - <bool>true</bool> - </attribute> - <attribute name="verticalHeaderVisible"> - <bool>false</bool> - </attribute> - <column/> - </widget> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>RemoteLinux::Internal::ProFilesUpdateDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>RemoteLinux::Internal::ProFilesUpdateDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/src/plugins/remotelinux/remotelinux.pro b/src/plugins/remotelinux/remotelinux.pro index 6059ce60ab..aaa4162a03 100644 --- a/src/plugins/remotelinux/remotelinux.pro +++ b/src/plugins/remotelinux/remotelinux.pro @@ -21,9 +21,6 @@ HEADERS += \ remotelinuxruncontrolfactory.h \ remotelinuxdebugsupport.h \ genericlinuxdeviceconfigurationwizardpages.h \ - deployablefile.h \ - deployablefilesperprofile.h \ - deploymentinfo.h \ abstractremotelinuxdeploystep.h \ genericdirectuploadstep.h \ uploadandinstalltarpackagestep.h \ @@ -44,14 +41,13 @@ HEADERS += \ sshkeydeployer.h \ typespecificdeviceconfigurationlistmodel.h \ remotelinuxutils.h \ - deploymentsettingsassistant.h \ remotelinuxdeployconfigurationwidget.h \ - profilesupdatedialog.h \ remotelinuxcustomcommanddeployservice.h \ remotelinuxcustomcommanddeploymentstep.h \ genericlinuxdeviceconfigurationwidget.h \ remotelinuxcheckforfreediskspaceservice.h \ - remotelinuxcheckforfreediskspacestep.h + remotelinuxcheckforfreediskspacestep.h \ + remotelinuxdeploymentdatamodel.h SOURCES += \ embeddedlinuxqtversion.cpp \ @@ -68,8 +64,6 @@ SOURCES += \ remotelinuxruncontrolfactory.cpp \ remotelinuxdebugsupport.cpp \ genericlinuxdeviceconfigurationwizardpages.cpp \ - deployablefilesperprofile.cpp \ - deploymentinfo.cpp \ abstractremotelinuxdeploystep.cpp \ genericdirectuploadstep.cpp \ uploadandinstalltarpackagestep.cpp \ @@ -89,20 +83,18 @@ SOURCES += \ sshkeydeployer.cpp \ typespecificdeviceconfigurationlistmodel.cpp \ remotelinuxutils.cpp \ - deploymentsettingsassistant.cpp \ remotelinuxdeployconfigurationwidget.cpp \ - profilesupdatedialog.cpp \ remotelinuxcustomcommanddeployservice.cpp \ remotelinuxcustomcommanddeploymentstep.cpp \ genericlinuxdeviceconfigurationwidget.cpp \ remotelinuxcheckforfreediskspaceservice.cpp \ - remotelinuxcheckforfreediskspacestep.cpp + remotelinuxcheckforfreediskspacestep.cpp \ + remotelinuxdeploymentdatamodel.cpp FORMS += \ genericlinuxdeviceconfigurationwizardsetuppage.ui \ linuxdevicetestdialog.ui \ remotelinuxdeployconfigurationwidget.ui \ - profilesupdatedialog.ui \ genericlinuxdeviceconfigurationwidget.ui \ remotelinuxcheckforfreediskspacestepwidget.ui diff --git a/src/plugins/remotelinux/remotelinux.qbs b/src/plugins/remotelinux/remotelinux.qbs index 221172e322..8246f6b39d 100644 --- a/src/plugins/remotelinux/remotelinux.qbs +++ b/src/plugins/remotelinux/remotelinux.qbs @@ -9,61 +9,58 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "Debugger" } Depends { name: "ProjectExplorer" } - Depends { name: "Qt4ProjectManager" } Depends { name: "QtSupport" } Depends { name: "QtcSsh" } - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ "abstractpackagingstep.cpp", "abstractpackagingstep.h", "abstractremotelinuxdeployservice.cpp", "abstractremotelinuxdeployservice.h", + "abstractremotelinuxdeploystep.cpp", "abstractremotelinuxdeploystep.h", "abstractuploadandinstallpackageservice.cpp", "abstractuploadandinstallpackageservice.h", - "deployablefile.h", - "deployablefilesperprofile.cpp", - "deployablefilesperprofile.h", - "deploymentinfo.cpp", - "deploymentinfo.h", - "deploymentsettingsassistant.cpp", - "deploymentsettingsassistant.h", "embeddedlinuxqtversion.cpp", "embeddedlinuxqtversion.h", "embeddedlinuxqtversionfactory.cpp", "embeddedlinuxqtversionfactory.h", "genericdirectuploadservice.cpp", + "genericdirectuploadservice.h", + "genericdirectuploadstep.cpp", "genericdirectuploadstep.h", "genericlinuxdeviceconfigurationfactory.cpp", "genericlinuxdeviceconfigurationfactory.h", + "genericlinuxdeviceconfigurationwidget.cpp", + "genericlinuxdeviceconfigurationwidget.h", + "genericlinuxdeviceconfigurationwidget.ui", "genericlinuxdeviceconfigurationwizard.cpp", "genericlinuxdeviceconfigurationwizard.h", "genericlinuxdeviceconfigurationwizardpages.cpp", "genericlinuxdeviceconfigurationwizardpages.h", "genericlinuxdeviceconfigurationwizardsetuppage.ui", - "genericlinuxdeviceconfigurationwidget.cpp", - "genericlinuxdeviceconfigurationwidget.h", - "genericlinuxdeviceconfigurationwidget.ui", "genericremotelinuxdeploystepfactory.cpp", "genericremotelinuxdeploystepfactory.h", "linuxdevice.cpp", "linuxdevice.h", "linuxdevicetestdialog.cpp", "linuxdevicetestdialog.h", + "linuxdevicetestdialog.ui", "linuxdevicetester.cpp", "linuxdevicetester.h", + "packageuploader.cpp", + "packageuploader.h", "publickeydeploymentdialog.cpp", "publickeydeploymentdialog.h", "remotelinux.qrc", "remotelinux_constants.h", "remotelinux_export.h", + "remotelinuxcheckforfreediskspaceservice.cpp", + "remotelinuxcheckforfreediskspaceservice.h", + "remotelinuxcheckforfreediskspacestep.cpp", + "remotelinuxcheckforfreediskspacestep.h", + "remotelinuxcheckforfreediskspacestepwidget.ui", + "remotelinuxcustomcommanddeploymentstep.cpp", "remotelinuxcustomcommanddeploymentstep.h", "remotelinuxcustomcommanddeployservice.cpp", "remotelinuxcustomcommanddeployservice.h", @@ -75,7 +72,13 @@ QtcPlugin { "remotelinuxdeployconfigurationfactory.h", "remotelinuxdeployconfigurationwidget.cpp", "remotelinuxdeployconfigurationwidget.h", + "remotelinuxdeployconfigurationwidget.ui", + "remotelinuxdeploymentdatamodel.cpp", + "remotelinuxdeploymentdatamodel.h", + "remotelinuxenvironmentreader.cpp", + "remotelinuxenvironmentreader.h", "remotelinuxpackageinstaller.cpp", + "remotelinuxpackageinstaller.h", "remotelinuxplugin.cpp", "remotelinuxplugin.h", "remotelinuxrunconfiguration.cpp", @@ -84,40 +87,21 @@ QtcPlugin { "remotelinuxrunconfigurationfactory.h", "remotelinuxrunconfigurationwidget.cpp", "remotelinuxrunconfigurationwidget.h", + "remotelinuxruncontrol.cpp", "remotelinuxruncontrol.h", + "remotelinuxruncontrolfactory.cpp", + "remotelinuxruncontrolfactory.h", "remotelinuxutils.cpp", "remotelinuxutils.h", - "tarpackagecreationstep.h", - "uploadandinstalltarpackagestep.h", - "genericdirectuploadservice.h", - "linuxdevicetestdialog.ui", - "packageuploader.cpp", - "packageuploader.h", - "profilesupdatedialog.cpp", - "profilesupdatedialog.h", - "profilesupdatedialog.ui", - "remotelinuxdeployconfigurationwidget.ui", - "remotelinuxenvironmentreader.cpp", - "remotelinuxenvironmentreader.h", - "remotelinuxpackageinstaller.h", "sshkeydeployer.cpp", "sshkeydeployer.h", + "tarpackagecreationstep.cpp", + "tarpackagecreationstep.h", "typespecificdeviceconfigurationlistmodel.cpp", "typespecificdeviceconfigurationlistmodel.h", - "abstractremotelinuxdeploystep.cpp", - "genericdirectuploadstep.cpp", - "remotelinuxcustomcommanddeploymentstep.cpp", - "remotelinuxruncontrol.cpp", - "remotelinuxruncontrolfactory.cpp", - "remotelinuxruncontrolfactory.h", - "tarpackagecreationstep.cpp", "uploadandinstalltarpackagestep.cpp", - "remotelinuxcheckforfreediskspaceservice.h", - "remotelinuxcheckforfreediskspaceservice.cpp", - "remotelinuxcheckforfreediskspacestep.h", - "remotelinuxcheckforfreediskspacestep.cpp", - "remotelinuxcheckforfreediskspacestepwidget.ui", - "images/embeddedtarget.png" + "uploadandinstalltarpackagestep.h", + "images/embeddedtarget.png", ] ProductModule { diff --git a/src/plugins/remotelinux/remotelinux_dependencies.pri b/src/plugins/remotelinux/remotelinux_dependencies.pri index c2940f9362..697ec645a1 100644 --- a/src/plugins/remotelinux/remotelinux_dependencies.pri +++ b/src/plugins/remotelinux/remotelinux_dependencies.pri @@ -1,4 +1,4 @@ include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/debugger/debugger.pri) include(../../plugins/projectexplorer/projectexplorer.pri) -include(../../plugins/qt4projectmanager/qt4projectmanager.pri) +include(../../plugins/qtsupport/qtsupport.pri) diff --git a/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp b/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp index f54c84e6ed..d5f5bc8b73 100644 --- a/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp @@ -28,21 +28,12 @@ ****************************************************************************/ #include "remotelinuxdeployconfiguration.h" -#include "deploymentinfo.h" #include "remotelinuxdeployconfigurationwidget.h" -#include "typespecificdeviceconfigurationlistmodel.h" -#include <projectexplorer/devicesupport/devicemanager.h> #include <projectexplorer/project.h> #include <projectexplorer/target.h> -#include <qt4projectmanager/qt4project.h> using namespace ProjectExplorer; -using namespace Qt4ProjectManager; - -namespace { -const char DEPLOYMENT_INFO_SETTING[] = "RemoteLinux.DeploymentInfo"; -} // namespace namespace RemoteLinux { @@ -53,15 +44,6 @@ RemoteLinuxDeployConfiguration::RemoteLinuxDeployConfiguration(ProjectExplorer:: : DeployConfiguration(target, id) { setDefaultDisplayName(defaultDisplayName); - - // Make sure we have deploymentInfo, but create it only once: - DeploymentInfo *info - = qobject_cast<DeploymentInfo *>(target->project()->namedSettings(QLatin1String(DEPLOYMENT_INFO_SETTING)).value<QObject *>()); - if (!info) { - info = new DeploymentInfo(static_cast<Qt4ProjectManager::Qt4Project *>(target->project())); - QVariant data = QVariant::fromValue(static_cast<QObject *>(info)); - target->project()->setNamedSettings(QLatin1String(DEPLOYMENT_INFO_SETTING), data); - } } RemoteLinuxDeployConfiguration::RemoteLinuxDeployConfiguration(ProjectExplorer::Target *target, @@ -69,26 +51,9 @@ RemoteLinuxDeployConfiguration::RemoteLinuxDeployConfiguration(ProjectExplorer:: : DeployConfiguration(target, source) { } -DeploymentInfo *RemoteLinuxDeployConfiguration::deploymentInfo() const -{ - DeploymentInfo *info - = qobject_cast<DeploymentInfo *>(target()->project()->namedSettings(QLatin1String(DEPLOYMENT_INFO_SETTING)).value<QObject *>()); - return info; -} - -QString RemoteLinuxDeployConfiguration::qmakeScope() const -{ - return QLatin1String("unix"); -} - -QString RemoteLinuxDeployConfiguration::installPrefix() const -{ - return QString(); -} - -DeployConfigurationWidget *RemoteLinuxDeployConfiguration::configurationWidget() const +NamedWidget *RemoteLinuxDeployConfiguration::createConfigWidget() { - return new RemoteLinuxDeployConfigurationWidget; + return new RemoteLinuxDeployConfigurationWidget(this); } } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxdeployconfiguration.h b/src/plugins/remotelinux/remotelinuxdeployconfiguration.h index 02512becd4..410cd42c39 100644 --- a/src/plugins/remotelinux/remotelinuxdeployconfiguration.h +++ b/src/plugins/remotelinux/remotelinuxdeployconfiguration.h @@ -38,9 +38,6 @@ #include <projectexplorer/devicesupport/idevice.h> namespace RemoteLinux { -class AbstractEmbeddedLinuxTarget; -class DeploymentInfo; - namespace Internal { class RemoteLinuxDeployConfigurationFactory; } class REMOTELINUX_EXPORT RemoteLinuxDeployConfiguration @@ -54,9 +51,7 @@ public: RemoteLinuxDeployConfiguration(ProjectExplorer::Target *target, RemoteLinuxDeployConfiguration *source); - ProjectExplorer::DeployConfigurationWidget *configurationWidget() const; - - DeploymentInfo *deploymentInfo() const; + ProjectExplorer::NamedWidget *createConfigWidget(); template<class T> T *earlierBuildStep(const ProjectExplorer::BuildStep *laterBuildStep) const { @@ -70,9 +65,6 @@ public: return 0; } - virtual QString qmakeScope() const; - virtual QString installPrefix() const; - signals: void packagingChanged(); diff --git a/src/plugins/remotelinux/remotelinuxdeployconfigurationfactory.cpp b/src/plugins/remotelinux/remotelinuxdeployconfigurationfactory.cpp index e15dc56b89..94768e188a 100644 --- a/src/plugins/remotelinux/remotelinuxdeployconfigurationfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxdeployconfigurationfactory.cpp @@ -36,8 +36,8 @@ #include <projectexplorer/abi.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/project.h> #include <projectexplorer/target.h> -#include <qt4projectmanager/qt4project.h> #include <QCoreApplication> @@ -58,8 +58,6 @@ RemoteLinuxDeployConfigurationFactory::RemoteLinuxDeployConfigurationFactory(QOb QList<Core::Id> RemoteLinuxDeployConfigurationFactory::availableCreationIds(Target *parent) const { QList<Core::Id> ids; - if (!qobject_cast<Qt4ProjectManager::Qt4Project *>(parent->project())) - return ids; if (!parent->project()->supportsKit(parent->kit())) return ids; ProjectExplorer::ToolChain *tc diff --git a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.cpp b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.cpp index e4a53a4dae..05197c3a93 100644 --- a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.cpp +++ b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.cpp @@ -29,147 +29,55 @@ #include "remotelinuxdeployconfigurationwidget.h" #include "ui_remotelinuxdeployconfigurationwidget.h" -#include "deployablefilesperprofile.h" -#include "deploymentinfo.h" #include "remotelinuxdeployconfiguration.h" -#include "typespecificdeviceconfigurationlistmodel.h" +#include "remotelinuxdeploymentdatamodel.h" -#include <coreplugin/editormanager/editormanager.h> -#include <coreplugin/icore.h> -#include <coreplugin/id.h> -#include <projectexplorer/devicesupport/devicemanager.h> -#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/project.h> #include <projectexplorer/target.h> #include <utils/qtcassert.h> -#include <QTreeView> - using namespace ProjectExplorer; namespace RemoteLinux { namespace Internal { -namespace { -class MyTreeView : public QTreeView -{ - Q_OBJECT -public: - MyTreeView(QWidget *parent = 0) : QTreeView(parent) {} - -signals: - void doubleClicked(); - -private: - void mouseDoubleClickEvent(QMouseEvent *event) - { - emit doubleClicked(); - QTreeView::mouseDoubleClickEvent(event); - } -}; - -} // anonymous namespace class RemoteLinuxDeployConfigurationWidgetPrivate { public: Ui::RemoteLinuxDeployConfigurationWidget ui; - MyTreeView treeView; RemoteLinuxDeployConfiguration *deployConfiguration; + RemoteLinuxDeploymentDataModel deploymentDataModel; }; } // namespace Internal using namespace Internal; -RemoteLinuxDeployConfigurationWidget::RemoteLinuxDeployConfigurationWidget(QWidget *parent) : - DeployConfigurationWidget(parent), d(new RemoteLinuxDeployConfigurationWidgetPrivate) +RemoteLinuxDeployConfigurationWidget::RemoteLinuxDeployConfigurationWidget(RemoteLinuxDeployConfiguration *dc, + QWidget *parent) : + NamedWidget(parent), d(new RemoteLinuxDeployConfigurationWidgetPrivate) { d->ui.setupUi(this); - d->treeView.setTextElideMode(Qt::ElideMiddle); - d->treeView.setWordWrap(false); - d->treeView.setUniformRowHeights(true); - layout()->addWidget(&d->treeView); -} - -RemoteLinuxDeployConfigurationWidget::~RemoteLinuxDeployConfigurationWidget() -{ - delete d; -} - -void RemoteLinuxDeployConfigurationWidget::init(DeployConfiguration *dc) -{ - d->deployConfiguration = qobject_cast<RemoteLinuxDeployConfiguration *>(dc); - Q_ASSERT(d->deployConfiguration); - - connect(&d->treeView, SIGNAL(doubleClicked()), SLOT(openProjectFile())); - - d->ui.projectsComboBox->setModel(d->deployConfiguration->deploymentInfo()); - connect(d->deployConfiguration->deploymentInfo(), SIGNAL(modelAboutToBeReset()), - SLOT(handleModelListToBeReset())); + d->ui.deploymentDataView->setTextElideMode(Qt::ElideMiddle); + d->ui.deploymentDataView->setWordWrap(false); + d->ui.deploymentDataView->setUniformRowHeights(true); + d->ui.deploymentDataView->setModel(&d->deploymentDataModel); - // Queued connection because of race condition with combo box's reaction - // to modelReset(). - connect(d->deployConfiguration->deploymentInfo(), SIGNAL(modelReset()), - SLOT(handleModelListReset()), Qt::QueuedConnection); + d->deployConfiguration = dc; - connect(d->ui.projectsComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setModel(int))); - handleModelListReset(); + connect(dc->target(), SIGNAL(deploymentDataChanged()), SLOT(updateDeploymentDataModel())); + updateDeploymentDataModel(); } -RemoteLinuxDeployConfiguration *RemoteLinuxDeployConfigurationWidget::deployConfiguration() const -{ - return d->deployConfiguration; -} - -DeployableFilesPerProFile *RemoteLinuxDeployConfigurationWidget::currentModel() const -{ - const int modelRow = d->ui.projectsComboBox->currentIndex(); - if (modelRow == -1) - return 0; - return d->deployConfiguration->deploymentInfo()->modelAt(modelRow); -} - -void RemoteLinuxDeployConfigurationWidget::handleModelListToBeReset() -{ - d->treeView.setModel(0); -} - -void RemoteLinuxDeployConfigurationWidget::handleModelListReset() -{ - QTC_ASSERT(d->deployConfiguration->deploymentInfo()->modelCount() - == d->ui.projectsComboBox->count(), return); - - if (d->deployConfiguration->deploymentInfo()->modelCount() > 0) { - d->treeView.setToolTip(tr("Double-click to edit the project file")); - if (d->ui.projectsComboBox->currentIndex() == -1) - d->ui.projectsComboBox->setCurrentIndex(0); - else - setModel(d->ui.projectsComboBox->currentIndex()); - } else { - d->treeView.setToolTip(QString()); - } -} - -void RemoteLinuxDeployConfigurationWidget::setModel(int row) +RemoteLinuxDeployConfigurationWidget::~RemoteLinuxDeployConfigurationWidget() { - DeployableFilesPerProFile * const proFileInfo = row == -1 - ? 0 : d->deployConfiguration->deploymentInfo()->modelAt(row); - d->treeView.setModel(proFileInfo); - if (proFileInfo) - d->treeView.resizeColumnToContents(0); - emit currentModelChanged(proFileInfo); + delete d; } -void RemoteLinuxDeployConfigurationWidget::openProjectFile() +void RemoteLinuxDeployConfigurationWidget::updateDeploymentDataModel() { - const int row = d->ui.projectsComboBox->currentIndex(); - if (row == -1) - return; - const DeployableFilesPerProFile * const proFileInfo = - d->deployConfiguration->deploymentInfo()->modelAt(row); - Core::EditorManager::openEditor(proFileInfo->proFilePath(), Core::Id(), - Core::EditorManager::ModeSwitch); + d->deploymentDataModel.setDeploymentData(d->deployConfiguration->target()->deploymentData()); + d->ui.deploymentDataView->resizeColumnToContents(0); } } // namespace RemoteLinux - -#include "remotelinuxdeployconfigurationwidget.moc" diff --git a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.h b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.h index 5528011636..2571e4284c 100644 --- a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.h +++ b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.h @@ -34,7 +34,6 @@ #include <projectexplorer/deployconfiguration.h> namespace RemoteLinux { -class DeployableFilesPerProFile; class RemoteLinuxDeployConfiguration; namespace Internal { @@ -42,27 +41,17 @@ class RemoteLinuxDeployConfigurationWidgetPrivate; } // namespace Internal class REMOTELINUX_EXPORT RemoteLinuxDeployConfigurationWidget - : public ProjectExplorer::DeployConfigurationWidget + : public ProjectExplorer::NamedWidget { Q_OBJECT public: - explicit RemoteLinuxDeployConfigurationWidget(QWidget *parent = 0); + explicit RemoteLinuxDeployConfigurationWidget(RemoteLinux::RemoteLinuxDeployConfiguration *dc, + QWidget *parent = 0); ~RemoteLinuxDeployConfigurationWidget(); - void init(ProjectExplorer::DeployConfiguration *dc); - - RemoteLinuxDeployConfiguration *deployConfiguration() const; - DeployableFilesPerProFile *currentModel() const; - -signals: - void currentModelChanged(const RemoteLinux::DeployableFilesPerProFile *proFileInfo); - private slots: - void handleModelListToBeReset(); - void handleModelListReset(); - void setModel(int row); - void openProjectFile(); + void updateDeploymentDataModel(); private: Internal::RemoteLinuxDeployConfigurationWidgetPrivate * const d; diff --git a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.ui b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.ui index 2bfa1bd8a6..fb765741e9 100644 --- a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.ui +++ b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.ui @@ -15,45 +15,14 @@ </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <layout class="QFormLayout" name="formLayout"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Files to deploy:</string> </property> - <item row="0" column="0"> - <widget class="QLabel" name="installLabel"> - <property name="toolTip"> - <string>These show the INSTALLS settings from the project file(s).</string> - </property> - <property name="text"> - <string>Files to install for subproject:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QComboBox" name="projectsComboBox"> - <property name="sizeAdjustPolicy"> - <enum>QComboBox::AdjustToContents</enum> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> + </widget> + </item> + <item> + <widget class="QTreeView" name="deploymentDataView"/> </item> </layout> </widget> diff --git a/src/plugins/remotelinux/deploymentinfo.h b/src/plugins/remotelinux/remotelinuxdeploymentdatamodel.cpp index a97d11399d..f620fc01fb 100644 --- a/src/plugins/remotelinux/deploymentinfo.h +++ b/src/plugins/remotelinux/remotelinuxdeploymentdatamodel.cpp @@ -1,4 +1,4 @@ -/**************************************************************************** +/************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal @@ -27,55 +27,55 @@ ** ****************************************************************************/ -#ifndef DEPLOYMENTINFO_H -#define DEPLOYMENTINFO_H +#include "remotelinuxdeploymentdatamodel.h" -#include "remotelinux_export.h" +#include <QDir> -#include <QAbstractListModel> - -namespace ProjectExplorer { class Target; } -namespace Qt4ProjectManager { -class Qt4ProFileNode; -class Qt4Project; -} // namespace Qt4ProjectManager +using namespace ProjectExplorer; namespace RemoteLinux { -class DeployableFile; -class DeployableFilesPerProFile; -namespace Internal { -class DeploymentInfoPrivate; +RemoteLinuxDeploymentDataModel::RemoteLinuxDeploymentDataModel(QObject *parent) + : QAbstractTableModel(parent) +{ } -class REMOTELINUX_EXPORT DeploymentInfo : public QAbstractListModel +void RemoteLinuxDeploymentDataModel::setDeploymentData(const DeploymentData &deploymentData) { - Q_OBJECT -public: - DeploymentInfo(Qt4ProjectManager::Qt4Project *project, const QString &installPrefix = QString()); - ~DeploymentInfo(); + beginResetModel(); + m_deploymentData = deploymentData; + endResetModel(); +} - void setUnmodified(); - bool isModified() const; - void setInstallPrefix(const QString &installPrefix); - int deployableCount() const; - DeployableFile deployableAt(int i) const; - QString remoteExecutableFilePath(const QString &localExecutableFilePath) const; - int modelCount() const; - DeployableFilesPerProFile *modelAt(int i) const; +int RemoteLinuxDeploymentDataModel::rowCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : m_deploymentData.fileCount(); +} -private slots: - void createModels(); +int RemoteLinuxDeploymentDataModel::columnCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : 2; +} -private: - virtual int rowCount(const QModelIndex &parent) const; - virtual QVariant data(const QModelIndex &index, int role) const; +QVariant RemoteLinuxDeploymentDataModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (orientation == Qt::Vertical || role != Qt::DisplayRole) + return QVariant(); + return section == 0 ? tr("Local File Path") : tr("Remote Directory"); +} - void createModels(const Qt4ProjectManager::Qt4ProFileNode *proFileNode); +QVariant RemoteLinuxDeploymentDataModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount()) + return QVariant(); - Internal::DeploymentInfoPrivate * const d; -}; + const DeployableFile &d = m_deploymentData.fileAt(index.row()); + if (index.column() == 0 && role == Qt::DisplayRole) + return d.localFilePath().toUserOutput(); + if (role == Qt::DisplayRole) + return d.remoteDirectory(); + return QVariant(); +} } // namespace RemoteLinux - -#endif // DEPLOYMENTINFO_H diff --git a/src/plugins/remotelinux/profilesupdatedialog.h b/src/plugins/remotelinux/remotelinuxdeploymentdatamodel.h index 42393bd605..cb4cf6de75 100644 --- a/src/plugins/remotelinux/profilesupdatedialog.h +++ b/src/plugins/remotelinux/remotelinuxdeploymentdatamodel.h @@ -26,43 +26,32 @@ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ +#ifndef REMOTELINUXDEPLOYMENTDATAMODEL_H +#define REMOTELINUXDEPLOYMENTDATAMODEL_H -#ifndef PROFILESUPDATEDIALOG_H -#define PROFILESUPDATEDIALOG_H +#include <projectexplorer/deploymentdata.h> -#include <QList> -#include <QPair> -#include <QString> -#include <QDialog> +#include <QAbstractTableModel> namespace RemoteLinux { -class DeployableFilesPerProFile; -namespace Internal { -namespace Ui { class ProFilesUpdateDialog; } - -class ProFilesUpdateDialog : public QDialog +class RemoteLinuxDeploymentDataModel : public QAbstractTableModel { Q_OBJECT - public: - typedef QPair<DeployableFilesPerProFile *, bool> UpdateSetting; + explicit RemoteLinuxDeploymentDataModel(QObject *parent = 0); - explicit ProFilesUpdateDialog(const QList<DeployableFilesPerProFile *> &models, - QWidget *parent = 0); - ~ProFilesUpdateDialog(); - QList<UpdateSetting> getUpdateSettings() const; + void setDeploymentData(const ProjectExplorer::DeploymentData &deploymentData); private: - Q_SLOT void checkAll(); - Q_SLOT void uncheckAll(); - void setCheckStateForAll(Qt::CheckState checkState); + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - const QList<DeployableFilesPerProFile *> m_models; - Ui::ProFilesUpdateDialog *ui; + ProjectExplorer::DeploymentData m_deploymentData; }; } // namespace RemoteLinux -} // namespace Internal -#endif // PROFILESUPDATEDIALOG_H +#endif // REMOTELINUXDEPLOYMENTDATAMODEL_H diff --git a/src/plugins/remotelinux/remotelinuxplugin.cpp b/src/plugins/remotelinux/remotelinuxplugin.cpp index 38b3f9679f..0044f92404 100644 --- a/src/plugins/remotelinux/remotelinuxplugin.cpp +++ b/src/plugins/remotelinux/remotelinuxplugin.cpp @@ -30,10 +30,8 @@ #include "remotelinuxplugin.h" #include "embeddedlinuxqtversionfactory.h" -#include "deployablefile.h" #include "genericlinuxdeviceconfigurationfactory.h" #include "genericremotelinuxdeploystepfactory.h" -#include "qt4projectmanager/qt4projectmanagerconstants.h" #include "remotelinuxdeployconfigurationfactory.h" #include "remotelinuxrunconfigurationfactory.h" #include "remotelinuxruncontrolfactory.h" @@ -71,8 +69,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments, addAutoReleasedObject(new EmbeddedLinuxQtVersionFactory); - qRegisterMetaType<RemoteLinux::DeployableFile>("RemoteLinux::DeployableFile"); - return true; } diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp index f2fb2bcd10..9fce62be5a 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp @@ -29,23 +29,21 @@ #include "remotelinuxrunconfiguration.h" -#include "deploymentinfo.h" #include "remotelinuxdeployconfiguration.h" #include "remotelinuxrunconfigurationwidget.h" -#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/buildtargetinfo.h> +#include <projectexplorer/deploymentdata.h> +#include <projectexplorer/project.h> #include <projectexplorer/session.h> #include <projectexplorer/target.h> #include <projectexplorer/toolchain.h> #include <qtsupport/qtoutputformatter.h> -#include <qt4projectmanager/qt4nodes.h> -#include <qt4projectmanager/qt4project.h> #include <utils/portlist.h> #include <utils/qtcassert.h> using namespace ProjectExplorer; -using namespace Qt4ProjectManager; using namespace QSsh; using namespace Utils; @@ -65,38 +63,32 @@ const char WorkingDirectoryKey[] = "RemoteLinux.RunConfig.WorkingDirectory"; class RemoteLinuxRunConfigurationPrivate { public: - RemoteLinuxRunConfigurationPrivate(const QString &proFilePath, const ProjectExplorer::Target *target) - : proFilePath(proFilePath), + RemoteLinuxRunConfigurationPrivate(const QString &projectFilePath) + : projectFilePath(projectFilePath), baseEnvironmentType(RemoteLinuxRunConfiguration::RemoteBaseEnvironment), - validParse(false), - parseInProgress(true), useAlternateRemoteExecutable(false) { - validParse = static_cast<Qt4Project *>(target->project())->validParse(proFilePath); - parseInProgress = static_cast<Qt4Project *>(target->project())->parseInProgress(proFilePath); } RemoteLinuxRunConfigurationPrivate(const RemoteLinuxRunConfigurationPrivate *other) - : proFilePath(other->proFilePath), gdbPath(other->gdbPath), arguments(other->arguments), + : projectFilePath(other->projectFilePath), + gdbPath(other->gdbPath), + arguments(other->arguments), baseEnvironmentType(other->baseEnvironmentType), remoteEnvironment(other->remoteEnvironment), userEnvironmentChanges(other->userEnvironmentChanges), - validParse(other->validParse), - parseInProgress(other->parseInProgress), useAlternateRemoteExecutable(other->useAlternateRemoteExecutable), alternateRemoteExecutable(other->alternateRemoteExecutable), workingDirectory(other->workingDirectory) { } - QString proFilePath; + QString projectFilePath; QString gdbPath; QString arguments; RemoteLinuxRunConfiguration::BaseEnvironmentType baseEnvironmentType; Environment remoteEnvironment; QList<EnvironmentItem> userEnvironmentChanges; - bool validParse; - bool parseInProgress; QString disabledReason; bool useAlternateRemoteExecutable; QString alternateRemoteExecutable; @@ -110,7 +102,7 @@ using namespace Internal; RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *parent, const Core::Id id, const QString &proFilePath) : RunConfiguration(parent, id), - d(new RemoteLinuxRunConfigurationPrivate(proFilePath, parent)) + d(new RemoteLinuxRunConfigurationPrivate(proFilePath)) { init(); } @@ -133,34 +125,14 @@ void RemoteLinuxRunConfiguration::init() setDefaultDisplayName(defaultDisplayName()); debuggerAspect()->suppressQmlDebuggingSpinbox(); - connect(target(), - SIGNAL(activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration*)), - this, SLOT(handleDeployConfigChanged())); - handleDeployConfigChanged(); - - Project *pro = target()->project(); - connect(pro, SIGNAL(kitUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)), - this, SLOT(proFileUpdate(Qt4ProjectManager::Qt4ProFileNode*,bool,bool))); + connect(target(), SIGNAL(deploymentDataChanged()), SLOT(handleBuildSystemDataUpdated())); + connect(target(), SIGNAL(applicationTargetsChanged()), SLOT(handleBuildSystemDataUpdated())); connect(target(), SIGNAL(kitChanged()), - this, SLOT(handleDeployablesUpdated())); // Handles device changes, etc. + this, SLOT(handleBuildSystemDataUpdated())); // Handles device changes, etc. } bool RemoteLinuxRunConfiguration::isEnabled() const { - if (d->parseInProgress) { - d->disabledReason = tr("The .pro file '%1' is being parsed.") - .arg(QFileInfo(d->proFilePath).fileName()); - return false; - } - if (!d->validParse) { - Qt4Project *project = static_cast<Qt4Project *>(target()->project()); - d->disabledReason = project->disabledReasonForRunConfiguration(d->proFilePath); - return false; - } - if (!activeBuildConfiguration()) { - d->disabledReason = tr("No active build configuration."); - return false; - } if (remoteExecutableFilePath().isEmpty()) { d->disabledReason = tr("Don't know what to run."); return false; @@ -184,26 +156,12 @@ OutputFormatter *RemoteLinuxRunConfiguration::createOutputFormatter() const return new QtSupport::QtOutputFormatter(target()->project()); } -void RemoteLinuxRunConfiguration::proFileUpdate(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress) -{ - if (d->proFilePath == pro->path()) { - bool enabled = isEnabled(); - QString reason = disabledReason(); - d->validParse = success; - d->parseInProgress = parseInProgress; - if (enabled != isEnabled() || reason != disabledReason()) - updateEnabledState(); - if (!parseInProgress) - emit targetInformationChanged(); - } -} - QVariantMap RemoteLinuxRunConfiguration::toMap() const { QVariantMap map(RunConfiguration::toMap()); map.insert(QLatin1String(ArgumentsKey), d->arguments); const QDir dir = QDir(target()->project()->projectDirectory()); - map.insert(QLatin1String(ProFileKey), dir.relativeFilePath(d->proFilePath)); + map.insert(QLatin1String(ProFileKey), dir.relativeFilePath(d->projectFilePath)); map.insert(QLatin1String(BaseEnvironmentBaseKey), d->baseEnvironmentType); map.insert(QLatin1String(UserEnvironmentChangesKey), EnvironmentItem::toStringList(d->userEnvironmentChanges)); @@ -220,7 +178,8 @@ bool RemoteLinuxRunConfiguration::fromMap(const QVariantMap &map) d->arguments = map.value(QLatin1String(ArgumentsKey)).toString(); const QDir dir = QDir(target()->project()->projectDirectory()); - d->proFilePath = QDir::cleanPath(dir.filePath(map.value(QLatin1String(ProFileKey)).toString())); + d->projectFilePath + = QDir::cleanPath(dir.filePath(map.value(QLatin1String(ProFileKey)).toString())); d->userEnvironmentChanges = EnvironmentItem::fromStringList(map.value(QLatin1String(UserEnvironmentChangesKey)) .toStringList()); @@ -230,10 +189,6 @@ bool RemoteLinuxRunConfiguration::fromMap(const QVariantMap &map) d->alternateRemoteExecutable = map.value(QLatin1String(AlternateExeKey)).toString(); d->workingDirectory = map.value(QLatin1String(WorkingDirectoryKey)).toString(); - Qt4Project *project = static_cast<Qt4Project *>(target()->project()); - d->validParse = project->validParse(d->proFilePath); - d->parseInProgress = project->parseInProgress(d->proFilePath); - setDefaultDisplayName(defaultDisplayName()); return true; @@ -241,18 +196,13 @@ bool RemoteLinuxRunConfiguration::fromMap(const QVariantMap &map) QString RemoteLinuxRunConfiguration::defaultDisplayName() { - if (!d->proFilePath.isEmpty()) + if (!d->projectFilePath.isEmpty()) //: %1 is the name of a project which is being run on remote Linux - return tr("%1 (on Remote Device)").arg(QFileInfo(d->proFilePath).completeBaseName()); + return tr("%1 (on Remote Device)").arg(QFileInfo(d->projectFilePath).completeBaseName()); //: Remote Linux run configuration default display name return tr("Run on Remote Device"); } -RemoteLinuxDeployConfiguration *RemoteLinuxRunConfiguration::deployConfig() const -{ - return qobject_cast<RemoteLinuxDeployConfiguration *>(target()->activeDeployConfiguration()); -} - QString RemoteLinuxRunConfiguration::arguments() const { return d->arguments; @@ -280,19 +230,14 @@ QString RemoteLinuxRunConfiguration::commandPrefix() const QString RemoteLinuxRunConfiguration::localExecutableFilePath() const { - TargetInformation ti = static_cast<Qt4Project *>(target()->project())->rootQt4ProjectNode() - ->targetInformation(d->proFilePath); - if (!ti.valid) - return QString(); - - return QDir::cleanPath(ti.workingDir + QLatin1Char('/') + ti.target); + return target()->applicationTargets() + .targetForProject(Utils::FileName::fromString(d->projectFilePath)).toString(); } QString RemoteLinuxRunConfiguration::defaultRemoteExecutableFilePath() const { - return deployConfig() - ? deployConfig()->deploymentInfo()->remoteExecutableFilePath(localExecutableFilePath()) - : QString(); + return target()->deploymentData().deployableForLocalFile(localExecutableFilePath()) + .remoteFilePath(); } QString RemoteLinuxRunConfiguration::remoteExecutableFilePath() const @@ -347,17 +292,10 @@ int RemoteLinuxRunConfiguration::portsUsedByDebuggers() const return ports; } -void RemoteLinuxRunConfiguration::handleDeployConfigChanged() -{ - RemoteLinuxDeployConfiguration * const activeDeployConf = deployConfig(); - if (activeDeployConf) - connect(activeDeployConf->deploymentInfo(), SIGNAL(modelReset()), - SLOT(handleDeployablesUpdated()), Qt::UniqueConnection); -} - -void RemoteLinuxRunConfiguration::handleDeployablesUpdated() +void RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated() { emit deploySpecsChanged(); + emit targetInformationChanged(); updateEnabledState(); } @@ -432,9 +370,9 @@ void RemoteLinuxRunConfiguration::setRemoteEnvironment(const Environment &enviro } } -QString RemoteLinuxRunConfiguration::proFilePath() const +QString RemoteLinuxRunConfiguration::projectFilePath() const { - return d->proFilePath; + return d->projectFilePath; } void RemoteLinuxRunConfiguration::setDisabledReason(const QString &reason) const diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.h b/src/plugins/remotelinux/remotelinuxrunconfiguration.h index 980224f4ea..afd91c955d 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfiguration.h +++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.h @@ -35,10 +35,6 @@ #include <projectexplorer/runconfiguration.h> #include <utils/environment.h> -namespace Qt4ProjectManager { -class Qt4ProFileNode; -} // namespace Qt4ProjectManager - namespace Utils { class PortList; } namespace RemoteLinux { @@ -66,7 +62,7 @@ public: enum DebuggingType { DebugCppOnly, DebugQmlOnly, DebugCppAndQml }; RemoteLinuxRunConfiguration(ProjectExplorer::Target *parent, const Core::Id id, - const QString &proFilePath); + const QString &projectFilePath); ~RemoteLinuxRunConfiguration(); bool isEnabled() const; @@ -74,8 +70,6 @@ public: QWidget *createConfigurationWidget(); Utils::OutputFormatter *createOutputFormatter() const; - RemoteLinuxDeployConfiguration *deployConfig() const; - virtual QString environmentPreparationCommand() const; virtual QString commandPrefix() const; @@ -102,7 +96,7 @@ public: int portsUsedByDebuggers() const; - QString proFilePath() const; + QString projectFilePath() const; static const QString IdPrefix; @@ -125,9 +119,7 @@ protected slots: void updateEnabledState() { emit enabledChanged(); } private slots: - void proFileUpdate(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress); - void handleDeployConfigChanged(); - void handleDeployablesUpdated(); + void handleBuildSystemDataUpdated(); private: void init(); diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp index 89f0ac6819..6d48536bb5 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp @@ -29,14 +29,12 @@ #include "remotelinuxrunconfigurationfactory.h" #include "remotelinux_constants.h" -#include "remotelinuxdeployconfigurationfactory.h" #include "remotelinuxrunconfiguration.h" +#include <projectexplorer/buildtargetinfo.h> #include <projectexplorer/kitinformation.h> +#include <projectexplorer/project.h> #include <projectexplorer/target.h> -#include <qt4projectmanager/qt4project.h> -#include <qt4projectmanager/qt4nodes.h> -#include <qtsupport/customexecutablerunconfiguration.h> #include <utils/qtcassert.h> #include <QFileInfo> @@ -44,7 +42,6 @@ #include <QStringList> using namespace ProjectExplorer; -using namespace Qt4ProjectManager; namespace RemoteLinux { namespace Internal { @@ -61,8 +58,10 @@ QString pathFromId(Core::Id id) } // namespace RemoteLinuxRunConfigurationFactory::RemoteLinuxRunConfigurationFactory(QObject *parent) - : Qt4ProjectManager::QmakeRunConfigurationFactory(parent) -{ setObjectName(QLatin1String("RemoteLinuxRunConfigurationFactory")); } + : IRunConfigurationFactory(parent) +{ + setObjectName(QLatin1String("RemoteLinuxRunConfigurationFactory")); +} RemoteLinuxRunConfigurationFactory::~RemoteLinuxRunConfigurationFactory() { @@ -72,14 +71,14 @@ bool RemoteLinuxRunConfigurationFactory::canCreate(Target *parent, const Core::I { if (!canHandle(parent)) return false; - return static_cast<Qt4Project *>(parent->project())->hasApplicationProFile(pathFromId(id)); + return !parent->applicationTargets().targetForProject(pathFromId(id)).isEmpty(); } bool RemoteLinuxRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const { if (!canHandle(parent)) return false; - return ProjectExplorer::idFromMap(map).toString().startsWith(RemoteLinuxRunConfiguration::IdPrefix); + return idFromMap(map).toString().startsWith(RemoteLinuxRunConfiguration::IdPrefix); } bool RemoteLinuxRunConfigurationFactory::canClone(Target *parent, RunConfiguration *source) const @@ -95,10 +94,8 @@ QList<Core::Id> RemoteLinuxRunConfigurationFactory::availableCreationIds(Target if (!canHandle(parent)) return result; - QStringList proFiles = static_cast<Qt4Project *>(parent->project()) - ->applicationProFilePathes(RemoteLinuxRunConfiguration::IdPrefix); - foreach (const QString &pf, proFiles) - result << Core::Id(pf); + foreach (const BuildTargetInfo &bti, parent->applicationTargets().list) + result << (Core::Id(RemoteLinuxRunConfiguration::IdPrefix + bti.projectFilePath.toString())); return result; } @@ -118,8 +115,8 @@ RunConfiguration *RemoteLinuxRunConfigurationFactory::restore(Target *parent, const QVariantMap &map) { QTC_ASSERT(canRestore(parent, map), return 0); - RemoteLinuxRunConfiguration *rc - = new RemoteLinuxRunConfiguration(parent, Core::Id(RemoteLinuxRunConfiguration::IdPrefix), QString()); + RemoteLinuxRunConfiguration *rc = new RemoteLinuxRunConfiguration(parent, + Core::Id(RemoteLinuxRunConfiguration::IdPrefix), QString()); if (rc->fromMap(map)) return rc; @@ -135,26 +132,13 @@ RunConfiguration *RemoteLinuxRunConfigurationFactory::clone(Target *parent, return new RemoteLinuxRunConfiguration(parent, old); } -bool RemoteLinuxRunConfigurationFactory::canHandle(Target *t) const +bool RemoteLinuxRunConfigurationFactory::canHandle(const Target *target) const { - if (!t->project()->supportsKit(t->kit())) + if (!target->project()->supportsKit(target->kit())) return false; - if (!qobject_cast<Qt4Project *>(t->project())) - return false; - - Core::Id deviceType = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(t->kit()); + const Core::Id deviceType = DeviceTypeKitInformation::deviceTypeId(target->kit()); return deviceType == RemoteLinux::Constants::GenericLinuxOsType; } -QList<RunConfiguration *> RemoteLinuxRunConfigurationFactory::runConfigurationsForNode(Target *t, ProjectExplorer::Node *n) -{ - QList<ProjectExplorer::RunConfiguration *> result; - foreach (ProjectExplorer::RunConfiguration *rc, t->runConfigurations()) - if (RemoteLinuxRunConfiguration *qt4c = qobject_cast<RemoteLinuxRunConfiguration *>(rc)) - if (qt4c->proFilePath() == n->path()) - result << rc; - return result; -} - } // namespace Internal } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.h b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.h index 4a281e775b..4cd8b85dc7 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.h +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.h @@ -30,14 +30,11 @@ #define REMOTELINUXRUNCONFIGURATIONFACTORY_H #include <projectexplorer/runconfiguration.h> -#include <qt4projectmanager/qmakerunconfigurationfactory.h> - -namespace ProjectExplorer { class Node; } namespace RemoteLinux { namespace Internal { -class RemoteLinuxRunConfigurationFactory : public Qt4ProjectManager::QmakeRunConfigurationFactory +class RemoteLinuxRunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory { Q_OBJECT @@ -59,9 +56,8 @@ public: ProjectExplorer::RunConfiguration *clone(ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *source); - bool canHandle(ProjectExplorer::Target *t) const; - QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Target *t, - ProjectExplorer::Node *n); +private: + bool canHandle(const ProjectExplorer::Target *target) const; }; } // namespace Internal diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp index 08abe3ee1f..47e1f7ba41 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp @@ -229,13 +229,23 @@ void RemoteLinuxRunConfigurationWidget::argumentsEdited(const QString &text) void RemoteLinuxRunConfigurationWidget::updateTargetInformation() { - d->localExecutableLabel - .setText(QDir::toNativeSeparators(d->runConfiguration->localExecutableFilePath())); + setLabelText(d->localExecutableLabel, + QDir::toNativeSeparators(d->runConfiguration->localExecutableFilePath()), + tr("Unknown")); } void RemoteLinuxRunConfigurationWidget::handleDeploySpecsChanged() { - d->remoteExecutableLabel.setText(d->runConfiguration->defaultRemoteExecutableFilePath()); + setLabelText(d->remoteExecutableLabel, d->runConfiguration->defaultRemoteExecutableFilePath(), + tr("Remote path not set")); +} + +void RemoteLinuxRunConfigurationWidget::setLabelText(QLabel &label, const QString ®ularText, + const QString &errorText) +{ + const QString errorMessage = QLatin1String("<font color=\"red\">") + errorText + + QLatin1String("</font>"); + label.setText(regularText.isEmpty() ? errorMessage : regularText); } void RemoteLinuxRunConfigurationWidget::handleUseAlternateCommandChanged() diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h index bfe20ea023..be45305150 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h @@ -34,6 +34,7 @@ #include <QWidget> QT_BEGIN_NAMESPACE +class QLabel; class QVBoxLayout; QT_END_NAMESPACE @@ -79,6 +80,7 @@ private slots: private: void addGenericWidgets(QVBoxLayout *mainLayout); void addEnvironmentWidgets(QVBoxLayout *mainLayout); + void setLabelText(QLabel &label, const QString ®ularText, const QString &errorText); Internal::RemoteLinuxRunConfigurationWidgetPrivate * const d; }; diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp index 4defbc848a..3f6fff6c19 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.cpp +++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp @@ -28,10 +28,9 @@ ****************************************************************************/ #include "tarpackagecreationstep.h" -#include "deployablefile.h" -#include "deploymentinfo.h" #include "remotelinuxdeployconfiguration.h" +#include <projectexplorer/deploymentdata.h> #include <projectexplorer/project.h> #include <projectexplorer/target.h> @@ -40,6 +39,8 @@ #include <QFile> #include <QFileInfo> +#include <cstring> + using namespace ProjectExplorer; namespace RemoteLinux { @@ -112,13 +113,8 @@ bool TarPackageCreationStep::init() if (!AbstractPackagingStep::init()) return false; m_packagingNeeded = isPackagingNeeded(); - if (!m_packagingNeeded) - return true; - - const DeploymentInfo * const deploymentInfo = deployConfiguration()->deploymentInfo(); - for (int i = 0; i < deploymentInfo->deployableCount(); ++i) - m_files.append(deploymentInfo->deployableAt(i)); - + if (m_packagingNeeded) + m_files = target()->deploymentData().allFiles(); return true; } @@ -152,13 +148,13 @@ bool TarPackageCreationStep::doPackage(QFutureInterface<bool> &fi) } foreach (const DeployableFile &d, m_files) { - if (d.remoteDir.isEmpty()) { + if (d.remoteDirectory().isEmpty()) { emit addOutput(tr("No remote path specified for file '%1', skipping.") - .arg(QDir::toNativeSeparators(d.localFilePath)), ErrorMessageOutput); + .arg(d.localFilePath().toUserOutput()), ErrorMessageOutput); continue; } - QFileInfo fileInfo(d.localFilePath); - if (!appendFile(tarFile, fileInfo, d.remoteDir + QLatin1Char('/') + QFileInfo fileInfo = d.localFilePath().toFileInfo(); + if (!appendFile(tarFile, fileInfo, d.remoteDirectory() + QLatin1Char('/') + fileInfo.fileName(), fi)) { return false; } @@ -230,7 +226,7 @@ bool TarPackageCreationStep::writeHeader(QFile &tarFile, const QFileInfo &fileIn const QString &remoteFilePath) { TarFileHeader header; - qMemSet(&header, '\0', sizeof header); + std::memset(&header, '\0', sizeof header); const QByteArray &filePath = remoteFilePath.toUtf8(); const int maxFilePathLength = sizeof header.fileNamePrefix + sizeof header.fileName; if (filePath.count() > maxFilePathLength) { @@ -241,9 +237,9 @@ bool TarPackageCreationStep::writeHeader(QFile &tarFile, const QFileInfo &fileIn const int fileNameBytesToWrite = qMin<int>(filePath.length(), sizeof header.fileName); const int fileNameOffset = filePath.length() - fileNameBytesToWrite; - qMemCopy(&header.fileName, filePath.data() + fileNameOffset, fileNameBytesToWrite); + std::memcpy(&header.fileName, filePath.data() + fileNameOffset, fileNameBytesToWrite); if (fileNameOffset > 0) - qMemCopy(&header.fileNamePrefix, filePath.data(), fileNameOffset); + std::memcpy(&header.fileNamePrefix, filePath.data(), fileNameOffset); int permissions = (0400 * fileInfo.permission(QFile::ReadOwner)) | (0200 * fileInfo.permission(QFile::WriteOwner)) | (0100 * fileInfo.permission(QFile::ExeOwner)) @@ -254,35 +250,35 @@ bool TarPackageCreationStep::writeHeader(QFile &tarFile, const QFileInfo &fileIn | (02 * fileInfo.permission(QFile::WriteOther)) | (01 * fileInfo.permission(QFile::ExeOther)); const QByteArray permissionString = QString("%1").arg(permissions, - sizeof header.fileMode - 1, 8, QLatin1Char('0')).toAscii(); - qMemCopy(&header.fileMode, permissionString.data(), permissionString.length()); + sizeof header.fileMode - 1, 8, QLatin1Char('0')).toLatin1(); + std::memcpy(&header.fileMode, permissionString.data(), permissionString.length()); const QByteArray uidString = QString("%1").arg(fileInfo.ownerId(), - sizeof header.uid - 1, 8, QLatin1Char('0')).toAscii(); - qMemCopy(&header.uid, uidString.data(), uidString.length()); + sizeof header.uid - 1, 8, QLatin1Char('0')).toLatin1(); + std::memcpy(&header.uid, uidString.data(), uidString.length()); const QByteArray gidString = QString("%1").arg(fileInfo.groupId(), - sizeof header.gid - 1, 8, QLatin1Char('0')).toAscii(); - qMemCopy(&header.gid, gidString.data(), gidString.length()); + sizeof header.gid - 1, 8, QLatin1Char('0')).toLatin1(); + std::memcpy(&header.gid, gidString.data(), gidString.length()); const QByteArray sizeString = QString("%1").arg(fileInfo.size(), - sizeof header.length - 1, 8, QLatin1Char('0')).toAscii(); - qMemCopy(&header.length, sizeString.data(), sizeString.length()); + sizeof header.length - 1, 8, QLatin1Char('0')).toLatin1(); + std::memcpy(&header.length, sizeString.data(), sizeString.length()); const QByteArray mtimeString = QString("%1").arg(fileInfo.lastModified().toTime_t(), - sizeof header.mtime - 1, 8, QLatin1Char('0')).toAscii(); - qMemCopy(&header.mtime, mtimeString.data(), mtimeString.length()); + sizeof header.mtime - 1, 8, QLatin1Char('0')).toLatin1(); + std::memcpy(&header.mtime, mtimeString.data(), mtimeString.length()); if (fileInfo.isDir()) header.typeflag = '5'; - qMemCopy(&header.magic, "ustar", sizeof "ustar"); - qMemCopy(&header.version, "00", 2); + std::memcpy(&header.magic, "ustar", sizeof "ustar"); + std::memcpy(&header.version, "00", 2); const QByteArray &owner = fileInfo.owner().toUtf8(); - qMemCopy(&header.uname, owner.data(), qMin<int>(owner.length(), sizeof header.uname - 1)); + std::memcpy(&header.uname, owner.data(), qMin<int>(owner.length(), sizeof header.uname - 1)); const QByteArray &group = fileInfo.group().toUtf8(); - qMemCopy(&header.gname, group.data(), qMin<int>(group.length(), sizeof header.gname - 1)); - qMemSet(&header.chksum, ' ', sizeof header.chksum); + std::memcpy(&header.gname, group.data(), qMin<int>(group.length(), sizeof header.gname - 1)); + std::memset(&header.chksum, ' ', sizeof header.chksum); quint64 checksum = 0; for (size_t i = 0; i < sizeof header; ++i) checksum += reinterpret_cast<char *>(&header)[i]; const QByteArray checksumString = QString("%1").arg(checksum, - sizeof header.chksum - 1, 8, QLatin1Char('0')).toAscii(); - qMemCopy(&header.chksum, checksumString.data(), checksumString.length()); + sizeof header.chksum - 1, 8, QLatin1Char('0')).toLatin1(); + std::memcpy(&header.chksum, checksumString.data(), checksumString.length()); header.chksum[sizeof header.chksum-1] = 0; if (!tarFile.write(reinterpret_cast<char *>(&header), sizeof header)) { raiseError(tr("Error writing tar file '%1': %2") diff --git a/src/plugins/remotelinux/tarpackagecreationstep.h b/src/plugins/remotelinux/tarpackagecreationstep.h index 335dc25e1e..29d5335d67 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.h +++ b/src/plugins/remotelinux/tarpackagecreationstep.h @@ -31,7 +31,8 @@ #include "abstractpackagingstep.h" #include "remotelinux_export.h" -#include "deployablefile.h" + +#include <projectexplorer/deployablefile.h> QT_BEGIN_NAMESPACE class QFile; @@ -65,7 +66,7 @@ private: const QString &remoteFilePath); bool m_packagingNeeded; - QList<DeployableFile> m_files; + QList<ProjectExplorer::DeployableFile> m_files; }; } // namespace RemoteLinux diff --git a/src/plugins/resourceeditor/qrceditor/resourcefile.cpp b/src/plugins/resourceeditor/qrceditor/resourcefile.cpp index deabeb28e2..e28c7fafb5 100644 --- a/src/plugins/resourceeditor/qrceditor/resourcefile.cpp +++ b/src/plugins/resourceeditor/qrceditor/resourcefile.cpp @@ -698,7 +698,7 @@ bool ResourceModel::iconFileExtension(const QString &path) const QList<QByteArray> _ext_list = QImageReader::supportedImageFormats(); foreach (const QByteArray &ext, _ext_list) { QString dotExt = QString(QLatin1Char('.')); - dotExt += QString::fromAscii(ext); + dotExt += QString::fromLatin1(ext); ext_list.append(dotExt); } } @@ -1091,10 +1091,11 @@ QModelIndex ResourceModel::deleteItem(const QModelIndex &idx) bool ResourceModel::reload() { + beginResetModel(); const bool result = m_resource_file.load(); if (result) setDirty(false); - reset(); + endResetModel(); return result; } diff --git a/src/plugins/resourceeditor/resourceeditor.qbs b/src/plugins/resourceeditor/resourceeditor.qbs index 68dc1df8bc..889bd951f2 100644 --- a/src/plugins/resourceeditor/resourceeditor.qbs +++ b/src/plugins/resourceeditor/resourceeditor.qbs @@ -10,14 +10,7 @@ QtcPlugin { Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["widgets", "xml"] } - cpp.includePaths: [ - "..", - "../..", - "../../libs", - buildDirectory, - "qrceditor", - "../../tools/utils" - ] + cpp.includePaths: base.concat("qrceditor") files: [ "ResourceEditor.mimetypes.xml", @@ -31,15 +24,14 @@ QtcPlugin { "resourceeditorw.h", "resourcewizard.cpp", "resourcewizard.h", - "qrceditor/resourcefile.cpp", - "qrceditor/resourceview.cpp", "qrceditor/qrceditor.cpp", - "qrceditor/undocommands.cpp", + "qrceditor/qrceditor.h", + "qrceditor/qrceditor.ui", + "qrceditor/resourcefile.cpp", "qrceditor/resourcefile_p.h", + "qrceditor/resourceview.cpp", "qrceditor/resourceview.h", - "qrceditor/qrceditor.h", + "qrceditor/undocommands.cpp", "qrceditor/undocommands_p.h", - "qrceditor/qrceditor.ui" ] } - diff --git a/src/plugins/resourceeditor/resourceeditorfactory.cpp b/src/plugins/resourceeditor/resourceeditorfactory.cpp index 27ae0e5cf1..0dc0027181 100644 --- a/src/plugins/resourceeditor/resourceeditorfactory.cpp +++ b/src/plugins/resourceeditor/resourceeditorfactory.cpp @@ -54,7 +54,7 @@ ResourceEditorFactory::ResourceEditorFactory(ResourceEditorPlugin *plugin) : Core::Id ResourceEditorFactory::id() const { - return RESOURCEEDITOR_ID; + return Core::Id(RESOURCEEDITOR_ID); } QString ResourceEditorFactory::displayName() const diff --git a/src/plugins/subversion/subversion.qbs b/src/plugins/subversion/subversion.qbs index bed2a9aea3..ed5571e47c 100644 --- a/src/plugins/subversion/subversion.qbs +++ b/src/plugins/subversion/subversion.qbs @@ -12,35 +12,28 @@ QtcPlugin { Depends { name: "VcsBase" } Depends { name: "Locator" } - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ + "annotationhighlighter.cpp", "annotationhighlighter.h", - "subversionplugin.h", - "subversioncontrol.h", - "settingspage.h", - "subversioneditor.h", - "subversionsubmiteditor.h", - "subversionsettings.h", + "checkoutwizard.cpp", "checkoutwizard.h", + "checkoutwizardpage.cpp", "checkoutwizardpage.h", + "settingspage.cpp", + "settingspage.h", + "settingspage.ui", + "subversion.qrc", "subversionconstants.h", - "annotationhighlighter.cpp", - "subversionplugin.cpp", "subversioncontrol.cpp", - "settingspage.cpp", + "subversioncontrol.h", "subversioneditor.cpp", - "subversionsubmiteditor.cpp", + "subversioneditor.h", + "subversionplugin.cpp", + "subversionplugin.h", "subversionsettings.cpp", - "checkoutwizard.cpp", - "checkoutwizardpage.cpp", - "settingspage.ui", - "subversion.qrc" + "subversionsettings.h", + "subversionsubmiteditor.cpp", + "subversionsubmiteditor.h", ] } diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp index 88807a3b52..788e1fd176 100644 --- a/src/plugins/subversion/subversioncontrol.cpp +++ b/src/plugins/subversion/subversioncontrol.cpp @@ -50,7 +50,7 @@ QString SubversionControl::displayName() const Core::Id SubversionControl::id() const { - return VcsBase::Constants::VCS_ID_SUBVERSION; + return Core::Id(VcsBase::Constants::VCS_ID_SUBVERSION); } bool SubversionControl::isConfigured() const diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index cf2b7fcb2d..bf4768c218 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -45,6 +45,7 @@ #include <utils/synchronousprocess.h> #include <utils/parameteraction.h> #include <utils/fileutils.h> +#include <utils/hostosinfo.h> #include <coreplugin/icore.h> #include <coreplugin/coreconstants.h> @@ -141,7 +142,7 @@ static inline const VcsBase::VcsBaseEditorParameters *findType(int ie) static inline QString debugCodec(const QTextCodec *c) { - return c ? QString::fromAscii(c->name()) : QString::fromAscii("Null codec"); + return c ? QString::fromLatin1(c->name()) : QString::fromLatin1("Null codec"); } // Parse "svn status" output for added/modified/deleted files @@ -171,10 +172,9 @@ StatusList parseStatusOutput(const QString &output) static inline QStringList svnDirectories() { QStringList rc(QLatin1String(".svn")); -#ifdef Q_OS_WIN - // Option on Windows systems to avoid hassle with some IDEs - rc.push_back(QLatin1String("_svn")); -#endif + if (Utils::HostOsInfo::isWindowsHost()) + // Option on Windows systems to avoid hassle with some IDEs + rc.push_back(QLatin1String("_svn")); return rc; } @@ -1145,7 +1145,7 @@ Core::IEditor *SubversionPlugin::showOutputInEditor(const QString &title, const { const VcsBase::VcsBaseEditorParameters *params = findType(editorType); QTC_ASSERT(params, return 0); - const Core::Id id = params->id; + const Core::Id id = Core::Id(QByteArray(params->id)); if (Subversion::Constants::debug) qDebug() << "SubversionPlugin::showOutputInEditor" << title << id.name() << "Size= " << output.size() << " Type=" << editorType << debugCodec(codec); @@ -1190,11 +1190,9 @@ SubversionPlugin *SubversionPlugin::instance() bool SubversionPlugin::vcsAdd(const QString &workingDir, const QString &rawFileName) { -#ifdef Q_OS_MAC // See below. - return vcsAdd14(workingDir, rawFileName); -#else + if (Utils::HostOsInfo::isMacHost()) // See below. + return vcsAdd14(workingDir, rawFileName); return vcsAdd15(workingDir, rawFileName); -#endif } // Post 1.4 add: Use "--parents" to add directories diff --git a/src/plugins/subversion/subversionsettings.cpp b/src/plugins/subversion/subversionsettings.cpp index 621ab52057..a323cbacef 100644 --- a/src/plugins/subversion/subversionsettings.cpp +++ b/src/plugins/subversion/subversionsettings.cpp @@ -30,6 +30,7 @@ #include "subversionsettings.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <QSettings> @@ -48,12 +49,7 @@ enum { defaultTimeOutS = 30, defaultLogCount = 1000 }; static QString defaultCommand() { - QString rc; - rc = QLatin1String("svn"); -#if defined(Q_OS_WIN32) - rc.append(QLatin1String(".exe")); -#endif - return rc; + return QLatin1String("svn" QTC_HOST_EXE_SUFFIX); } using namespace Subversion::Internal; diff --git a/src/plugins/tasklist/taskfilefactory.cpp b/src/plugins/tasklist/taskfilefactory.cpp index e00aeb4c86..fcc02b5904 100644 --- a/src/plugins/tasklist/taskfilefactory.cpp +++ b/src/plugins/tasklist/taskfilefactory.cpp @@ -59,7 +59,7 @@ QStringList TaskFileFactory::mimeTypes() const Core::Id TaskFileFactory::id() const { - return "ProjectExplorer.TaskFileFactory"; + return Core::Id("ProjectExplorer.TaskFileFactory"); } QString TaskFileFactory::displayName() const diff --git a/src/plugins/tasklist/tasklist.qbs b/src/plugins/tasklist/tasklist.qbs index 8dc99abeae..9a92e0493e 100644 --- a/src/plugins/tasklist/tasklist.qbs +++ b/src/plugins/tasklist/tasklist.qbs @@ -12,26 +12,19 @@ QtcPlugin { Depends { name: "Locator" } Depends { name: "TextEditor" } - Depends { name: "cpp" } - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] - files: [ - "tasklistplugin.h", - "tasklist_export.h", - "tasklistconstants.h", - "stopmonitoringhandler.h", - "taskfile.h", - "taskfilefactory.h", - "tasklistplugin.cpp", + "TaskList.mimetypes.xml", "stopmonitoringhandler.cpp", + "stopmonitoringhandler.h", "taskfile.cpp", + "taskfile.h", "taskfilefactory.cpp", + "taskfilefactory.h", "tasklist.qrc", - "TaskList.mimetypes.xml" + "tasklist_export.h", + "tasklistconstants.h", + "tasklistplugin.cpp", + "tasklistplugin.h", ] } diff --git a/src/plugins/texteditor/basetextdocumentlayout.cpp b/src/plugins/texteditor/basetextdocumentlayout.cpp index e57acbc9af..53826856cb 100644 --- a/src/plugins/texteditor/basetextdocumentlayout.cpp +++ b/src/plugins/texteditor/basetextdocumentlayout.cpp @@ -29,6 +29,7 @@ #include "basetextdocumentlayout.h" #include <utils/qtcassert.h> +#include <QDebug> using namespace TextEditor; @@ -52,8 +53,6 @@ public: void removeMarkFromMarksCache(TextEditor::ITextMark *mark); private: - double recalculateMaxMarkWidthFactor() const; - TextMarks m_marksCache; // not owned QTextDocument *document; }; @@ -86,24 +85,23 @@ bool DocumentMarker::addMark(TextEditor::ITextMark *mark) mark->updateLineNumber(blockNumber + 1); QTC_CHECK(mark->lineNumber() == blockNumber + 1); // Checks that the base class is called mark->updateBlock(block); - documentLayout->hasMarks = true; - documentLayout->maxMarkWidthFactor = qMax(mark->widthFactor(), - documentLayout->maxMarkWidthFactor); - documentLayout->requestUpdate(); mark->setMarkableInterface(this); + if (!mark->isVisible()) + return true; + // Update document layout + double newMaxWidthFactor = qMax(mark->widthFactor(), documentLayout->maxMarkWidthFactor); + bool fullUpdate = newMaxWidthFactor > documentLayout->maxMarkWidthFactor || !documentLayout->hasMarks; + documentLayout->hasMarks = true; + documentLayout->maxMarkWidthFactor = newMaxWidthFactor; + if (fullUpdate) + documentLayout->requestUpdate(); + else + documentLayout->requestExtraAreaUpdate(); return true; } return false; } -double DocumentMarker::recalculateMaxMarkWidthFactor() const -{ - double maxWidthFactor = 1.0; - foreach (const ITextMark *mark, marks()) - maxWidthFactor = qMax(mark->widthFactor(), maxWidthFactor); - return maxWidthFactor; -} - TextEditor::TextMarks DocumentMarker::marksAt(int line) const { QTC_ASSERT(line >= 1, return TextMarks()); @@ -122,31 +120,50 @@ void DocumentMarker::removeMarkFromMarksCache(TextEditor::ITextMark *mark) BaseTextDocumentLayout *documentLayout = qobject_cast<BaseTextDocumentLayout*>(document->documentLayout()); QTC_ASSERT(documentLayout, return); - bool needUpdate = m_marksCache.removeOne(mark); + m_marksCache.removeAll(mark); + if (m_marksCache.isEmpty()) { documentLayout->hasMarks = false; - needUpdate = true; + documentLayout->maxMarkWidthFactor = 1.0; + documentLayout->requestUpdate(); + return; } - if (needUpdate) { - documentLayout->maxMarkWidthFactor = recalculateMaxMarkWidthFactor(); - updateMark(0); + if (!mark->isVisible()) + return; + + if (documentLayout->maxMarkWidthFactor == 1.0 + || mark->widthFactor() == 1.0 + || mark->widthFactor() < documentLayout->maxMarkWidthFactor) { + // No change in width possible + documentLayout->requestExtraAreaUpdate(); + } else { + double maxWidthFactor = 1.0; + foreach (const ITextMark *mark, marks()) { + if (!mark->isVisible()) + continue; + maxWidthFactor = qMax(mark->widthFactor(), maxWidthFactor); + if (maxWidthFactor == documentLayout->maxMarkWidthFactor) + break; // Still a mark with the maxMarkWidthFactor + } + + if (maxWidthFactor != documentLayout->maxMarkWidthFactor) { + documentLayout->maxMarkWidthFactor = maxWidthFactor; + documentLayout->requestUpdate(); + } else { + documentLayout->requestExtraAreaUpdate(); + } } } void DocumentMarker::removeMark(TextEditor::ITextMark *mark) { - BaseTextDocumentLayout *documentLayout = - qobject_cast<BaseTextDocumentLayout*>(document->documentLayout()); - QTC_ASSERT(documentLayout, return); - - QTextBlock block = document->begin(); - while (block.isValid()) { - if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData())) { - data->removeMark(mark); - } - block = block.next(); + QTextBlock block = document->findBlockByNumber(mark->lineNumber() - 1); + if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData())) { + if (!data->removeMark(mark)) + qDebug() << "Could not find mark" << mark << "on line" << mark->lineNumber(); } + removeMarkFromMarksCache(mark); mark->setMarkableInterface(0); } @@ -169,9 +186,7 @@ CodeFormatterData::~CodeFormatterData() TextBlockUserData::~TextBlockUserData() { - TextMarks marks = m_marks; - m_marks.clear(); - foreach (ITextMark *mrk, marks) { + foreach (ITextMark *mrk, m_marks) { TextEditor::Internal::DocumentMarker *documentMarker = static_cast<TextEditor::Internal::DocumentMarker *>(mrk->markableInterface()); documentMarker->removeMarkFromMarksCache(mrk); @@ -375,8 +390,7 @@ bool TextBlockUserData::findPreviousBlockOpenParenthesis(QTextCursor *cursor, bo for (int i = parenList.count()-1; i >= 0; --i) { Parenthesis paren = parenList.at(i); if (paren.chr != QLatin1Char('{') && paren.chr != QLatin1Char('}') - && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-') - && paren.chr != QLatin1Char('[') && paren.chr != QLatin1Char(']')) + && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-')) continue; if (block == cursor->block()) { if (position - block.position() <= paren.pos + (paren.type == Parenthesis::Closed ? 1 : 0)) @@ -439,8 +453,7 @@ bool TextBlockUserData::findNextBlockClosingParenthesis(QTextCursor *cursor) for (int i = 0; i < parenList.count(); ++i) { Parenthesis paren = parenList.at(i); if (paren.chr != QLatin1Char('{') && paren.chr != QLatin1Char('}') - && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-') - && paren.chr != QLatin1Char('[') && paren.chr != QLatin1Char(']')) + && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-')) continue; if (block == cursor->block() && (position - block.position() > paren.pos - (paren.type == Parenthesis::Opened ? 1 : 0))) @@ -674,6 +687,11 @@ void BaseTextDocumentLayout::setFolded(const QTextBlock &block, bool folded) } } +void BaseTextDocumentLayout::requestExtraAreaUpdate() +{ + emit updateExtraArea(); +} + ITextMarkable *BaseTextDocumentLayout::markableInterface() { return m_documentMarker; @@ -747,6 +765,7 @@ void BaseTextDocumentLayout::documentReloaded(TextMarks marks) = static_cast<TextEditor::Internal::DocumentMarker *>(m_documentMarker); documentMarker->removeMarkFromMarksCache(mark); mark->removedFromEditor(); + mark->setMarkableInterface(0); } } requestUpdate(); diff --git a/src/plugins/texteditor/basetextdocumentlayout.h b/src/plugins/texteditor/basetextdocumentlayout.h index cc8ecc1525..0acf7e254c 100644 --- a/src/plugins/texteditor/basetextdocumentlayout.h +++ b/src/plugins/texteditor/basetextdocumentlayout.h @@ -202,6 +202,7 @@ public: return data; } + void requestExtraAreaUpdate(); void emitDocumentSizeChanged() { emit documentSizeChanged(documentSize()); } ITextMarkable *markableInterface(); @@ -221,6 +222,9 @@ public: void documentReloaded(TextMarks marks); void updateMarksLineNumber(); void updateMarksBlock(const QTextBlock &block); + +signals: + void updateExtraArea(); }; } // namespace TextEditor diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 2e73ed4b78..3fe7050546 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -67,6 +67,7 @@ #include <extensionsystem/pluginmanager.h> #include <find/basetextfind.h> #include <utils/linecolumnlabel.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <utils/stylehelper.h> @@ -116,6 +117,7 @@ using namespace TextEditor; using namespace TextEditor::Internal; +using namespace Utils; namespace TextEditor { namespace Internal { @@ -252,7 +254,7 @@ BaseTextEditorWidget::BaseTextEditorWidget(QWidget *parent) // parentheses matcher d->m_formatRange = true; d->m_matchFormat.setForeground(Qt::red); - d->m_rangeFormat.setBackground(QColor(0xb4, 0xee, 0xb4)); + d->m_matchFormat.setBackground(QColor(0xb4, 0xee, 0xb4)); d->m_mismatchFormat.setBackground(Qt::magenta); d->m_parenthesesMatchingTimer = new QTimer(this); d->m_parenthesesMatchingTimer->setSingleShot(true); @@ -566,14 +568,13 @@ void BaseTextEditorWidget::updateCannotDecodeInfo() { setReadOnly(d->m_document->hasDecodingError()); if (d->m_document->hasDecodingError()) { - Core::InfoBarEntry info( - QLatin1String(Constants::SELECT_ENCODING), + Core::InfoBarEntry info(Core::Id(Constants::SELECT_ENCODING), tr("<b>Error:</b> Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.") .arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name()))); info.setCustomButtonInfo(tr("Select Encoding"), this, SLOT(selectEncoding())); d->m_document->infoBar()->addInfo(info); } else { - d->m_document->infoBar()->removeInfo(QLatin1String(Constants::SELECT_ENCODING)); + d->m_document->infoBar()->removeInfo(Core::Id(Constants::SELECT_ENCODING)); } } @@ -1761,7 +1762,8 @@ void BaseTextEditorWidget::keyPressEvent(QKeyEvent *e) // fall through case Qt::Key_Right: case Qt::Key_Left: -#ifndef Q_OS_MAC + if (HostOsInfo::isMacHost()) + break; if ((e->modifiers() & (Qt::AltModifier | Qt::ShiftModifier)) == (Qt::AltModifier | Qt::ShiftModifier)) { int diff_row = 0; @@ -1785,7 +1787,6 @@ void BaseTextEditorWidget::keyPressEvent(QKeyEvent *e) viewport()->update(); } } -#endif break; case Qt::Key_PageUp: case Qt::Key_PageDown: @@ -1829,13 +1830,8 @@ void BaseTextEditorWidget::keyPressEvent(QKeyEvent *e) } } - if (e->key() == Qt::Key_H && e->modifiers() == -#ifdef Q_OS_DARWIN - Qt::MetaModifier -#else - Qt::ControlModifier -#endif - ) { + if (e->key() == Qt::Key_H + && e->modifiers() == Qt::KeyboardModifiers(HostOsInfo::controlModifier())) { universalHelper(); e->accept(); return; @@ -2500,6 +2496,7 @@ BaseTextEditorWidgetPrivate::BaseTextEditorWidgetPrivate() m_codeAssistant(new CodeAssistant), m_assistRelevantContentAdded(false), m_cursorBlockNumber(-1), + m_markDragging(false), m_autoCompleter(new AutoCompleter), m_indenter(new Indenter), m_clipboardAssistProvider(new Internal::ClipboardAssistProvider) @@ -2535,6 +2532,7 @@ void BaseTextEditorWidgetPrivate::setupDocumentSignals(BaseTextDocument *documen q->setCursorWidth(2); // Applies to the document layout QObject::connect(documentLayout, SIGNAL(updateBlock(QTextBlock)), q, SLOT(slotUpdateBlockNotify(QTextBlock))); + QObject::connect(documentLayout, SIGNAL(updateExtraArea()), q, SLOT(slotUpdateExtraArea())); QObject::connect(q, SIGNAL(requestBlockUpdate(QTextBlock)), documentLayout, SIGNAL(updateBlock(QTextBlock))); QObject::connect(doc, SIGNAL(modificationChanged(bool)), q, SIGNAL(changed())); QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, @@ -2607,13 +2605,7 @@ void BaseTextEditorWidgetPrivate::snippetTabOrBacktab(bool forward) QPoint BaseTextEditorWidget::toolTipPosition(const QTextCursor &c) const { const QPoint cursorPos = mapToGlobal(cursorRect(c).bottomRight() + QPoint(1,1)); - return cursorPos + QPoint(d->m_extraArea->width(), -#ifdef Q_OS_WIN - -24 -#else - -16 -#endif - ); + return cursorPos + QPoint(d->m_extraArea->width(), HostOsInfo::isWindowsHost() ? -24 : -16); } void BaseTextEditorWidget::processTooltipRequest(const QTextCursor &c) @@ -3373,6 +3365,7 @@ void BaseTextEditorWidget::paintEvent(QPaintEvent *e) o.start = relativePos; o.length = 1; o.format.setForeground(palette().base()); + o.format.setBackground(palette().text()); selections.append(o); } } @@ -3395,11 +3388,8 @@ void BaseTextEditorWidget::paintEvent(QPaintEvent *e) cursor_pen = painter.pen(); } -#ifndef Q_OS_MAC // no visible cursor on mac - if (blockSelectionCursorRect.isValid()) + if (!HostOsInfo::isMacHost() && blockSelectionCursorRect.isValid()) painter.fillRect(blockSelectionCursorRect, palette().text()); -#endif - } offset.ry() += r.height(); @@ -3800,7 +3790,7 @@ void BaseTextEditorWidget::extraAreaPaintEvent(QPaintEvent *e) int count = 0; it = marks.constEnd() - 1; while (it != marks.constBegin()) { - if ((*it)->visible()) + if ((*it)->isVisible()) ++count; if (count == 3) break; @@ -3810,7 +3800,7 @@ void BaseTextEditorWidget::extraAreaPaintEvent(QPaintEvent *e) TextMarks::const_iterator end = marks.constEnd(); for ( ; it != end; ++it) { ITextMark *mark = *it; - if (!mark->visible()) + if (!mark->isVisible()) continue; const int height = fmLineSpacing - 1; const int width = int(.5 + height * mark->widthFactor()); @@ -4074,7 +4064,14 @@ void BaseTextEditorWidget::updateHighlights() && d->m_animator == 0) { d->m_parenthesesMatchingTimer->start(50); } else { - // use 0-timer, not direct call, to give the syntax highlighter a chance + // when we uncheck "highlight matching parentheses" + // we need clear current selection before viewport update + // otherwise we get sticky highlighted parentheses + if (!d->m_displaySettings.m_highlightMatchingParentheses) { + setExtraSelections(ParenthesesMatchingSelection, QList<QTextEdit::ExtraSelection>()); + } + + // use 0-timer, not direct call, to give the syntax highlighter a chance // to update the parentheses information d->m_parenthesesMatchingTimer->start(0); } @@ -4122,6 +4119,11 @@ void BaseTextEditorWidget::slotUpdateBlockNotify(const QTextBlock &block) blockRecursion = false; } +void BaseTextEditorWidget::slotUpdateExtraArea() +{ + d->m_extraArea->update(); +} + void BaseTextEditorWidget::timerEvent(QTimerEvent *e) { if (e->timerId() == d->autoScrollTimer.timerId()) { @@ -4252,10 +4254,8 @@ void BaseTextEditorWidget::mousePressEvent(QMouseEvent *e) } } -#ifdef Q_OS_LINUX - if (handleForwardBackwardMouseButtons(e)) + if (HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(e)) return; -#endif QPlainTextEdit::mousePressEvent(e); } @@ -4275,10 +4275,8 @@ void BaseTextEditorWidget::mouseReleaseEvent(QMouseEvent *e) } } -#ifndef Q_OS_LINUX - if (handleForwardBackwardMouseButtons(e)) + if (!HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(e)) return; -#endif QPlainTextEdit::mouseReleaseEvent(e); } @@ -4366,6 +4364,7 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) int markWidth; extraAreaWidth(&markWidth); + const bool inMarkArea = e->pos().x() <= markWidth && e->pos().x() >= 0; if (d->m_codeFoldingVisible && e->type() == QEvent::MouseMove && e->buttons() == 0) { // mouse tracking @@ -4386,9 +4385,22 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) // Set whether the mouse cursor is a hand or normal arrow if (e->type() == QEvent::MouseMove) { - bool hand = (e->pos().x() <= markWidth); - if (hand != (d->m_extraArea->cursor().shape() == Qt::PointingHandCursor)) - d->m_extraArea->setCursor(hand ? Qt::PointingHandCursor : Qt::ArrowCursor); + if (inMarkArea) { + //Find line by cursor position + int line = cursor.blockNumber() + 1; + emit editor()->markTooltipRequested(editor(), mapToGlobal(e->pos()), line); + } + + if (e->buttons() & Qt::LeftButton && !d->m_markDragStart.isNull()) { + int dist = (e->pos() - d->m_markDragStart).manhattanLength(); + if (dist > QApplication::startDragDistance()) + d->m_markDragging = true; + } + + if (d->m_markDragging) + d->m_extraArea->setCursor(inMarkArea ? Qt::DragMoveCursor : Qt::ForbiddenCursor); + else if (inMarkArea != (d->m_extraArea->cursor().shape() == Qt::PointingHandCursor)) + d->m_extraArea->setCursor(inMarkArea ? Qt::PointingHandCursor : Qt::ArrowCursor); } if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick) { @@ -4406,7 +4418,7 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) toggleBlockVisible(c); d->moveCursorVisible(false); } - } else if (d->m_lineNumbersVisible && e->pos().x() > markWidth) { + } else if (d->m_lineNumbersVisible && !inMarkArea) { QTextCursor selection = cursor; selection.setVisualNavigation(true); d->extraAreaSelectionAnchorBlockNumber = selection.blockNumber(); @@ -4415,6 +4427,18 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) setTextCursor(selection); } else { d->extraAreaToggleMarkBlockNumber = cursor.blockNumber(); + d->m_markDragging = false; + QTextBlock block = cursor.document()->findBlockByNumber(d->extraAreaToggleMarkBlockNumber); + if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData())) { + TextMarks marks = data->marks(); + for (int i = marks.size(); --i >= 0; ) { + ITextMark *mark = marks.at(i); + if (mark->isDraggable()) { + d->m_markDragStart = e->pos(); + break; + } + } + } } } } else if (d->extraAreaSelectionAnchorBlockNumber >= 0) { @@ -4448,25 +4472,41 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) if (e->type() == QEvent::MouseButtonRelease && e->button() == Qt::LeftButton) { int n = d->extraAreaToggleMarkBlockNumber; d->extraAreaToggleMarkBlockNumber = -1; - if (cursor.blockNumber() == n) { - if (TextBlockUserData *data = static_cast<TextBlockUserData *>(cursor.block().userData())) { - foreach (ITextMark *mark, data->marks()) { - if (mark->clickable()) { + const bool sameLine = cursor.blockNumber() == n; + const bool wasDragging = d->m_markDragging; + d->m_markDragging = false; + d->m_markDragStart = QPoint(); + QTextBlock block = cursor.document()->findBlockByNumber(n); + if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData())) { + TextMarks marks = data->marks(); + for (int i = marks.size(); --i >= 0; ) { + ITextMark *mark = marks.at(i); + if (sameLine) { + if (mark->isClickable()) { mark->clicked(); return; } + } else { + if (wasDragging && mark->isDraggable()) { + if (inMarkArea) { + mark->dragToLine(cursor.blockNumber() + 1); + d->m_extraArea->setCursor(Qt::PointingHandCursor); + } else { + d->m_extraArea->setCursor(Qt::ArrowCursor); + } + return; + } } } - - int line = n + 1; - ITextEditor::MarkRequestKind kind; - if (QApplication::keyboardModifiers() & Qt::ShiftModifier) - kind = ITextEditor::BookmarkRequest; - else - kind = ITextEditor::BreakpointRequest; - - emit editor()->markRequested(editor(), line, kind); } + int line = n + 1; + ITextEditor::MarkRequestKind kind; + if (QApplication::keyboardModifiers() & Qt::ShiftModifier) + kind = ITextEditor::BookmarkRequest; + else + kind = ITextEditor::BreakpointRequest; + + emit editor()->markRequested(editor(), line, kind); } } } @@ -4475,9 +4515,25 @@ void BaseTextEditorWidget::ensureCursorVisible() { QTextBlock block = textCursor().block(); if (!block.isVisible()) { - while (!block.isVisible() && block.previous().isValid()) + BaseTextDocumentLayout *documentLayout = qobject_cast<BaseTextDocumentLayout*>(document()->documentLayout()); + QTC_ASSERT(documentLayout, return); + + // Open all parent folds of current line. + int indent = BaseTextDocumentLayout::foldingIndent(block); + block = block.previous(); + while (block.isValid()) { + const int indent2 = BaseTextDocumentLayout::foldingIndent(block); + if (BaseTextDocumentLayout::canFold(block) && indent2 < indent) { + BaseTextDocumentLayout::doFoldOrUnfold(block, /* unfold = */ true); + if (block.isVisible()) + break; + indent = indent2; + } block = block.previous(); - toggleBlockVisible(block); + } + + documentLayout->requestUpdate(); + documentLayout->emitDocumentSizeChanged(); } QPlainTextEdit::ensureCursorVisible(); } @@ -4499,12 +4555,12 @@ const TabSettings &BaseTextEditorWidget::tabSettings() const return d->m_document->tabSettings(); } -void BaseTextEditorWidget::setLanguageSettingsId(const QString &settingsId) +void BaseTextEditorWidget::setLanguageSettingsId(Core::Id settingsId) { d->m_tabSettingsId = settingsId; } -QString BaseTextEditorWidget::languageSettingsId() const +Core::Id BaseTextEditorWidget::languageSettingsId() const { return d->m_tabSettingsId; } @@ -5017,11 +5073,15 @@ void BaseTextEditorAnimator::finish() void BaseTextEditorWidget::_q_matchParentheses() { - if (isReadOnly()) + if (isReadOnly() + || !(d->m_displaySettings.m_highlightMatchingParentheses + || d->m_displaySettings.m_animateMatchingParentheses)) return; QTextCursor backwardMatch = textCursor(); QTextCursor forwardMatch = textCursor(); + if (overwriteMode()) + backwardMatch.movePosition(QTextCursor::Right); const TextBlockUserData::MatchType backwardMatchType = TextBlockUserData::matchCursorBackward(&backwardMatch); const TextBlockUserData::MatchType forwardMatchType = TextBlockUserData::matchCursorForward(&forwardMatch); @@ -5038,27 +5098,23 @@ void BaseTextEditorWidget::_q_matchParentheses() if (backwardMatchType == TextBlockUserData::Mismatch) { sel.cursor = backwardMatch; sel.format = d->m_mismatchFormat; + extraSelections.append(sel); } else { - if (d->m_displaySettings.m_animateMatchingParentheses) { - animatePosition = backwardMatch.selectionStart(); - } else if (d->m_formatRange) { - sel.cursor = backwardMatch; - sel.format = d->m_rangeFormat; - extraSelections.append(sel); - } - sel.cursor = backwardMatch; sel.format = d->m_matchFormat; sel.cursor.setPosition(backwardMatch.selectionStart()); - sel.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + sel.cursor.setPosition(sel.cursor.position() + 1, QTextCursor::KeepAnchor); extraSelections.append(sel); + if (d->m_displaySettings.m_animateMatchingParentheses && sel.cursor.block().isVisible()) + animatePosition = backwardMatch.selectionStart(); + sel.cursor.setPosition(backwardMatch.selectionEnd()); - sel.cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + sel.cursor.setPosition(sel.cursor.position() - 1, QTextCursor::KeepAnchor); + extraSelections.append(sel); } - extraSelections.append(sel); } if (forwardMatch.hasSelection()) { @@ -5066,27 +5122,23 @@ void BaseTextEditorWidget::_q_matchParentheses() if (forwardMatchType == TextBlockUserData::Mismatch) { sel.cursor = forwardMatch; sel.format = d->m_mismatchFormat; + extraSelections.append(sel); } else { - if (d->m_displaySettings.m_animateMatchingParentheses) { - animatePosition = forwardMatch.selectionEnd()-1; - } else if (d->m_formatRange) { - sel.cursor = forwardMatch; - sel.format = d->m_rangeFormat; - extraSelections.append(sel); - } - sel.cursor = forwardMatch; sel.format = d->m_matchFormat; sel.cursor.setPosition(forwardMatch.selectionStart()); - sel.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + sel.cursor.setPosition(sel.cursor.position() + 1, QTextCursor::KeepAnchor); extraSelections.append(sel); sel.cursor.setPosition(forwardMatch.selectionEnd()); - sel.cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + sel.cursor.setPosition(sel.cursor.position() - 1, QTextCursor::KeepAnchor); + extraSelections.append(sel); + + if (d->m_displaySettings.m_animateMatchingParentheses && sel.cursor.block().isVisible()) + animatePosition = forwardMatch.selectionEnd() - 1; } - extraSelections.append(sel); } @@ -5107,13 +5159,13 @@ void BaseTextEditorWidget::_q_matchParentheses() d->m_animator->setPosition(animatePosition); QPalette pal; pal.setBrush(QPalette::Text, d->m_matchFormat.foreground()); - pal.setBrush(QPalette::Base, d->m_rangeFormat.background()); + pal.setBrush(QPalette::Base, d->m_matchFormat.background()); d->m_animator->setData(font(), pal, characterAt(d->m_animator->position())); connect(d->m_animator, SIGNAL(updateRequest(int,QPointF,QRectF)), this, SLOT(_q_animateUpdate(int,QPointF,QRectF))); } - - setExtraSelections(ParenthesesMatchingSelection, extraSelections); + if (d->m_displaySettings.m_highlightMatchingParentheses) + setExtraSelections(ParenthesesMatchingSelection, extraSelections); } void BaseTextEditorWidget::_q_highlightBlocks() @@ -5610,9 +5662,7 @@ void BaseTextEditorWidget::setFontSettings(const TextEditor::FontSettings &fs) d->m_searchResultFormat.setBackground(searchResultFormat.background()); // Matching braces - d->m_matchFormat.setForeground(parenthesesFormat.foreground()); - d->m_rangeFormat.setBackground(parenthesesFormat.background()); - + d->m_matchFormat = parenthesesFormat; // snippests d->m_occurrencesFormat = fs.toTextCharFormat(C_OCCURRENCES); diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 01e4b08bb7..be0583b6c2 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -33,8 +33,9 @@ #include "itexteditor.h" #include "codeassist/assistenums.h" -#include <find/ifindsupport.h> #include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/id.h> +#include <find/ifindsupport.h> #include <QPlainTextEdit> @@ -389,8 +390,8 @@ public: virtual void extraAreaMouseEvent(QMouseEvent *); const TabSettings &tabSettings() const; - void setLanguageSettingsId(const QString &settingsId); - QString languageSettingsId() const; + void setLanguageSettingsId(Core::Id settingsId); + Core::Id languageSettingsId() const; void setCodeStyle(ICodeStylePreferences *settings); @@ -524,6 +525,7 @@ protected: virtual QString foldReplacementText(const QTextBlock &block) const; protected slots: + virtual void slotUpdateExtraArea(); virtual void slotUpdateExtraAreaWidth(); virtual void slotModificationChanged(bool); virtual void slotUpdateRequest(const QRect &r, int dy); diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 8728aef149..c8bcb8c549 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -36,6 +36,7 @@ #include "fontsettings.h" #include "refactoroverlay.h" +#include <coreplugin/id.h> #include <utils/changeset.h> #include <QBasicTimer> @@ -197,13 +198,12 @@ public: bool m_formatRange; QTextCharFormat m_matchFormat; QTextCharFormat m_mismatchFormat; - QTextCharFormat m_rangeFormat; QTimer *m_parenthesesMatchingTimer; // end parentheses matcher QWidget *m_extraArea; - QString m_tabSettingsId; + Core::Id m_tabSettingsId; ICodeStylePreferences *m_codeStylePreferences; DisplaySettings m_displaySettings; FontSettings m_fontSettings; @@ -293,6 +293,9 @@ public: QPointer<BaseTextEditorAnimator> m_animator; int m_cursorBlockNumber; + QPoint m_markDragStart; + bool m_markDragging; + QScopedPointer<AutoCompleter> m_autoCompleter; QScopedPointer<Indenter> m_indenter; diff --git a/src/plugins/texteditor/codeassist/basicproposalitemlistmodel.cpp b/src/plugins/texteditor/codeassist/basicproposalitemlistmodel.cpp index 9a488dfaa6..3954ad48eb 100644 --- a/src/plugins/texteditor/codeassist/basicproposalitemlistmodel.cpp +++ b/src/plugins/texteditor/codeassist/basicproposalitemlistmodel.cpp @@ -193,14 +193,21 @@ void BasicProposalItemListModel::filter(const QString &prefix) /* * This code builds a regular expression in order to more intelligently match - * camel-case style. This means upper-case characters will be rewritten as follows: + * camel-case and underscore names. * - * A => [a-z0-9_]*A (for any but the first capital letter) + * For any but the first letter, the following replacements are made: + * A => [a-z0-9_]*A + * a => (?:[a-zA-Z0-9]*_)?a * - * Meaning it allows any sequence of lower-case characters to preceed an - * upper-case character. So for example gAC matches getActionController. + * That means any sequence of lower-case or underscore characters can preceed an + * upper-case character. And any sequence of lower-case or upper case characters - + * followed by an underscore can preceed a lower-case character. * - * It also implements the first-letter-only case sensitivity. + * Examples: (case sensitive mode) + * gAC matches getActionController + * gac matches get_action_controller + * + * It also implements the fully and first-letter-only case sensitivity. */ const TextEditor::CaseSensitivity caseSensitivity = TextEditorSettings::instance()->completionSettings().m_caseSensitivity; @@ -208,21 +215,29 @@ void BasicProposalItemListModel::filter(const QString &prefix) QString keyRegExp; keyRegExp += QLatin1Char('^'); bool first = true; - const QLatin1String wordContinuation("[a-z0-9_]*"); + const QLatin1String uppercaseWordContinuation("[a-z0-9_]*"); + const QLatin1String lowercaseWordContinuation("(?:[a-zA-Z0-9]*_)?"); foreach (const QChar &c, prefix) { if (caseSensitivity == TextEditor::CaseInsensitive || (caseSensitivity == TextEditor::FirstLetterCaseSensitive && !first)) { keyRegExp += QLatin1String("(?:"); - if (c.isUpper() && !first) - keyRegExp += wordContinuation; + if (!first) + keyRegExp += uppercaseWordContinuation; keyRegExp += QRegExp::escape(c.toUpper()); keyRegExp += QLatin1Char('|'); + if (!first) + keyRegExp += lowercaseWordContinuation; keyRegExp += QRegExp::escape(c.toLower()); keyRegExp += QLatin1Char(')'); } else { - if (c.isUpper() && !first) - keyRegExp += wordContinuation; + if (!first) { + if (c.isUpper()) { + keyRegExp += uppercaseWordContinuation; + } else { + keyRegExp += lowercaseWordContinuation; + } + } keyRegExp += QRegExp::escape(c); } diff --git a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp index 0efafd3740..cc5a8a2b84 100644 --- a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp +++ b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp @@ -32,6 +32,7 @@ #include "codeassistant.h" #include <utils/faketooltip.h> +#include <utils/hostosinfo.h> #include <QDebug> #include <QApplication> @@ -287,11 +288,9 @@ void FunctionHintProposalWidget::updateContent() void FunctionHintProposalWidget::updatePosition() { const QDesktopWidget *desktop = QApplication::desktop(); -#ifdef Q_OS_MAC - const QRect &screen = desktop->availableGeometry(desktop->screenNumber(d->m_underlyingWidget)); -#else - const QRect &screen = desktop->screenGeometry(desktop->screenNumber(d->m_underlyingWidget)); -#endif + const QRect &screen = Utils::HostOsInfo::isMacHost() + ? desktop->availableGeometry(desktop->screenNumber(d->m_underlyingWidget)) + : desktop->screenGeometry(desktop->screenNumber(d->m_underlyingWidget)); d->m_pager->setFixedWidth(d->m_pager->minimumSizeHint().width()); diff --git a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp index 73f56fe410..07c52597b6 100644 --- a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp +++ b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp @@ -39,6 +39,7 @@ #include <texteditor/texteditorconstants.h> #include <utils/faketooltip.h> +#include <utils/hostosinfo.h> #include <QRect> #include <QLatin1String> @@ -55,6 +56,7 @@ #include <QDesktopWidget> #include <QLabel> +using namespace Utils; namespace TextEditor { @@ -311,15 +313,15 @@ void GenericProposalWidgetPrivate::maybeShowInfoTip() GenericProposalWidget::GenericProposalWidget() : d(new GenericProposalWidgetPrivate(this)) { -#ifdef Q_OS_MAC - if (d->m_completionListView->horizontalScrollBar()) - d->m_completionListView->horizontalScrollBar()->setAttribute(Qt::WA_MacMiniSize); - if (d->m_completionListView->verticalScrollBar()) - d->m_completionListView->verticalScrollBar()->setAttribute(Qt::WA_MacMiniSize); -#else - // This improves the look with QGTKStyle. - setFrameStyle(d->m_completionListView->frameStyle()); -#endif + if (HostOsInfo::isMacHost()) { + if (d->m_completionListView->horizontalScrollBar()) + d->m_completionListView->horizontalScrollBar()->setAttribute(Qt::WA_MacMiniSize); + if (d->m_completionListView->verticalScrollBar()) + d->m_completionListView->verticalScrollBar()->setAttribute(Qt::WA_MacMiniSize); + } else { + // This improves the look with QGTKStyle. + setFrameStyle(d->m_completionListView->frameStyle()); + } d->m_completionListView->setFrameStyle(QFrame::NoFrame); d->m_completionListView->setAttribute(Qt::WA_MacShowFocusRect, false); d->m_completionListView->setUniformItemSizes(true); @@ -507,11 +509,9 @@ void GenericProposalWidget::updatePositionAndSize() // Determine the position, keeping the popup on the screen const QDesktopWidget *desktop = QApplication::desktop(); -#ifdef Q_OS_MAC - const QRect screen = desktop->availableGeometry(desktop->screenNumber(d->m_underlyingWidget)); -#else - const QRect screen = desktop->screenGeometry(desktop->screenNumber(d->m_underlyingWidget)); -#endif + const QRect screen = HostOsInfo::isMacHost() + ? desktop->availableGeometry(desktop->screenNumber(d->m_underlyingWidget)) + : desktop->screenGeometry(desktop->screenNumber(d->m_underlyingWidget)); QPoint pos = d->m_displayRect.bottomLeft(); pos.rx() -= 16 + fw; // Space for the icons @@ -555,11 +555,7 @@ bool GenericProposalWidget::eventFilter(QObject *o, QEvent *e) switch (ke->key()) { case Qt::Key_N: case Qt::Key_P: -#ifdef Q_OS_MAC - if (ke->modifiers() == Qt::MetaModifier) { -#else - if (ke->modifiers() == Qt::ControlModifier) { -#endif + if (ke->modifiers() == Qt::KeyboardModifiers(HostOsInfo::controlModifier())) { e->accept(); return true; } @@ -575,11 +571,7 @@ bool GenericProposalWidget::eventFilter(QObject *o, QEvent *e) case Qt::Key_P: // select next/previous completion d->m_explicitlySelected = true; -#ifdef Q_OS_MAC - if (ke->modifiers() == Qt::MetaModifier) { -#else - if (ke->modifiers() == Qt::ControlModifier) { -#endif + if (ke->modifiers() == Qt::KeyboardModifiers(HostOsInfo::controlModifier())) { int change = (ke->key() == Qt::Key_N) ? 1 : -1; int nrows = d->m_model->size(); int row = d->m_completionListView->currentIndex().row(); diff --git a/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp b/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp new file mode 100644 index 0000000000..3fda0de0f2 --- /dev/null +++ b/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp @@ -0,0 +1,278 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "keywordscompletionassist.h" + +#include <texteditor/codeassist/iassistinterface.h> +#include <texteditor/codeassist/genericproposal.h> +#include <texteditor/codeassist/ifunctionhintproposalmodel.h> +#include <texteditor/codeassist/functionhintproposal.h> +#include <texteditor/codeassist/basicproposalitemlistmodel.h> +#include "completionsettings.h" +#include "texteditorsettings.h" +#include "basetexteditor.h" + +#include <QtGui/QTextCursor> + +using namespace TextEditor; + +// -------------------------- +// Keywords +// -------------------------- +Keywords::Keywords() +{ + +} + +// Note: variables and functions must be sorted +Keywords::Keywords(const QStringList &variabels, const QStringList &functions, const QMap<QString, QStringList> &functionArgs) + : m_variables(variabels), m_functions(functions), m_functionArgs(functionArgs) +{ + +} + +bool Keywords::isVariable(const QString &word) const +{ + return qBinaryFind(m_variables, word) != m_variables.constEnd(); +} + +bool Keywords::isFunction(const QString &word) const +{ + return qBinaryFind(m_functions, word) != m_functions.constEnd(); +} + +QStringList Keywords::variables() const +{ + return m_variables; +} + +QStringList Keywords::functions() const +{ + return m_functions; +} + +QStringList Keywords::argsForFunction(const QString &function) const +{ + return m_functionArgs.value(function); +} + + +// -------------------------- +// KeywordsAssistProposalItem +// -------------------------- +KeywordsAssistProposalItem::KeywordsAssistProposalItem(Keywords keywords) + : m_keywords(keywords) +{ +} + +KeywordsAssistProposalItem::~KeywordsAssistProposalItem() +{} + +bool KeywordsAssistProposalItem::prematurelyApplies(const QChar &c) const +{ + // only '(' in case of a function + if (c == QLatin1Char('(') && m_keywords.isFunction(text())) + return true; + return false; +} + +void KeywordsAssistProposalItem::applyContextualContent(TextEditor::BaseTextEditor *editor, + int basePosition) const +{ + const CompletionSettings &settings = TextEditorSettings::instance()->completionSettings(); + + int replaceLength = editor->position() - basePosition; + QString toInsert = text(); + int cursorOffset = 0; + if (m_keywords.isFunction(toInsert) && settings.m_autoInsertBrackets) { + if (settings.m_spaceAfterFunctionName) { + if (editor->textAt(editor->position(), 2) == QLatin1String(" (")) { + cursorOffset = 2; + } else if (editor->characterAt(editor->position()) == QLatin1Char('(') + || editor->characterAt(editor->position()) == QLatin1Char(' ')) { + replaceLength += 1; + toInsert += QLatin1String(" ("); + } else { + toInsert += QLatin1String(" ()"); + cursorOffset = -1; + } + } else { + if (editor->characterAt(editor->position()) == QLatin1Char('(')) { + cursorOffset = 1; + } else { + toInsert += QLatin1String("()"); + cursorOffset = -1; + } + } + } + + editor->setCursorPosition(basePosition); + editor->replace(replaceLength, toInsert); + if (cursorOffset) + editor->setCursorPosition(editor->position() + cursorOffset); +} + +// ------------------------- +// KeywordsFunctionHintModel +// ------------------------- +KeywordsFunctionHintModel::KeywordsFunctionHintModel(const QStringList &functionSymbols) + : m_functionSymbols(functionSymbols) +{} + +KeywordsFunctionHintModel::~KeywordsFunctionHintModel() +{} + +void KeywordsFunctionHintModel::reset() +{} + +int KeywordsFunctionHintModel::size() const +{ + return m_functionSymbols.size(); +} + +QString KeywordsFunctionHintModel::text(int index) const +{ + return m_functionSymbols.at(index); +} + +int KeywordsFunctionHintModel::activeArgument(const QString &prefix) const +{ + Q_UNUSED(prefix); + return 1; +} + +// --------------------------------- +// KeywordsCompletionAssistProcessor +// --------------------------------- +KeywordsCompletionAssistProcessor::KeywordsCompletionAssistProcessor(Keywords keywords) + : m_startPosition(-1) + , m_variableIcon(QLatin1String(":/codemodel/images/keyword.png")) + , m_functionIcon(QLatin1String(":/codemodel/images/func.png")) + , m_keywords(keywords) +{} + +KeywordsCompletionAssistProcessor::~KeywordsCompletionAssistProcessor() +{} + +IAssistProposal *KeywordsCompletionAssistProcessor::perform(const IAssistInterface *interface) +{ + m_interface.reset(interface); + + if (isInComment()) + return 0; + + if (interface->reason() == IdleEditor && !acceptsIdleEditor()) + return 0; + + if (m_startPosition == -1) + m_startPosition = findStartOfName(); + + int nextCharPos = m_startPosition + m_word.length(); + if (m_keywords.isFunction(m_word) + && m_interface->characterAt(nextCharPos) == QLatin1Char('(')) { + QStringList functionSymbols = m_keywords.argsForFunction(m_word); + IFunctionHintProposalModel *model = + new KeywordsFunctionHintModel(functionSymbols); + IAssistProposal *proposal = new FunctionHintProposal(m_startPosition, model); + return proposal; + } else { + QList<TextEditor::BasicProposalItem *> items; + addWordsToProposalList(&items, m_keywords.variables(), m_variableIcon); + addWordsToProposalList(&items, m_keywords.functions(), m_functionIcon); + return new GenericProposal(m_startPosition, new BasicProposalItemListModel(items)); + } +} + +QChar KeywordsCompletionAssistProcessor::startOfCommentChar() const +{ + return QLatin1Char('#'); +} + +bool KeywordsCompletionAssistProcessor::acceptsIdleEditor() +{ + const int pos = m_interface->position(); + QChar characterUnderCursor = m_interface->characterAt(pos); + if (!characterUnderCursor.isLetterOrNumber()) { + m_startPosition = findStartOfName(); + if (pos - m_startPosition >= 3 && !isInComment()) + return true; + } + return false; +} + +int KeywordsCompletionAssistProcessor::findStartOfName(int pos) +{ + if (pos == -1) + pos = m_interface->position(); + + QChar chr = m_interface->characterAt(pos-1); + if (chr == QLatin1Char('(')) { + --pos; + } + // Skip to the start of a name + do { + chr = m_interface->characterAt(--pos); + } while (chr.isLetterOrNumber() || chr == QLatin1Char('_')); + + int start = ++pos; + m_word.clear(); + do { + m_word += m_interface->characterAt(pos); + chr = m_interface->characterAt(++pos); + } while ((chr.isLetterOrNumber() || chr == QLatin1Char('_')) + && chr != QLatin1Char('(')); + + return start; +} + +bool KeywordsCompletionAssistProcessor::isInComment() const +{ + QTextCursor tc(m_interface->textDocument()); + tc.setPosition(m_interface->position()); + tc.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); + const QString &lineBeginning = tc.selectedText(); + if (lineBeginning.contains(startOfCommentChar())) + return true; + return false; +} + +void KeywordsCompletionAssistProcessor::addWordsToProposalList(QList<BasicProposalItem *> *items, const QStringList &words, const QIcon &icon) +{ + if (!items) + return; + + for (int i = 0; i < words.count(); ++i) { + BasicProposalItem *item = new KeywordsAssistProposalItem(m_keywords); + item->setText(words.at(i)); + item->setIcon(icon); + items->append(item); + } +} + + diff --git a/src/plugins/texteditor/codeassist/keywordscompletionassist.h b/src/plugins/texteditor/codeassist/keywordscompletionassist.h new file mode 100644 index 0000000000..7c8f8eac66 --- /dev/null +++ b/src/plugins/texteditor/codeassist/keywordscompletionassist.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef KEYWORDSCOMPLETIONASSIST_H +#define KEYWORDSCOMPLETIONASSIST_H + +#include "iassistprocessor.h" +#include "basicproposalitem.h" +#include "ifunctionhintproposalmodel.h" + +#include <QtGui/QIcon> +#include <QtCore/QStringList> + +namespace TextEditor { + +class TEXTEDITOR_EXPORT Keywords +{ +public: + Keywords(); + Keywords(const QStringList &variabels, const QStringList &functions, const QMap<QString, QStringList> &functionArgs); + bool isVariable(const QString &word) const; + bool isFunction(const QString &word) const; + + QStringList variables() const; + QStringList functions() const; + QStringList argsForFunction(const QString &function) const; + +private: + QStringList m_variables; + QStringList m_functions; + QMap<QString, QStringList> m_functionArgs; +}; + +class TEXTEDITOR_EXPORT KeywordsAssistProposalItem : public TextEditor::BasicProposalItem +{ +public: + KeywordsAssistProposalItem(Keywords keywords); + virtual ~KeywordsAssistProposalItem(); + + virtual bool prematurelyApplies(const QChar &c) const; + virtual void applyContextualContent(TextEditor::BaseTextEditor *editor, + int basePosition) const; +private: + Keywords m_keywords; +}; + +class TEXTEDITOR_EXPORT KeywordsFunctionHintModel : public TextEditor::IFunctionHintProposalModel +{ +public: + KeywordsFunctionHintModel(const QStringList &functionSymbols); + virtual ~KeywordsFunctionHintModel(); + + virtual void reset(); + virtual int size() const; + virtual QString text(int index) const; + virtual int activeArgument(const QString &prefix) const; + +private: + QStringList m_functionSymbols; +}; + +class TEXTEDITOR_EXPORT KeywordsCompletionAssistProcessor : public TextEditor::IAssistProcessor +{ +public: + KeywordsCompletionAssistProcessor(Keywords keywords); + virtual ~KeywordsCompletionAssistProcessor(); + + virtual TextEditor::IAssistProposal *perform(const TextEditor::IAssistInterface *interface); + virtual QChar startOfCommentChar() const; + +private: + bool acceptsIdleEditor(); + int findStartOfName(int pos = -1); + bool isInComment() const; + void addWordsToProposalList(QList<BasicProposalItem *> *items, const QStringList &words, const QIcon &icon); + + int m_startPosition; + QString m_word; + QScopedPointer<const TextEditor::IAssistInterface> m_interface; + const QIcon m_variableIcon; + const QIcon m_functionIcon; + Keywords m_keywords; +}; + +} // TextEditor + +#endif // KEYWORDSCOMPLETIONASSISTPROCESSOR_H diff --git a/src/plugins/texteditor/codeassist/quickfixassistprocessor.cpp b/src/plugins/texteditor/codeassist/quickfixassistprocessor.cpp index b82510a980..d05dc032c0 100644 --- a/src/plugins/texteditor/codeassist/quickfixassistprocessor.cpp +++ b/src/plugins/texteditor/codeassist/quickfixassistprocessor.cpp @@ -55,12 +55,12 @@ IAssistProposal *QuickFixAssistProcessor::perform(const IAssistInterface *interf QSharedPointer<const IAssistInterface> assistInterface(interface); - QList<QuickFixOperation::Ptr> quickFixes; + QuickFixOperations quickFixes; const QuickFixAssistProvider *quickFixProvider = static_cast<const QuickFixAssistProvider *>(provider()); foreach (QuickFixFactory *factory, quickFixProvider->quickFixFactories()) - quickFixes += factory->matchingOperations(assistInterface); + factory->matchingOperations(assistInterface, quickFixes); if (!quickFixes.isEmpty()) { QList<BasicProposalItem *> items; diff --git a/src/plugins/texteditor/codestylepool.cpp b/src/plugins/texteditor/codestylepool.cpp index 2ab59a2059..14d054e8a1 100644 --- a/src/plugins/texteditor/codestylepool.cpp +++ b/src/plugins/texteditor/codestylepool.cpp @@ -40,9 +40,9 @@ using namespace TextEditor; -static const char *codeStyleDataKey = "CodeStyleData"; -static const char *displayNameKey = "DisplayName"; -static const char *codeStyleDocKey = "QtCreatorCodeStyle"; +static const char codeStyleDataKey[] = "CodeStyleData"; +static const char displayNameKey[] = "DisplayName"; +static const char codeStyleDocKey[] = "QtCreatorCodeStyle"; namespace TextEditor { namespace Internal { @@ -115,7 +115,7 @@ CodeStylePool::~CodeStylePool() QString CodeStylePool::settingsDir() const { - const QString suffix = d->m_factory ? d->m_factory->languageId() : QLatin1String("default"); + const QString suffix = d->m_factory ? d->m_factory->languageId().toString() : QLatin1String("default"); return customCodeStylesPath().append(suffix); } diff --git a/src/plugins/texteditor/colorschemeedit.cpp b/src/plugins/texteditor/colorschemeedit.cpp index 4b7bf7633b..7929cac17a 100644 --- a/src/plugins/texteditor/colorschemeedit.cpp +++ b/src/plugins/texteditor/colorschemeedit.cpp @@ -61,8 +61,9 @@ public: void setFormatDescriptions(const FormatDescriptions *descriptions) { + beginResetModel(); m_descriptions = descriptions; - reset(); + endResetModel(); } void setBaseFont(const QFont &font) diff --git a/src/plugins/texteditor/displaysettings.cpp b/src/plugins/texteditor/displaysettings.cpp index 49288d1bb5..be5e6f81a9 100644 --- a/src/plugins/texteditor/displaysettings.cpp +++ b/src/plugins/texteditor/displaysettings.cpp @@ -41,6 +41,7 @@ static const char displayFoldingMarkersKey[] = "DisplayFoldingMarkers"; static const char highlightCurrentLineKey[] = "HighlightCurrentLine2Key"; static const char highlightBlocksKey[] = "HighlightBlocksKey"; static const char animateMatchingParenthesesKey[] = "AnimateMatchingParenthesesKey"; +static const char highlightMatchingParenthesesKey[] = "HightlightMatchingParenthesesKey"; static const char markTextChangesKey[] = "MarkTextChanges"; static const char autoFoldFirstCommentKey[] = "AutoFoldFirstComment"; static const char centerCursorOnScrollKey[] = "CenterCursorOnScroll"; @@ -58,6 +59,7 @@ DisplaySettings::DisplaySettings() : m_highlightCurrentLine(false), m_highlightBlocks(false), m_animateMatchingParentheses(true), + m_highlightMatchingParentheses(true), m_markTextChanges(true), m_autoFoldFirstComment(true), m_centerCursorOnScroll(false) @@ -79,6 +81,7 @@ void DisplaySettings::toSettings(const QString &category, QSettings *s) const s->setValue(QLatin1String(highlightCurrentLineKey), m_highlightCurrentLine); s->setValue(QLatin1String(highlightBlocksKey), m_highlightBlocks); s->setValue(QLatin1String(animateMatchingParenthesesKey), m_animateMatchingParentheses); + s->setValue(QLatin1String(highlightMatchingParenthesesKey), m_highlightMatchingParentheses); s->setValue(QLatin1String(markTextChangesKey), m_markTextChanges); s->setValue(QLatin1String(autoFoldFirstCommentKey), m_autoFoldFirstComment); s->setValue(QLatin1String(centerCursorOnScrollKey), m_centerCursorOnScroll); @@ -103,6 +106,7 @@ void DisplaySettings::fromSettings(const QString &category, const QSettings *s) m_highlightCurrentLine = s->value(group + QLatin1String(highlightCurrentLineKey), m_highlightCurrentLine).toBool(); m_highlightBlocks = s->value(group + QLatin1String(highlightBlocksKey), m_highlightBlocks).toBool(); m_animateMatchingParentheses = s->value(group + QLatin1String(animateMatchingParenthesesKey), m_animateMatchingParentheses).toBool(); + m_highlightMatchingParentheses = s->value(group + QLatin1String(highlightMatchingParenthesesKey), m_highlightMatchingParentheses).toBool(); m_markTextChanges = s->value(group + QLatin1String(markTextChangesKey), m_markTextChanges).toBool(); m_autoFoldFirstComment = s->value(group + QLatin1String(autoFoldFirstCommentKey), m_autoFoldFirstComment).toBool(); m_centerCursorOnScroll = s->value(group + QLatin1String(centerCursorOnScrollKey), m_centerCursorOnScroll).toBool(); @@ -119,6 +123,7 @@ bool DisplaySettings::equals(const DisplaySettings &ds) const && m_highlightCurrentLine == ds.m_highlightCurrentLine && m_highlightBlocks == ds.m_highlightBlocks && m_animateMatchingParentheses == ds.m_animateMatchingParentheses + && m_highlightMatchingParentheses == ds.m_highlightMatchingParentheses && m_markTextChanges == ds.m_markTextChanges && m_autoFoldFirstComment== ds.m_autoFoldFirstComment && m_centerCursorOnScroll == ds.m_centerCursorOnScroll diff --git a/src/plugins/texteditor/displaysettings.h b/src/plugins/texteditor/displaysettings.h index 26e284a4e0..c64c63f3ab 100644 --- a/src/plugins/texteditor/displaysettings.h +++ b/src/plugins/texteditor/displaysettings.h @@ -55,6 +55,7 @@ public: bool m_highlightCurrentLine; bool m_highlightBlocks; bool m_animateMatchingParentheses; + bool m_highlightMatchingParentheses; bool m_markTextChanges; bool m_autoFoldFirstComment; bool m_centerCursorOnScroll; diff --git a/src/plugins/texteditor/displaysettingspage.cpp b/src/plugins/texteditor/displaysettingspage.cpp index 930d7133e9..a95c434ba7 100644 --- a/src/plugins/texteditor/displaysettingspage.cpp +++ b/src/plugins/texteditor/displaysettingspage.cpp @@ -82,6 +82,7 @@ QWidget *DisplaySettingsPage::createPage(QWidget *parent) << ' ' << d->m_page->highlightBlocks->text() << ' ' << d->m_page->visualizeWhitespace->text() << ' ' << d->m_page->animateMatchingParentheses->text() + << ' ' << d->m_page->highlightMatchingParentheses->text() << ' ' << d->m_page->enableTextWrapping->text() << ' ' << d->m_page->autoFoldFirstComment->text() << ' ' << d->m_page->centerOnScroll->text(); @@ -119,6 +120,7 @@ void DisplaySettingsPage::settingsFromUI(DisplaySettings &displaySettings) const displaySettings.m_highlightCurrentLine = d->m_page->highlightCurrentLine->isChecked(); displaySettings.m_highlightBlocks = d->m_page->highlightBlocks->isChecked(); displaySettings.m_animateMatchingParentheses = d->m_page->animateMatchingParentheses->isChecked(); + displaySettings.m_highlightMatchingParentheses = d->m_page->highlightMatchingParentheses->isChecked(); displaySettings.m_markTextChanges = d->m_page->markTextChanges->isChecked(); displaySettings.m_autoFoldFirstComment = d->m_page->autoFoldFirstComment->isChecked(); displaySettings.m_centerCursorOnScroll = d->m_page->centerOnScroll->isChecked(); @@ -136,6 +138,7 @@ void DisplaySettingsPage::settingsToUI() d->m_page->highlightCurrentLine->setChecked(displaySettings.m_highlightCurrentLine); d->m_page->highlightBlocks->setChecked(displaySettings.m_highlightBlocks); d->m_page->animateMatchingParentheses->setChecked(displaySettings.m_animateMatchingParentheses); + d->m_page->highlightMatchingParentheses->setChecked(displaySettings.m_highlightMatchingParentheses); d->m_page->markTextChanges->setChecked(displaySettings.m_markTextChanges); d->m_page->autoFoldFirstComment->setChecked(displaySettings.m_autoFoldFirstComment); d->m_page->centerOnScroll->setChecked(displaySettings.m_centerCursorOnScroll); diff --git a/src/plugins/texteditor/displaysettingspage.ui b/src/plugins/texteditor/displaysettingspage.ui index c136ebaece..6a1f7b46f5 100644 --- a/src/plugins/texteditor/displaysettingspage.ui +++ b/src/plugins/texteditor/displaysettingspage.ui @@ -6,11 +6,61 @@ <rect> <x>0</x> <y>0</y> - <width>450</width> + <width>471</width> <height>288</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QGroupBox" name="groupBoxText"> + <property name="title"> + <string>Text Wrapping</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QCheckBox" name="enableTextWrapping"> + <property name="text"> + <string>Enable text &wrapping</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QCheckBox" name="showWrapColumn"> + <property name="text"> + <string>Display right &margin at column:</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="wrapColumn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximum"> + <number>999</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> <item row="2" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> @@ -82,13 +132,6 @@ </property> </widget> </item> - <item row="4" column="1"> - <widget class="QCheckBox" name="autoFoldFirstComment"> - <property name="text"> - <string>Auto-fold first &comment</string> - </property> - </widget> - </item> <item row="5" column="0"> <widget class="QCheckBox" name="centerOnScroll"> <property name="text"> @@ -96,55 +139,19 @@ </property> </widget> </item> - </layout> - </widget> - </item> - <item row="0" column="0"> - <widget class="QGroupBox" name="groupBoxText"> - <property name="title"> - <string>Text Wrapping</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QCheckBox" name="enableTextWrapping"> + <item row="5" column="1"> + <widget class="QCheckBox" name="autoFoldFirstComment"> <property name="text"> - <string>Enable text &wrapping</string> + <string>Auto-fold first &comment</string> </property> </widget> </item> - <item row="1" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QCheckBox" name="showWrapColumn"> - <property name="text"> - <string>Display right &margin at column:</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="wrapColumn"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="maximum"> - <number>999</number> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> + <item row="4" column="1"> + <widget class="QCheckBox" name="highlightMatchingParentheses"> + <property name="text"> + <string>&Highlight matching parentheses</string> + </property> + </widget> </item> </layout> </widget> diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp index e9c4b2df09..f31bc1b457 100644 --- a/src/plugins/texteditor/fontsettings.cpp +++ b/src/plugins/texteditor/fontsettings.cpp @@ -53,13 +53,13 @@ static const bool DEFAULT_ANTIALIAS = true; #ifdef Q_OS_MAC enum { DEFAULT_FONT_SIZE = 12 }; - static const char *DEFAULT_FONT_FAMILY = "Monaco"; + static const char DEFAULT_FONT_FAMILY[] = "Monaco"; #elif defined(Q_OS_UNIX) enum { DEFAULT_FONT_SIZE = 9 }; - static const char *DEFAULT_FONT_FAMILY = "Monospace"; + static const char DEFAULT_FONT_FAMILY[] = "Monospace"; #else enum { DEFAULT_FONT_SIZE = 10 }; - static const char *DEFAULT_FONT_FAMILY = "Courier"; + static const char DEFAULT_FONT_FAMILY[] = "Courier"; #endif } // anonymous namespace @@ -132,7 +132,7 @@ bool FontSettings::fromSettings(const QString &category, // Load color scheme from ini file foreach (const FormatDescription &desc, descriptions) { const TextStyle id = desc.id(); - const QString fmt = s->value(group + Constants::nameForStyle(id), QString()).toString(); + const QString fmt = s->value(group + QLatin1String(Constants::nameForStyle(id)), QString()).toString(); Format format; if (fmt.isEmpty()) { format.setForeground(desc.foreground()); @@ -260,6 +260,12 @@ void FontSettings::setAntialias(bool antialias) * Returns the format for the given font category. */ Format &FontSettings::formatFor(TextStyle category) + +{ + return m_scheme.formatFor(category); +} + +Format FontSettings::formatFor(TextStyle category) const { return m_scheme.formatFor(category); } diff --git a/src/plugins/texteditor/fontsettings.h b/src/plugins/texteditor/fontsettings.h index 31720e5eae..33f7a0299f 100644 --- a/src/plugins/texteditor/fontsettings.h +++ b/src/plugins/texteditor/fontsettings.h @@ -85,6 +85,7 @@ public: void setAntialias(bool antialias); Format &formatFor(TextStyle category); + Format formatFor(TextStyle category) const; QString colorSchemeFileName() const; void setColorSchemeFileName(const QString &fileName); diff --git a/src/plugins/texteditor/fontsettingspage.cpp b/src/plugins/texteditor/fontsettingspage.cpp index 74d413f9ab..8fca3108e0 100644 --- a/src/plugins/texteditor/fontsettingspage.cpp +++ b/src/plugins/texteditor/fontsettingspage.cpp @@ -100,8 +100,9 @@ public: void setColorSchemes(const QList<ColorSchemeEntry> &colorSchemes) { + beginResetModel(); m_colorSchemes = colorSchemes; - reset(); + endResetModel(); } const ColorSchemeEntry &colorSchemeAt(int index) const diff --git a/src/plugins/texteditor/generichighlighter/highlighter.h b/src/plugins/texteditor/generichighlighter/highlighter.h index ffd608e5af..13a06d118b 100644 --- a/src/plugins/texteditor/generichighlighter/highlighter.h +++ b/src/plugins/texteditor/generichighlighter/highlighter.h @@ -30,8 +30,8 @@ #ifndef HIGHLIGHTER_H #define HIGHLIGHTER_H -#include "basetextdocumentlayout.h" -#include "syntaxhighlighter.h" +#include "../basetextdocumentlayout.h" +#include "../syntaxhighlighter.h" #include <QString> #include <QVector> diff --git a/src/plugins/texteditor/generichighlighter/highlightersettingspage.h b/src/plugins/texteditor/generichighlighter/highlightersettingspage.h index 66fb1075b5..682a6bcd83 100644 --- a/src/plugins/texteditor/generichighlighter/highlightersettingspage.h +++ b/src/plugins/texteditor/generichighlighter/highlightersettingspage.h @@ -30,7 +30,7 @@ #ifndef HIGHLIGHTERSETTINGSPAGE_H #define HIGHLIGHTERSETTINGSPAGE_H -#include "texteditoroptionspage.h" +#include "../texteditoroptionspage.h" QT_BEGIN_NAMESPACE template <class> class QList; diff --git a/src/plugins/texteditor/icodestylepreferences.cpp b/src/plugins/texteditor/icodestylepreferences.cpp index 3d327dfe8d..850bb587d9 100644 --- a/src/plugins/texteditor/icodestylepreferences.cpp +++ b/src/plugins/texteditor/icodestylepreferences.cpp @@ -39,7 +39,7 @@ using namespace TextEditor; -static const char *currentPreferencesKey = "CurrentPreferences"; +static const char currentPreferencesKey[] = "CurrentPreferences"; namespace TextEditor { namespace Internal { diff --git a/src/plugins/texteditor/icodestylepreferencesfactory.h b/src/plugins/texteditor/icodestylepreferencesfactory.h index b801613404..60c4487d36 100644 --- a/src/plugins/texteditor/icodestylepreferencesfactory.h +++ b/src/plugins/texteditor/icodestylepreferencesfactory.h @@ -32,6 +32,8 @@ #include "texteditor_global.h" +#include <coreplugin/id.h> + #include <QObject> namespace TextEditor { @@ -47,7 +49,7 @@ class TEXTEDITOR_EXPORT ICodeStylePreferencesFactory : public QObject public: explicit ICodeStylePreferencesFactory(QObject *parent = 0); - virtual QString languageId() = 0; + virtual Core::Id languageId() = 0; virtual QString displayName() = 0; virtual ICodeStylePreferences *createCodeStyle() const = 0; virtual QWidget *createEditor(ICodeStylePreferences *preferences, QWidget *parent) const = 0; diff --git a/src/plugins/texteditor/itexteditor.h b/src/plugins/texteditor/itexteditor.h index 66ef363a59..7c702093b9 100644 --- a/src/plugins/texteditor/itexteditor.h +++ b/src/plugins/texteditor/itexteditor.h @@ -116,6 +116,7 @@ signals: void markContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu); void tooltipOverrideRequested(TextEditor::ITextEditor *editor, const QPoint &globalPos, int position, bool *handled); void tooltipRequested(TextEditor::ITextEditor *editor, const QPoint &globalPos, int position); + void markTooltipRequested(TextEditor::ITextEditor *editor, const QPoint &globalPos, int line); void contextHelpIdRequested(TextEditor::ITextEditor *editor, int position); }; diff --git a/src/plugins/texteditor/itextmark.cpp b/src/plugins/texteditor/itextmark.cpp index b81d742dbd..0ed2309562 100644 --- a/src/plugins/texteditor/itextmark.cpp +++ b/src/plugins/texteditor/itextmark.cpp @@ -80,7 +80,7 @@ ITextMark::Priority ITextMark::priority() const return m_priority; } -bool ITextMark::visible() const +bool ITextMark::isVisible() const { return m_visible; } @@ -102,7 +102,7 @@ void ITextMark::setWidthFactor(double factor) m_widthFactor = factor; } -bool ITextMark::clickable() const +bool ITextMark::isClickable() const { return false; } @@ -110,6 +110,16 @@ bool ITextMark::clickable() const void ITextMark::clicked() {} +bool ITextMark::isDraggable() const +{ + return false; +} + +void ITextMark::dragToLine(int lineNumber) +{ + Q_UNUSED(lineNumber); +} + ITextMarkable *ITextMark::markableInterface() const { return m_markableInterface; diff --git a/src/plugins/texteditor/itextmark.h b/src/plugins/texteditor/itextmark.h index eed816da36..95dafedbba 100644 --- a/src/plugins/texteditor/itextmark.h +++ b/src/plugins/texteditor/itextmark.h @@ -74,16 +74,18 @@ public: virtual void updateLineNumber(int lineNumber); virtual void updateBlock(const QTextBlock &block); virtual void removedFromEditor(); - virtual bool clickable() const; + virtual bool isClickable() const; virtual void clicked(); + virtual bool isDraggable() const; + virtual void dragToLine(int lineNumber); void setIcon(const QIcon &icon); // call this if the icon has changed. void updateMarker(); Priority priority() const; void setPriority(Priority prioriy); - bool visible() const; - void setVisible(bool visible); + bool isVisible() const; + void setVisible(bool isVisible); double widthFactor() const; void setWidthFactor(double factor); diff --git a/src/plugins/texteditor/plaintexteditor.cpp b/src/plugins/texteditor/plaintexteditor.cpp index 237c21fa6a..84b03254cb 100644 --- a/src/plugins/texteditor/plaintexteditor.cpp +++ b/src/plugins/texteditor/plaintexteditor.cpp @@ -90,7 +90,7 @@ Core::IEditor *PlainTextEditor::duplicate(QWidget *parent) Core::Id PlainTextEditor::id() const { - return Core::Constants::K_DEFAULT_TEXT_EDITOR_ID; + return Core::Id(Core::Constants::K_DEFAULT_TEXT_EDITOR_ID); } void PlainTextEditorWidget::unCommentSelection() diff --git a/src/plugins/texteditor/plaintexteditorfactory.cpp b/src/plugins/texteditor/plaintexteditorfactory.cpp index d904152d9e..08977d7016 100644 --- a/src/plugins/texteditor/plaintexteditorfactory.cpp +++ b/src/plugins/texteditor/plaintexteditorfactory.cpp @@ -65,7 +65,7 @@ PlainTextEditorFactory::~PlainTextEditorFactory() Core::Id PlainTextEditorFactory::id() const { - return Core::Constants::K_DEFAULT_TEXT_EDITOR_ID; + return Core::Id(Core::Constants::K_DEFAULT_TEXT_EDITOR_ID); } QString PlainTextEditorFactory::displayName() const @@ -91,7 +91,7 @@ void PlainTextEditorFactory::updateEditorInfoBar(Core::IEditor *editor) if (!file) return; PlainTextEditorWidget *textEditor = static_cast<PlainTextEditorWidget *>(editorEditable->editorWidget()); - const QString infoSyntaxDefinition = QLatin1String(Constants::INFO_SYNTAX_DEFINITION); + Core::Id infoSyntaxDefinition(Constants::INFO_SYNTAX_DEFINITION); if (textEditor->isMissingSyntaxDefinition() && !textEditor->ignoreMissingSyntaxDefinition() && TextEditorSettings::instance()->highlighterSettings().alertWhenNoDefinition()) { diff --git a/src/plugins/texteditor/quickfix.h b/src/plugins/texteditor/quickfix.h index 7685541b1f..1993535f7d 100644 --- a/src/plugins/texteditor/quickfix.h +++ b/src/plugins/texteditor/quickfix.h @@ -90,6 +90,9 @@ private: QString _description; }; +typedef QList<QuickFixOperation::Ptr> QuickFixOperations; +typedef QSharedPointer<const IAssistInterface> QuickFixInterface; + /*! The QuickFixFactory is responsible for generating QuickFixOperation s which are applicable to the given QuickFixState. @@ -107,10 +110,9 @@ class TEXTEDITOR_EXPORT QuickFixFactory: public QObject public: QuickFixFactory(QObject *parent = 0); - virtual ~QuickFixFactory(); + ~QuickFixFactory(); - virtual QList<QuickFixOperation::Ptr> - matchingOperations(const QSharedPointer<const IAssistInterface> &interface) = 0; + virtual void matchingOperations(const QuickFixInterface &interface, QuickFixOperations &result) = 0; }; } // namespace TextEditor diff --git a/src/plugins/texteditor/snippets/snippeteditor.cpp b/src/plugins/texteditor/snippets/snippeteditor.cpp index d9b8d31384..4d346aa499 100644 --- a/src/plugins/texteditor/snippets/snippeteditor.cpp +++ b/src/plugins/texteditor/snippets/snippeteditor.cpp @@ -53,7 +53,7 @@ SnippetEditor::SnippetEditor(SnippetEditorWidget *editor) Core::Id SnippetEditor::id() const { - return Constants::SNIPPET_EDITOR_ID; + return Core::Id(Constants::SNIPPET_EDITOR_ID); } SnippetEditorWidget::SnippetEditorWidget(QWidget *parent) : BaseTextEditorWidget(parent) diff --git a/src/plugins/texteditor/snippets/snippetssettingspage.cpp b/src/plugins/texteditor/snippets/snippetssettingspage.cpp index 6404be97bf..f8ad8cdf2d 100644 --- a/src/plugins/texteditor/snippets/snippetssettingspage.cpp +++ b/src/plugins/texteditor/snippets/snippetssettingspage.cpp @@ -164,8 +164,9 @@ QVariant SnippetsTableModel::headerData(int section, Qt::Orientation orientation void SnippetsTableModel::load(const QString &groupId) { + beginResetModel(); m_activeGroupId = groupId; - reset(); + endResetModel(); } QList<QString> SnippetsTableModel::groupIds() const @@ -218,14 +219,16 @@ void SnippetsTableModel::revertBuitInSnippet(const QModelIndex &modelIndex) void SnippetsTableModel::restoreRemovedBuiltInSnippets() { + beginResetModel(); m_collection->restoreRemovedSnippets(m_activeGroupId); - reset(); + endResetModel(); } void SnippetsTableModel::resetSnippets() { + beginResetModel(); m_collection->reset(m_activeGroupId); - reset(); + endResetModel(); } void SnippetsTableModel::replaceSnippet(const Snippet &snippet, const QModelIndex &modelIndex) diff --git a/src/plugins/texteditor/snippets/snippetssettingspage.h b/src/plugins/texteditor/snippets/snippetssettingspage.h index 4786a738cc..24667488d0 100644 --- a/src/plugins/texteditor/snippets/snippetssettingspage.h +++ b/src/plugins/texteditor/snippets/snippetssettingspage.h @@ -30,7 +30,7 @@ #ifndef SNIPPETSSETTINGSPAGE_H #define SNIPPETSSETTINGSPAGE_H -#include "texteditoroptionspage.h" +#include "../texteditoroptionspage.h" namespace TextEditor { namespace Internal { diff --git a/src/plugins/texteditor/storagesettings.cpp b/src/plugins/texteditor/storagesettings.cpp index cbc020ff32..a4654984e8 100644 --- a/src/plugins/texteditor/storagesettings.cpp +++ b/src/plugins/texteditor/storagesettings.cpp @@ -36,11 +36,11 @@ namespace TextEditor { -static const char * const cleanWhitespaceKey = "cleanWhitespace"; -static const char * const inEntireDocumentKey = "inEntireDocument"; -static const char * const addFinalNewLineKey = "addFinalNewLine"; -static const char * const cleanIndentationKey = "cleanIndentation"; -static const char * const groupPostfix = "StorageSettings"; +static const char cleanWhitespaceKey[] = "cleanWhitespace"; +static const char inEntireDocumentKey[] = "inEntireDocument"; +static const char addFinalNewLineKey[] = "addFinalNewLine"; +static const char cleanIndentationKey[] = "cleanIndentation"; +static const char groupPostfix[] = "StorageSettings"; StorageSettings::StorageSettings() : m_cleanWhitespace(true), diff --git a/src/plugins/texteditor/syntaxhighlighter.cpp b/src/plugins/texteditor/syntaxhighlighter.cpp index f39e8c6d2f..4f9c8f8704 100644 --- a/src/plugins/texteditor/syntaxhighlighter.cpp +++ b/src/plugins/texteditor/syntaxhighlighter.cpp @@ -40,6 +40,8 @@ #include <qtextedit.h> #include <qtimer.h> +#include <math.h> + using namespace TextEditor; class TextEditor::SyntaxHighlighterPrivate @@ -755,4 +757,38 @@ void SyntaxHighlighter::setExtraAdditionalFormats(const QTextBlock& block, d->inReformatBlocks = wasInReformatBlocks; } +/* Generate at least n different colors for highlighting, excluding background + * color. */ + +QList<QColor> SyntaxHighlighter::generateColors(int n, const QColor &background) +{ + QList<QColor> result; + // Assign a color gradient. Generate a sufficient number of colors + // by using ceil and looping from 0..step. + const double oneThird = 1.0 / 3.0; + const int step = qRound(ceil(pow(double(n), oneThird))); + result.reserve(step * step * step); + const int factor = 255 / step; + const int half = factor / 2; + const int bgRed = background.red(); + const int bgGreen = background.green(); + const int bgBlue = background.blue(); + for (int r = step; r >= 0; --r) { + const int red = r * factor; + if (bgRed - half > red || bgRed + half <= red) { + for (int g = step; g >= 0; --g) { + const int green = g * factor; + if (bgGreen - half > green || bgGreen + half <= green) { + for (int b = step; b >= 0 ; --b) { + const int blue = b * factor; + if (bgBlue - half > blue || bgBlue + half <= blue) + result.append(QColor(red, green, blue)); + } + } + } + } + } + return result; +} + #include "moc_syntaxhighlighter.cpp" diff --git a/src/plugins/texteditor/syntaxhighlighter.h b/src/plugins/texteditor/syntaxhighlighter.h index 047ed51890..72e71900eb 100644 --- a/src/plugins/texteditor/syntaxhighlighter.h +++ b/src/plugins/texteditor/syntaxhighlighter.h @@ -66,6 +66,8 @@ public: void setExtraAdditionalFormats(const QTextBlock& block, const QList<QTextLayout::FormatRange> &formats); + static QList<QColor> generateColors(int n, const QColor &background); + public Q_SLOTS: void rehighlight(); void rehighlightBlock(const QTextBlock &block); diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro index d123c07569..5840f6b61d 100644 --- a/src/plugins/texteditor/texteditor.pro +++ b/src/plugins/texteditor/texteditor.pro @@ -116,7 +116,8 @@ SOURCES += texteditorplugin.cpp \ codestyleeditor.cpp \ circularclipboard.cpp \ circularclipboardassist.cpp \ - itextmark.cpp + itextmark.cpp \ + codeassist/keywordscompletionassist.cpp HEADERS += texteditorplugin.h \ textfilewizard.h \ @@ -235,7 +236,8 @@ HEADERS += texteditorplugin.h \ basefilefind_p.h \ circularclipboard.h \ circularclipboardassist.h \ - itextmark.h + itextmark.h \ + codeassist/keywordscompletionassist.h FORMS += \ displaysettingspage.ui \ diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs index fc8d395779..ef14c2500d 100644 --- a/src/plugins/texteditor/texteditor.qbs +++ b/src/plugins/texteditor/texteditor.qbs @@ -11,16 +11,12 @@ QtcPlugin { Depends { name: "Find" } Depends { name: "Locator" } - cpp.includePaths: [ - ".", - "..", + cpp.includePaths: base.concat([ "generichighlighter", "tooltip", "snippets", - "codeassist", - "../../libs", - buildDirectory - ] + "codeassist" + ]) files: [ "TextEditor.mimetypes.xml", @@ -62,10 +58,10 @@ QtcPlugin { "codestyleselectorwidget.h", "codestyleselectorwidget.ui", "colorscheme.cpp", + "colorscheme.h", "colorschemeedit.cpp", "colorschemeedit.h", "colorschemeedit.ui", - "colorscheme.h", "completionsettings.cpp", "completionsettings.h", "convenience.cpp", @@ -91,9 +87,9 @@ QtcPlugin { "helpitem.cpp", "helpitem.h", "icodestylepreferences.cpp", + "icodestylepreferences.h", "icodestylepreferencesfactory.cpp", "icodestylepreferencesfactory.h", - "icodestylepreferences.h", "indenter.cpp", "indenter.h", "ioutlinewidget.h", @@ -108,9 +104,9 @@ QtcPlugin { "outlinefactory.cpp", "outlinefactory.h", "plaintexteditor.cpp", + "plaintexteditor.h", "plaintexteditorfactory.cpp", "plaintexteditorfactory.h", - "plaintexteditor.h", "quickfix.cpp", "quickfix.h", "refactoringchanges.cpp", @@ -132,18 +128,18 @@ QtcPlugin { "tabsettingswidget.cpp", "tabsettingswidget.h", "tabsettingswidget.ui", + "texteditor.qrc", + "texteditor_global.h", "texteditoractionhandler.cpp", "texteditoractionhandler.h", "texteditorconstants.cpp", "texteditorconstants.h", - "texteditor_global.h", "texteditoroptionspage.cpp", "texteditoroptionspage.h", "texteditoroverlay.cpp", "texteditoroverlay.h", "texteditorplugin.cpp", "texteditorplugin.h", - "texteditor.qrc", "texteditorsettings.cpp", "texteditorsettings.h", "textfilewizard.cpp", @@ -192,6 +188,9 @@ QtcPlugin { "ifunctionhintproposalmodel.h", "igenericproposalmodel.cpp", "igenericproposalmodel.h", + "ikeywords.h", + "keywordscompletionassist.cpp", + "keywordscompletionassist.h", "quickfixassistprocessor.cpp", "quickfixassistprocessor.h", "quickfixassistprovider.cpp", @@ -217,8 +216,8 @@ QtcPlugin { "highlightdefinitionmetadata.cpp", "highlightdefinitionmetadata.h", "highlighter.cpp", - "highlighterexception.h", "highlighter.h", + "highlighterexception.h", "highlightersettings.cpp", "highlightersettings.h", "highlightersettingspage.cpp", @@ -253,12 +252,12 @@ QtcPlugin { "plaintextsnippetprovider.cpp", "plaintextsnippetprovider.h", "reuse.h", + "snippet.cpp", + "snippet.h", "snippetassistcollector.cpp", "snippetassistcollector.h", - "snippet.cpp", "snippeteditor.cpp", "snippeteditor.h", - "snippet.h", "snippetscollection.cpp", "snippetscollection.h", "snippetssettings.cpp", @@ -281,7 +280,7 @@ QtcPlugin { "tips.cpp", "tips.h", "tooltip.cpp", - "tooltip.h" + "tooltip.h", ] } @@ -290,4 +289,3 @@ QtcPlugin { Depends { name: "Locator" } } } - diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index d6d75baafb..e3ef0e315b 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -274,9 +274,14 @@ void TextEditorPlugin::invokeQuickFix() void TextEditorPlugin::updateSearchResultsFont(const FontSettings &settings) { - if (m_searchResultWindow) + if (m_searchResultWindow) { m_searchResultWindow->setTextEditorFont(QFont(settings.family(), - settings.fontSize() * settings.fontZoom() / 100)); + settings.fontSize() * settings.fontZoom() / 100), + settings.formatFor(TextEditor::C_TEXT).foreground(), + settings.formatFor(TextEditor::C_TEXT).background(), + settings.formatFor(TextEditor::C_SEARCH_RESULT).foreground(), + settings.formatFor(TextEditor::C_SEARCH_RESULT).background()); + } } void TextEditorPlugin::updateVariable(const QByteArray &variable) diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp index 5e0664f427..e761795d35 100644 --- a/src/plugins/texteditor/texteditorsettings.cpp +++ b/src/plugins/texteditor/texteditorsettings.cpp @@ -69,11 +69,11 @@ public: HighlighterSettingsPage *m_highlighterSettingsPage; SnippetsSettingsPage *m_snippetsSettingsPage; - QMap<QString, ICodeStylePreferencesFactory *> m_languageToFactory; + QMap<Core::Id, ICodeStylePreferencesFactory *> m_languageToFactory; - QMap<QString, ICodeStylePreferences *> m_languageToCodeStyle; - QMap<QString, CodeStylePool *> m_languageToCodeStylePool; - QMap<QString, QString> m_mimeTypeToLanguage; + QMap<Core::Id, ICodeStylePreferences *> m_languageToCodeStyle; + QMap<Core::Id, CodeStylePool *> m_languageToCodeStylePool; + QMap<QString, Core::Id> m_mimeTypeToLanguage; CompletionSettings m_completionSettings; @@ -411,12 +411,12 @@ void TextEditorSettings::registerCodeStyleFactory(ICodeStylePreferencesFactory * m_d->m_languageToFactory.insert(factory->languageId(), factory); } -QMap<QString, ICodeStylePreferencesFactory *> TextEditorSettings::codeStyleFactories() const +QMap<Core::Id, ICodeStylePreferencesFactory *> TextEditorSettings::codeStyleFactories() const { return m_d->m_languageToFactory; } -ICodeStylePreferencesFactory *TextEditorSettings::codeStyleFactory(const QString &languageId) const +ICodeStylePreferencesFactory *TextEditorSettings::codeStyleFactory(Core::Id languageId) const { return m_d->m_languageToFactory.value(languageId); } @@ -426,17 +426,17 @@ ICodeStylePreferences *TextEditorSettings::codeStyle() const return m_d->m_behaviorSettingsPage->codeStyle(); } -ICodeStylePreferences *TextEditorSettings::codeStyle(const QString &languageId) const +ICodeStylePreferences *TextEditorSettings::codeStyle(Core::Id languageId) const { return m_d->m_languageToCodeStyle.value(languageId, codeStyle()); } -QMap<QString, ICodeStylePreferences *> TextEditorSettings::codeStyles() const +QMap<Core::Id, ICodeStylePreferences *> TextEditorSettings::codeStyles() const { return m_d->m_languageToCodeStyle; } -void TextEditorSettings::registerCodeStyle(const QString &languageId, ICodeStylePreferences *prefs) +void TextEditorSettings::registerCodeStyle(Core::Id languageId, ICodeStylePreferences *prefs) { m_d->m_languageToCodeStyle.insert(languageId, prefs); } @@ -446,22 +446,22 @@ CodeStylePool *TextEditorSettings::codeStylePool() const return m_d->m_behaviorSettingsPage->codeStylePool(); } -CodeStylePool *TextEditorSettings::codeStylePool(const QString &languageId) const +CodeStylePool *TextEditorSettings::codeStylePool(Core::Id languageId) const { return m_d->m_languageToCodeStylePool.value(languageId); } -void TextEditorSettings::registerCodeStylePool(const QString &languageId, CodeStylePool *pool) +void TextEditorSettings::registerCodeStylePool(Core::Id languageId, CodeStylePool *pool) { m_d->m_languageToCodeStylePool.insert(languageId, pool); } -void TextEditorSettings::registerMimeTypeForLanguageId(const QString &mimeType, const QString &languageId) +void TextEditorSettings::registerMimeTypeForLanguageId(const QString &mimeType, Core::Id languageId) { m_d->m_mimeTypeToLanguage.insert(mimeType, languageId); } -QString TextEditorSettings::languageId(const QString &mimeType) const +Core::Id TextEditorSettings::languageId(const QString &mimeType) const { return m_d->m_mimeTypeToLanguage.value(mimeType); } diff --git a/src/plugins/texteditor/texteditorsettings.h b/src/plugins/texteditor/texteditorsettings.h index 400f963bcb..4baba8cc04 100644 --- a/src/plugins/texteditor/texteditorsettings.h +++ b/src/plugins/texteditor/texteditorsettings.h @@ -32,6 +32,8 @@ #include "texteditor_global.h" +#include <coreplugin/id.h> + #include <QObject> QT_BEGIN_NAMESPACE @@ -87,21 +89,21 @@ public: void setCompletionSettings(const TextEditor::CompletionSettings &); - ICodeStylePreferencesFactory *codeStyleFactory(const QString &languageId) const; - QMap<QString, ICodeStylePreferencesFactory *> codeStyleFactories() const; + ICodeStylePreferencesFactory *codeStyleFactory(Core::Id languageId) const; + QMap<Core::Id, ICodeStylePreferencesFactory *> codeStyleFactories() const; void registerCodeStyleFactory(ICodeStylePreferencesFactory *codeStyleFactory); CodeStylePool *codeStylePool() const; - CodeStylePool *codeStylePool(const QString &languageId) const; - void registerCodeStylePool(const QString &languageId, CodeStylePool *pool); + CodeStylePool *codeStylePool(Core::Id languageId) const; + void registerCodeStylePool(Core::Id languageId, CodeStylePool *pool); ICodeStylePreferences *codeStyle() const; - ICodeStylePreferences *codeStyle(const QString &languageId) const; - QMap<QString, ICodeStylePreferences *> codeStyles() const; - void registerCodeStyle(const QString &languageId, ICodeStylePreferences *prefs); + ICodeStylePreferences *codeStyle(Core::Id languageId) const; + QMap<Core::Id, ICodeStylePreferences *> codeStyles() const; + void registerCodeStyle(Core::Id languageId, ICodeStylePreferences *prefs); - void registerMimeTypeForLanguageId(const QString &mimeType, const QString &languageId); - QString languageId(const QString &mimeType) const; + void registerMimeTypeForLanguageId(const QString &mimeType, Core::Id languageId); + Core::Id languageId(const QString &mimeType) const; signals: void fontSettingsChanged(const TextEditor::FontSettings &); diff --git a/src/plugins/texteditor/tooltip/tooltip.cpp b/src/plugins/texteditor/tooltip/tooltip.cpp index 7721155da2..d4f2521860 100644 --- a/src/plugins/texteditor/tooltip/tooltip.cpp +++ b/src/plugins/texteditor/tooltip/tooltip.cpp @@ -34,6 +34,8 @@ #include "effects.h" #include "reuse.h" +#include <utils/hostosinfo.h> + #include <QString> #include <QColor> #include <QApplication> @@ -204,14 +206,7 @@ void ToolTip::placeTip(const QPoint &pos, QWidget *w) { QRect screen = Internal::screenGeometry(pos, w); QPoint p = pos; - p += QPoint(2, -#ifdef Q_OS_WIN - 21 -#else - 16 -#endif - ); - + p += QPoint(2, Utils::HostOsInfo::isWindowsHost() ? 21 : 16); if (p.x() + m_tip->width() > screen.x() + screen.width()) p.rx() -= 4 + m_tip->width(); if (p.y() + m_tip->height() > screen.y() + screen.height()) diff --git a/src/plugins/todo/todo.qbs b/src/plugins/todo/todo.qbs index 8629356c0e..85d218de15 100644 --- a/src/plugins/todo/todo.qbs +++ b/src/plugins/todo/todo.qbs @@ -15,21 +15,16 @@ QtcPlugin { Depends { name: "cpp" } cpp.defines: base.concat(["QT_NO_CAST_FROM_ASCII"]) - cpp.includePaths: [ - "..", - "../../libs", - buildDirectory - ] files: [ "constants.h", "cpptodoitemsscanner.cpp", "cpptodoitemsscanner.h", "keyword.cpp", + "keyword.h", "keyworddialog.cpp", "keyworddialog.h", "keyworddialog.ui", - "keyword.h", "lineparser.cpp", "lineparser.h", "optionsdialog.cpp", @@ -52,6 +47,6 @@ QtcPlugin { "todooutputpane.h", "todoplugin.cpp", "todoplugin.h", - "todoplugin.qrc" + "todoplugin.qrc", ] } diff --git a/src/plugins/updateinfo/updateinfo.qbs b/src/plugins/updateinfo/updateinfo.qbs index 716ff5e686..de31720174 100644 --- a/src/plugins/updateinfo/updateinfo.qbs +++ b/src/plugins/updateinfo/updateinfo.qbs @@ -21,6 +21,6 @@ QtcPlugin { "updateinfobutton.cpp", "updateinfobutton.h", "updateinfoplugin.cpp", - "updateinfoplugin.h" + "updateinfoplugin.h", ] } diff --git a/src/plugins/valgrind/callgrind/callgrindcontroller.cpp b/src/plugins/valgrind/callgrind/callgrindcontroller.cpp index 861252bee1..1d2f9b0e46 100644 --- a/src/plugins/valgrind/callgrind/callgrindcontroller.cpp +++ b/src/plugins/valgrind/callgrind/callgrindcontroller.cpp @@ -28,12 +28,12 @@ ****************************************************************************/ #include "callgrindcontroller.h" +#include "../valgrindprocess.h" #include <QDebug> #include <QDir> -#include <valgrindprocess.h> - +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <ssh/sftpchannel.h> @@ -134,11 +134,7 @@ void CallgrindController::run(Option option) #if CALLGRIND_CONTROL_DEBUG m_process->setProcessChannelMode(QProcess::ForwardedChannels); #endif -#ifdef Q_OS_WIN - int pid = 0; -#else - const int pid = m_valgrindProc->pid(); -#endif + const int pid = Utils::HostOsInfo::isWindowsHost() ? 0 : m_valgrindProc->pid(); m_process->run(CALLGRIND_CONTROL_BINARY, QStringList() << optionString << QString::number(pid), QString(), QString()); diff --git a/src/plugins/valgrind/callgrind/callgrindrunner.h b/src/plugins/valgrind/callgrind/callgrindrunner.h index ff2f8efdb6..e42c821f80 100644 --- a/src/plugins/valgrind/callgrind/callgrindrunner.h +++ b/src/plugins/valgrind/callgrind/callgrindrunner.h @@ -30,7 +30,7 @@ #ifndef VALGRIND_CALLGRIND_CALLGRINDRUNNER_H #define VALGRIND_CALLGRIND_CALLGRINDRUNNER_H -#include <valgrindrunner.h> +#include "../valgrindrunner.h" #include "callgrindcontroller.h" diff --git a/src/plugins/valgrind/callgrindtool.cpp b/src/plugins/valgrind/callgrindtool.cpp index 740b67e061..03cfd63904 100644 --- a/src/plugins/valgrind/callgrindtool.cpp +++ b/src/plugins/valgrind/callgrindtool.cpp @@ -516,7 +516,7 @@ CallgrindTool::~CallgrindTool() Core::Id CallgrindTool::id() const { - return "Callgrind"; + return Core::Id("Callgrind"); } ProjectExplorer::RunMode CallgrindTool::runMode() const diff --git a/src/plugins/valgrind/memcheck/memcheckrunner.cpp b/src/plugins/valgrind/memcheck/memcheckrunner.cpp index 17a600e240..48393113c9 100644 --- a/src/plugins/valgrind/memcheck/memcheckrunner.cpp +++ b/src/plugins/valgrind/memcheck/memcheckrunner.cpp @@ -30,9 +30,9 @@ #include "memcheckrunner.h" -#include <xmlprotocol/error.h> -#include <xmlprotocol/status.h> -#include <xmlprotocol/threadedparser.h> +#include "../xmlprotocol/error.h" +#include "../xmlprotocol/status.h" +#include "../xmlprotocol/threadedparser.h" #include <utils/qtcassert.h> diff --git a/src/plugins/valgrind/memcheck/memcheckrunner.h b/src/plugins/valgrind/memcheck/memcheckrunner.h index 28bd93e76c..2dd1ccc4fd 100644 --- a/src/plugins/valgrind/memcheck/memcheckrunner.h +++ b/src/plugins/valgrind/memcheck/memcheckrunner.h @@ -31,7 +31,7 @@ #ifndef VALGRIND_PROTOCOL_MEMCHECKRUNNER_H #define VALGRIND_PROTOCOL_MEMCHECKRUNNER_H -#include <valgrindrunner.h> +#include "../valgrindrunner.h" namespace Valgrind { diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index ddaed33490..1b26e02a45 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -283,7 +283,7 @@ void MemcheckTool::maybeActiveRunConfigurationChanged() Core::Id MemcheckTool::id() const { - return "Memcheck"; + return Core::Id("Memcheck"); } ProjectExplorer::RunMode MemcheckTool::runMode() const diff --git a/src/plugins/valgrind/valgrind.qbs b/src/plugins/valgrind/valgrind.qbs index dfdc6d6582..e3add86457 100644 --- a/src/plugins/valgrind/valgrind.qbs +++ b/src/plugins/valgrind/valgrind.qbs @@ -13,15 +13,6 @@ QtcPlugin { Depends { name: "RemoteLinux" } Depends { name: "CPlusPlus"} - Depends { name: "cpp" } - cpp.includePaths: [ - ".", - "valgrind", - "..", - "../../libs", - buildDirectory - ] - files: [ "callgrindcostdelegate.cpp", "callgrindcostdelegate.h", @@ -54,16 +45,16 @@ QtcPlugin { "valgrindengine.h", "valgrindplugin.cpp", "valgrindplugin.h", + "valgrindprocess.cpp", + "valgrindprocess.h", + "valgrindrunner.cpp", + "valgrindrunner.h", "valgrindsettings.cpp", "valgrindsettings.h", "valgrindtool.cpp", "valgrindtool.h", "workarounds.cpp", "workarounds.h", - "valgrindprocess.cpp", - "valgrindprocess.h", - "valgrindrunner.cpp", - "valgrindrunner.h", "callgrind/callgrindabstractmodel.h", "callgrind/callgrindcallmodel.cpp", "callgrind/callgrindcallmodel.h", @@ -115,7 +106,6 @@ QtcPlugin { "xmlprotocol/suppression.cpp", "xmlprotocol/suppression.h", "xmlprotocol/threadedparser.cpp", - "xmlprotocol/threadedparser.h" + "xmlprotocol/threadedparser.h", ] } - diff --git a/src/plugins/valgrind/valgrindconfigwidget.cpp b/src/plugins/valgrind/valgrindconfigwidget.cpp index e5e8e01141..7b63c68be8 100644 --- a/src/plugins/valgrind/valgrindconfigwidget.cpp +++ b/src/plugins/valgrind/valgrindconfigwidget.cpp @@ -33,6 +33,7 @@ #include "ui_valgrindconfigwidget.h" +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDebug> @@ -63,12 +64,12 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings, connect(m_settings, SIGNAL(valgrindExecutableChanged(QString)), m_ui->valgrindExeChooser, SLOT(setPath(QString))); -#ifdef Q_OS_WIN - // FIXME: On Window we know that we don't have a local valgrind - // executable, so having the "Browse" button in the path chooser - // (which is needed for the remote executable) is confusing. - m_ui->valgrindExeChooser->buttonAtIndex(0)->hide(); -#endif + if (Utils::HostOsInfo::isWindowsHost()) { + // FIXME: On Window we know that we don't have a local valgrind + // executable, so having the "Browse" button in the path chooser + // (which is needed for the remote executable) is confusing. + m_ui->valgrindExeChooser->buttonAtIndex(0)->hide(); + } // // Callgrind diff --git a/src/plugins/valgrind/valgrindplugin.cpp b/src/plugins/valgrind/valgrindplugin.cpp index ee546e7de2..32f4b90be3 100644 --- a/src/plugins/valgrind/valgrindplugin.cpp +++ b/src/plugins/valgrind/valgrindplugin.cpp @@ -43,6 +43,7 @@ #include <projectexplorer/applicationrunconfiguration.h> #include <projectexplorer/projectexplorer.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDebug> @@ -91,9 +92,8 @@ void ValgrindPlugin::startValgrindTool(IAnalyzerTool *tool, StartMode mode) bool ValgrindPlugin::initialize(const QStringList &, QString *) { StartModes modes; -#ifndef Q_OS_WIN - modes.append(StartMode(StartLocal)); -#endif + if (!Utils::HostOsInfo::isWindowsHost()) + modes.append(StartMode(StartLocal)); modes.append(StartMode(StartRemote)); AnalyzerManager::addTool(new MemcheckTool(this), modes); diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp index fbb19174d7..71d38699ed 100644 --- a/src/plugins/valgrind/valgrindrunner.cpp +++ b/src/plugins/valgrind/valgrindrunner.cpp @@ -31,9 +31,10 @@ #include "valgrindrunner.h" #include "valgrindprocess.h" +#include <utils/environment.h> +#include <utils/hostosinfo.h> #include <utils/qtcassert.h> -#include <utils/environment.h> #include <ssh/sshconnection.h> #include <ssh/sshremoteprocess.h> @@ -91,10 +92,9 @@ void ValgrindRunner::Private::run(ValgrindProcess *_process) QStringList valgrindArgs = valgrindArguments; valgrindArgs << QString("--tool=%1").arg(q->tool()); -#ifdef Q_OS_MAC - // May be slower to start but without it we get no filenames for symbols. - valgrindArgs << QLatin1String("--dsymutil=yes"); -#endif + if (Utils::HostOsInfo::isMacHost()) + // May be slower to start but without it we get no filenames for symbols. + valgrindArgs << QLatin1String("--dsymutil=yes"); QObject::connect(process, SIGNAL(processOutput(QByteArray,Utils::OutputFormat)), q, SIGNAL(processOutputReceived(QByteArray,Utils::OutputFormat))); diff --git a/src/plugins/valgrind/valgrindsettings.cpp b/src/plugins/valgrind/valgrindsettings.cpp index d00d5e88c9..ca417a48a3 100644 --- a/src/plugins/valgrind/valgrindsettings.cpp +++ b/src/plugins/valgrind/valgrindsettings.cpp @@ -324,6 +324,13 @@ void ValgrindGlobalSettings::fromMap(const QVariantMap &map) setIfPresent(map, QLatin1String(callgrindShortenTemplates), &m_shortenTemplates); } +AbstractAnalyzerSubConfig *ValgrindGlobalSettings::clone() +{ + ValgrindGlobalSettings *other = new ValgrindGlobalSettings; + other->fromMap(toMap()); + return other; +} + QVariantMap ValgrindGlobalSettings::toMap() const { QVariantMap map = ValgrindBaseSettings::toMap(); @@ -457,6 +464,13 @@ void ValgrindProjectSettings::fromMap(const QVariantMap &map) setIfPresent(map, removedSuppressionFilesC, &m_disabledGlobalSuppressionFiles); } +AbstractAnalyzerSubConfig *ValgrindProjectSettings::clone() +{ + ValgrindProjectSettings *other = new ValgrindProjectSettings; + other->fromMap(toMap()); + return other; +} + QVariantMap ValgrindProjectSettings::toMap() const { QVariantMap map = ValgrindBaseSettings::toMap(); diff --git a/src/plugins/valgrind/valgrindsettings.h b/src/plugins/valgrind/valgrindsettings.h index 3f221d5299..feb1881fea 100644 --- a/src/plugins/valgrind/valgrindsettings.h +++ b/src/plugins/valgrind/valgrindsettings.h @@ -173,6 +173,7 @@ public: QVariantMap toMap() const; QVariantMap defaults() const; void fromMap(const QVariantMap &map); + virtual AbstractAnalyzerSubConfig *clone(); /* * Global memcheck settings @@ -230,6 +231,7 @@ public: QVariantMap toMap() const; QVariantMap defaults() const; void fromMap(const QVariantMap &map); + virtual AbstractAnalyzerSubConfig *clone(); /** * Per-project memcheck settings, saves a diff to the global suppression files list diff --git a/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp b/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp index 6e12d51c1e..a7fc21211a 100644 --- a/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp +++ b/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp @@ -60,7 +60,7 @@ QString toolTipForFrame(const Frame &frame) if (frame.instructionPointer()) lines << qMakePair(QCoreApplication::translate("Valgrind::XmlProtocol", "Instruction pointer:"), - QString::fromAscii("0x%1").arg(frame.instructionPointer(), 0, 16)); + QString::fromLatin1("0x%1").arg(frame.instructionPointer(), 0, 16)); if (!frame.object().isEmpty()) lines << qMakePair(QCoreApplication::translate("Valgrind::XmlProtocol", "Object:"), frame.object()); diff --git a/src/plugins/valgrind/xmlprotocol/stackmodel.cpp b/src/plugins/valgrind/xmlprotocol/stackmodel.cpp index 4404acfe0c..0e9e16f31b 100644 --- a/src/plugins/valgrind/xmlprotocol/stackmodel.cpp +++ b/src/plugins/valgrind/xmlprotocol/stackmodel.cpp @@ -219,8 +219,9 @@ void StackModel::setError(const Error &error) { if (d->error == error) return; + beginResetModel(); d->error = error; - reset(); + endResetModel(); } void StackModel::clear() diff --git a/src/plugins/valgrind/xmlprotocol/threadedparser.cpp b/src/plugins/valgrind/xmlprotocol/threadedparser.cpp index 9784cd58f3..f8d7d0e9b9 100644 --- a/src/plugins/valgrind/xmlprotocol/threadedparser.cpp +++ b/src/plugins/valgrind/xmlprotocol/threadedparser.cpp @@ -39,7 +39,7 @@ #include <QIODevice> #include <QMetaType> #include <QThread> -#include <QSharedPointer> +#include <QPointer> namespace { @@ -74,7 +74,7 @@ public: Private() {} - QWeakPointer<Thread> parserThread; + QPointer<Thread> parserThread; QString errorString; }; diff --git a/src/plugins/vcsbase/baseannotationhighlighter.cpp b/src/plugins/vcsbase/baseannotationhighlighter.cpp index 65a4a2ae68..b0b68ef1ee 100644 --- a/src/plugins/vcsbase/baseannotationhighlighter.cpp +++ b/src/plugins/vcsbase/baseannotationhighlighter.cpp @@ -29,7 +29,6 @@ #include "baseannotationhighlighter.h" -#include <math.h> #include <QSet> #include <QDebug> #include <QColor> @@ -81,26 +80,12 @@ BaseAnnotationHighlighter::~BaseAnnotationHighlighter() void BaseAnnotationHighlighter::setChangeNumbers(const ChangeNumbers &changeNumbers) { - QColor bg = d->m_background; d->m_changeNumberMap.clear(); if (!changeNumbers.isEmpty()) { // Assign a color gradient to annotation change numbers. Give // each change number a unique color. - const double oneThird = 1.0 / 3.0; - const int step = qRound(ceil(pow(double(changeNumbers.count()), oneThird))); - QList<QColor> colors; - const int factor = 255 / step; - int half = factor / 2; - for (int i=0; i<=step; ++i) - for (int j=0; j<=step; ++j) - for (int k=0; k<=step; ++k) { - QColor c(i*factor, j*factor, k*factor); - if ((bg.red() - half > c.red() ||bg.red() + half <= c.red()) - && (bg.green() - half > c.green() || bg.green() + half <= c.green()) - && (bg.blue() - half > c.blue() || bg.blue() + half <= c.blue())) - colors.prepend(c); - } - + const QList<QColor> colors = + TextEditor::SyntaxHighlighter::generateColors(changeNumbers.size(), d->m_background); int m = 0; const int cstep = colors.count() / changeNumbers.count(); const ChangeNumbers::const_iterator cend = changeNumbers.constEnd(); diff --git a/src/plugins/vcsbase/basevcseditorfactory.cpp b/src/plugins/vcsbase/basevcseditorfactory.cpp index 2b7d2f6ff5..4c3401cdee 100644 --- a/src/plugins/vcsbase/basevcseditorfactory.cpp +++ b/src/plugins/vcsbase/basevcseditorfactory.cpp @@ -62,7 +62,7 @@ public: BaseVcsEditorFactoryPrivate::BaseVcsEditorFactoryPrivate(const VcsBaseEditorParameters *t) : m_type(t), - m_id(t->id), + m_id(QByteArray(t->id)), m_mimeTypes(QStringList(QLatin1String(t->mimeType))), m_editorHandler(new TextEditor::TextEditorActionHandler(t->context)) { diff --git a/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp b/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp index e1654f7759..35b7187180 100644 --- a/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp +++ b/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp @@ -49,7 +49,7 @@ public: BaseVcsSubmitEditorFactoryPrivate::BaseVcsSubmitEditorFactoryPrivate(const VcsBaseSubmitEditorParameters *parameters) : m_parameters(parameters), - m_id(parameters->id), + m_id(QByteArray(parameters->id)), m_displayName(QLatin1String(parameters->displayName)), m_mimeTypes(QLatin1String(parameters->mimeType)) { diff --git a/src/plugins/vcsbase/checkoutjobs.cpp b/src/plugins/vcsbase/checkoutjobs.cpp index 5f27520593..778487e924 100644 --- a/src/plugins/vcsbase/checkoutjobs.cpp +++ b/src/plugins/vcsbase/checkoutjobs.cpp @@ -29,8 +29,8 @@ #include "checkoutjobs.h" -#include <vcsbaseplugin.h> -#include <vcsbaseoutputwindow.h> +#include "vcsbaseplugin.h" +#include "vcsbaseoutputwindow.h" #include <QDebug> #include <QQueue> diff --git a/src/plugins/vcsbase/commonvcssettings.cpp b/src/plugins/vcsbase/commonvcssettings.cpp index 1022dc4cd3..1eda0667ba 100644 --- a/src/plugins/vcsbase/commonvcssettings.cpp +++ b/src/plugins/vcsbase/commonvcssettings.cpp @@ -29,6 +29,8 @@ #include "commonvcssettings.h" +#include <utils/hostosinfo.h> + #include <QSettings> #include <QDebug> @@ -51,11 +53,9 @@ static inline QString sshPasswordPromptDefault() const QByteArray envSetting = qgetenv("SSH_ASKPASS"); if (!envSetting.isEmpty()) return QString::fromLocal8Bit(envSetting); -#ifdef Q_OS_WIN - return QLatin1String("win-ssh-askpass"); -#else + if (Utils::HostOsInfo::isWindowsHost()) + return QLatin1String("win-ssh-askpass"); return QLatin1String("ssh-askpass"); -#endif } namespace VcsBase { diff --git a/src/plugins/vcsbase/vcsbase.qbs b/src/plugins/vcsbase/vcsbase.qbs index 91245e75d8..aefb0c04f9 100644 --- a/src/plugins/vcsbase/vcsbase.qbs +++ b/src/plugins/vcsbase/vcsbase.qbs @@ -14,18 +14,8 @@ QtcPlugin { Depends { name: "CppTools" } Depends { name: "CPlusPlus" } - cpp.includePaths: [ - ".", - "..", - "../../libs", - "../../libs/3rdparty", - buildDirectory - ] - files: [ "VcsBase.mimetypes.xml", - "vcsbase.qrc", - "vcsbase_global.h", "baseannotationhighlighter.cpp", "baseannotationhighlighter.h", "basecheckoutwizard.cpp", @@ -65,6 +55,8 @@ QtcPlugin { "submiteditorfile.h", "submitfilemodel.cpp", "submitfilemodel.h", + "vcsbase.qrc", + "vcsbase_global.h", "vcsbaseclient.cpp", "vcsbaseclient.h", "vcsbaseclientsettings.cpp", @@ -87,7 +79,6 @@ QtcPlugin { "vcsplugin.cpp", "vcsplugin.h", "images/diff.png", - "images/submit.png" + "images/submit.png", ] } - diff --git a/src/plugins/vcsbase/vcsbaseclientsettings.cpp b/src/plugins/vcsbase/vcsbaseclientsettings.cpp index 445df7e663..01e03b9125 100644 --- a/src/plugins/vcsbase/vcsbaseclientsettings.cpp +++ b/src/plugins/vcsbase/vcsbaseclientsettings.cpp @@ -30,6 +30,7 @@ #include "vcsbaseclientsettings.h" #include <utils/environment.h> +#include <utils/hostosinfo.h> #include <utils/synchronousprocess.h> #include <QSettings> @@ -350,7 +351,7 @@ QString VcsBaseClientSettings::binaryPath() const if (d->m_binaryFullPath.isEmpty()) { d->m_binaryFullPath = Utils::Environment::systemEnvironment().searchInPath( stringValue(binaryPathKey), stringValue(pathKey).split( - Utils::SynchronousProcess::pathSeparator())); + Utils::HostOsInfo::pathListSeparator())); } return d->m_binaryFullPath; } diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index 4d6594e800..1574460d47 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -178,7 +178,7 @@ private: VcsBaseEditor::VcsBaseEditor(VcsBaseEditorWidget *widget, const VcsBaseEditorParameters *type) : BaseTextEditor(widget), - m_id(type->id), + m_id(QByteArray(type->id)), m_temporary(false) { setContext(Core::Context(type->context, TextEditor::Constants::C_TEXTEDITOR)); diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp index 15444e2b9c..c41f984cbb 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp @@ -426,7 +426,7 @@ Core::IEditor *VcsBaseSubmitEditor::duplicate(QWidget * /*parent*/) Core::Id VcsBaseSubmitEditor::id() const { - return d->m_parameters->id; + return Core::Id(QByteArray(d->m_parameters->id)); } static QToolBar *createToolBar(const QWidget *someWidget, QAction *submitAction, QAction *diffAction) diff --git a/src/plugins/welcome/welcome.qbs b/src/plugins/welcome/welcome.qbs index d999ee58c5..a99fe82ab9 100644 --- a/src/plugins/welcome/welcome.qbs +++ b/src/plugins/welcome/welcome.qbs @@ -10,19 +10,11 @@ QtcPlugin { Depends { name: "ProjectExplorer" } Depends { name: "cpp" } - cpp.defines: project.additionalCppDefines - cpp.includePaths: [ - "..", - "../../libs", - "../../../src/shared/scriptwrapper", - "../../Core/dynamiclibrary", - buildDirectory - ] + cpp.includePaths: base.concat("../../shared/scriptwrapper") files: [ "welcome_global.h", "welcomeplugin.cpp", - "welcomeplugin.h" + "welcomeplugin.h", ] } - diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index 75d80cf909..fc231d39f1 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -40,6 +40,7 @@ #include <projectexplorer/projectexplorer.h> +#include <utils/hostosinfo.h> #include <utils/styledbar.h> #include <utils/iwelcomepage.h> #include <utils/networkaccessmanager.h> @@ -64,6 +65,7 @@ enum { debug = 0 }; using namespace ExtensionSystem; +using namespace Utils; static const char currentPageSettingsKeyC[] = "WelcomeTab"; @@ -238,11 +240,10 @@ void WelcomeMode::initPlugins() engine->setOutputWarningsToStandardError(false); engine->setNetworkAccessManagerFactory(m_networkAccessManagerFactory); QString pluginPath = QCoreApplication::applicationDirPath(); -#ifdef Q_OS_MAC - pluginPath += QLatin1String("/../PlugIns"); -#else - pluginPath += QLatin1String("/../" IDE_LIBRARY_BASENAME "/qtcreator"); -#endif + if (HostOsInfo::isMacHost()) + pluginPath += QLatin1String("/../PlugIns"); + else + pluginPath += QLatin1String("/../" IDE_LIBRARY_BASENAME "/qtcreator"); engine->addImportPath(QDir::cleanPath(pluginPath)); facilitateQml(engine); foreach (Utils::IWelcomePage *plugin, plugins) { @@ -259,17 +260,13 @@ void WelcomeMode::initPlugins() QString WelcomeMode::platform() const { -#if defined(Q_OS_WIN) - return QLatin1String("windows"); -#elif defined(Q_OS_MAC) - return QLatin1String("mac"); -#elif defined(Q_OS_LINUX) - return QLatin1String("linux"); -#elif defined(Q_OS_UNIX) - return QLatin1String("unix"); -#else - return QLatin1String("other") -#endif + switch (HostOsInfo::hostOs()) { + case HostOsInfo::HostOsWindows: return QLatin1String("windows"); + case HostOsInfo::HostOsMac: return QLatin1String("mac"); + case HostOsInfo::HostOsLinux: return QLatin1String("linux"); + case HostOsInfo::HostOsOtherUnix: return QLatin1String("unix"); + default: return QLatin1String("other"); + } } void WelcomeMode::welcomePluginAdded(QObject *obj) diff --git a/src/share/share.qbs b/src/share/share.qbs deleted file mode 100644 index 3f2d437be1..0000000000 --- a/src/share/share.qbs +++ /dev/null @@ -1,40 +0,0 @@ -import qbs.base 1.0 - -Product { - type: ["installed_content"] - name: "SharedConditionally" - - Group { - qbs.installDir: "share/qtcreator/externaltools" - fileTags: ["install"] - prefix: "qtcreator/externaltools/" - files: [ - "lrelease.xml", - "lupdate.xml", - "qmlviewer.xml", - "sort.xml", - ] - } - - Group { - condition: qbs.targetOS == "linux" - qbs.installDir: "share/qtcreator/externaltools" - fileTags: ["install"] - files: ["qtcreator/externaltools/vi.xml"] - } - - Group { - condition: qbs.targetOS == "mac" - qbs.installDir: "share/qtcreator/externaltools" - fileTags: ["install"] - files: ["qtcreator/externaltools/vi_mac.xml"] - } - - Group { - condition: qbs.targetOS == "windows" - qbs.installDir: "share/qtcreator/externaltools" - fileTags: ["install"] - files: ["qtcreator/externaltools/notepad_win.xml"] - } -} - diff --git a/src/shared/help/indexwindow.cpp b/src/shared/help/indexwindow.cpp index 179315104c..c5eab1914e 100644 --- a/src/shared/help/indexwindow.cpp +++ b/src/shared/help/indexwindow.cpp @@ -36,6 +36,7 @@ #include "topicchooser.h" #include <utils/filterlineedit.h> +#include <utils/hostosinfo.h> #include <utils/styledbar.h> #include <QLayout> @@ -164,13 +165,12 @@ bool IndexWindow::eventFilter(QObject *obj, QEvent *e) } } } -#ifdef Q_OS_MAC - else if (obj == m_indexWidget && e->type() == QEvent::KeyPress) { + else if (Utils::HostOsInfo::isMacHost() && obj == m_indexWidget + && e->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast<QKeyEvent*>(e); if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter) m_indexWidget->activateCurrentItem(); } -#endif return QWidget::eventFilter(obj, e); } diff --git a/src/shared/proparser/ioutils.cpp b/src/shared/proparser/ioutils.cpp index 738571e3c5..1887e789e0 100644 --- a/src/shared/proparser/ioutils.cpp +++ b/src/shared/proparser/ioutils.cpp @@ -29,8 +29,8 @@ #include "ioutils.h" -#include <QDir> -#include <QFile> +#include <qdir.h> +#include <qfile.h> #ifdef Q_OS_WIN # include <windows.h> @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE -using namespace ProFileEvaluatorInternal; +using namespace QMakeInternal; IoUtils::FileType IoUtils::fileType(const QString &fileName) { diff --git a/src/shared/proparser/ioutils.h b/src/shared/proparser/ioutils.h index e1dd2943df..c2bd0fbda0 100644 --- a/src/shared/proparser/ioutils.h +++ b/src/shared/proparser/ioutils.h @@ -30,11 +30,11 @@ #ifndef IOUTILS_H #define IOUTILS_H -#include <QString> +#include <qstring.h> QT_BEGIN_NAMESPACE -namespace ProFileEvaluatorInternal { +namespace QMakeInternal { /*! This class provides replacement functionality for QFileInfo, QFile & QDir, diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index ce8d43f81e..6f2fcca56c 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -34,7 +34,7 @@ #include <QDir> -using namespace ProFileEvaluatorInternal; +using namespace QMakeInternal; QT_BEGIN_NAMESPACE @@ -43,7 +43,7 @@ void ProFileEvaluator::initialize() QMakeEvaluator::initStatics(); } -ProFileEvaluator::ProFileEvaluator(QMakeGlobals *option, QMakeParser *parser, +ProFileEvaluator::ProFileEvaluator(ProFileGlobals *option, QMakeParser *parser, QMakeHandler *handler) : d(new QMakeEvaluator(option, parser, handler)) { @@ -81,7 +81,7 @@ QStringList ProFileEvaluator::values(const QString &variableName) const QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const { // It makes no sense to put any kind of magic into expanding these - const ProStringList &values = d->m_valuemapStack.at(0).value(ProKey(variableName)); + const ProStringList &values = d->m_valuemapStack.first().value(ProKey(variableName)); QStringList ret; ret.reserve(values.size()); foreach (const ProString &str, values) @@ -92,16 +92,17 @@ QStringList ProFileEvaluator::values(const QString &variableName, const ProFile QString ProFileEvaluator::sysrootify(const QString &path, const QString &baseDir) const { + ProFileGlobals *option = static_cast<ProFileGlobals *>(d->m_option); #ifdef Q_OS_WIN Qt::CaseSensitivity cs = Qt::CaseInsensitive; #else Qt::CaseSensitivity cs = Qt::CaseSensitive; #endif const bool isHostSystemPath = - d->m_option->sysroot.isEmpty() || path.startsWith(d->m_option->sysroot, cs) + option->sysroot.isEmpty() || path.startsWith(option->sysroot, cs) || path.startsWith(baseDir, cs) || path.startsWith(d->m_outputDir, cs); - return isHostSystemPath ? path : d->m_option->sysroot + path; + return isHostSystemPath ? path : option->sysroot + path; } QStringList ProFileEvaluator::absolutePathValues( @@ -214,6 +215,21 @@ void ProFileEvaluator::setCumulative(bool on) } #endif +void ProFileEvaluator::setExtraVars(const QHash<QString, QStringList> &extraVars) +{ + ProValueMap map; + QHash<QString, QStringList>::const_iterator it = extraVars.constBegin(); + QHash<QString, QStringList>::const_iterator end = extraVars.constEnd(); + for ( ; it != end; ++it) + map.insert(ProKey(it.key()), ProStringList(it.value())); + d->setExtraVars(map); +} + +void ProFileEvaluator::setExtraConfigs(const QStringList &extraConfigs) +{ + d->setExtraConfigs(ProStringList(extraConfigs)); +} + void ProFileEvaluator::setOutputDir(const QString &dir) { d->m_outputDir = dir; diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index 25acf6cfa8..c1a963a2ef 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -31,6 +31,7 @@ #define PROFILEEVALUATOR_H #include "qmake_global.h" +#include "qmakeglobals.h" #include "qmakeevaluator.h" #include "proitems.h" @@ -39,11 +40,16 @@ QT_BEGIN_NAMESPACE -class QMakeGlobals; class QMakeParser; class QMakeEvaluator; class QMakeHandler; +class QMAKE_EXPORT ProFileGlobals : public QMakeGlobals +{ +public: + QString sysroot; +}; + class QMAKE_EXPORT ProFileEvaluator { public: @@ -59,13 +65,15 @@ public: // Call this from a concurrency-free context static void initialize(); - ProFileEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeHandler *handler); + ProFileEvaluator(ProFileGlobals *option, QMakeParser *parser, QMakeHandler *handler); ~ProFileEvaluator(); ProFileEvaluator::TemplateType templateType() const; #ifdef PROEVALUATOR_CUMULATIVE void setCumulative(bool on); // Default is false #endif + void setExtraVars(const QHash<QString, QStringList> &extraVars); + void setExtraConfigs(const QStringList &extraConfigs); void setOutputDir(const QString &dir); // Default is empty bool loadNamedSpec(const QString &specDir, bool hostSpec); diff --git a/src/shared/proparser/proitems.cpp b/src/shared/proparser/proitems.cpp index 8da5866480..cf5c948d8f 100644 --- a/src/shared/proparser/proitems.cpp +++ b/src/shared/proparser/proitems.cpp @@ -29,10 +29,10 @@ #include "proitems.h" -#include <QFileInfo> -#include <QSet> -#include <QStringList> -#include <QTextStream> +#include <qfileinfo.h> +#include <qset.h> +#include <qstringlist.h> +#include <qtextstream.h> QT_BEGIN_NAMESPACE @@ -155,14 +155,14 @@ QString &ProString::toQString(QString &tmp) const return tmp.setRawData(m_string.constData() + m_offset, m_length); } -QChar *ProString::prepareAppend(int extraLen) +QChar *ProString::prepareExtend(int extraLen, int thisTarget, int extraTarget) { if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) { m_string.reserve(0); // Prevent the resize() below from reallocating QChar *ptr = (QChar *)m_string.constData(); - if (m_offset) - memmove(ptr, ptr + m_offset, m_length * 2); - ptr += m_length; + if (m_offset != thisTarget) + memmove(ptr + thisTarget, ptr + m_offset, m_length * 2); + ptr += extraTarget; m_offset = 0; m_length += extraLen; m_string.resize(m_length); @@ -171,13 +171,51 @@ QChar *ProString::prepareAppend(int extraLen) } else { QString neu(m_length + extraLen, Qt::Uninitialized); QChar *ptr = (QChar *)neu.constData(); - memcpy(ptr, m_string.constData() + m_offset, m_length * 2); - ptr += m_length; + memcpy(ptr + thisTarget, m_string.constData() + m_offset, m_length * 2); + ptr += extraTarget; *this = ProString(neu); return ptr; } } +ProString &ProString::prepend(const ProString &other) +{ + if (other.m_length) { + if (!m_length) { + *this = other; + } else { + QChar *ptr = prepareExtend(other.m_length, other.m_length, 0); + memcpy(ptr, other.constData(), other.m_length * 2); + if (!m_file) + m_file = other.m_file; + } + } + return *this; +} + +ProString &ProString::append(const QLatin1String other) +{ + const char *latin1 = other.latin1(); +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + int size = other.size(); +#else + int size = strlen(latin1); +#endif + if (size) { + QChar *ptr = prepareExtend(size, 0, m_length); + for (int i = 0; i < size; i++) + *ptr++ = QLatin1Char(latin1[i]); + } + return *this; +} + +ProString &ProString::append(QChar other) +{ + QChar *ptr = prepareExtend(1, 0, m_length); + *ptr = other; + return *this; +} + // If pending != 0, prefix with space if appending to non-empty non-pending ProString &ProString::append(const ProString &other, bool *pending) { @@ -187,10 +225,10 @@ ProString &ProString::append(const ProString &other, bool *pending) } else { QChar *ptr; if (pending && !*pending) { - ptr = prepareAppend(1 + other.m_length); + ptr = prepareExtend(1 + other.m_length, 0, m_length); *ptr++ = 32; } else { - ptr = prepareAppend(other.m_length); + ptr = prepareExtend(other.m_length, 0, m_length); } memcpy(ptr, other.m_string.constData() + other.m_offset, other.m_length * 2); if (other.m_file) @@ -223,7 +261,7 @@ ProString &ProString::append(const ProStringList &other, bool *pending, bool ski else totalLength--; - QChar *ptr = prepareAppend(totalLength); + QChar *ptr = prepareExtend(totalLength, 0, m_length); for (int i = startIdx; i < sz; ++i) { if (putSpace) *ptr++ = 32; diff --git a/src/shared/proparser/proitems.h b/src/shared/proparser/proitems.h index c4146448e4..9e2ac44d89 100644 --- a/src/shared/proparser/proitems.h +++ b/src/shared/proparser/proitems.h @@ -32,9 +32,9 @@ #include "qmake_global.h" -#include <QString> -#include <QVector> -#include <QHash> +#include <qstring.h> +#include <qvector.h> +#include <qhash.h> QT_BEGIN_NAMESPACE @@ -77,9 +77,18 @@ public: ProString &setSource(const ProFile *pro) { m_file = pro; return *this; } const ProFile *sourceFile() const { return m_file; } - ProString &operator+=(const ProString &other); + ProString &prepend(const ProString &other); ProString &append(const ProString &other, bool *pending = 0); + ProString &append(const QString &other) { return append(ProString(other)); } + ProString &append(const QLatin1String other); + ProString &append(const char *other) { return append(QLatin1String(other)); } + ProString &append(QChar other); ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false); + ProString &operator+=(const ProString &other) { return append(other); } + ProString &operator+=(const QString &other) { return append(other); } + ProString &operator+=(const QLatin1String other) { return append(other); } + ProString &operator+=(const char *other) { return append(other); } + ProString &operator+=(QChar other) { return append(other); } void chop(int n) { Q_ASSERT(n <= m_length); m_length -= n; } void chopFront(int n) { Q_ASSERT(n <= m_length); m_offset += n; m_length -= n; } @@ -154,7 +163,7 @@ private: int m_offset, m_length; const ProFile *m_file; mutable uint m_hash; - QChar *prepareAppend(int extraLen); + QChar *prepareExtend(int extraLen, int thisTarget, int extraTarget); uint updatedHash() const; friend uint qHash(const ProString &str); friend QString operator+(const ProString &one, const ProString &two); @@ -235,6 +244,7 @@ public: { return contains(ProString(str), cs); } bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; }; +Q_DECLARE_TYPEINFO(ProStringList, Q_MOVABLE_TYPE); inline ProStringList operator+(const ProStringList &one, const ProStringList &two) { ProStringList ret = one; ret += two; return ret; } diff --git a/src/shared/proparser/qmake_global.h b/src/shared/proparser/qmake_global.h index 427dcb27c9..0398b87892 100644 --- a/src/shared/proparser/qmake_global.h +++ b/src/shared/proparser/qmake_global.h @@ -52,4 +52,8 @@ # define ALWAYS_INLINE inline #endif +#ifdef PROEVALUATOR_FULL +# define PROEVALUATOR_DEBUG +#endif + #endif diff --git a/src/shared/proparser/qmakebuiltins.cpp b/src/shared/proparser/qmakebuiltins.cpp index 9a2305c986..1fe55265ca 100644 --- a/src/shared/proparser/qmakebuiltins.cpp +++ b/src/shared/proparser/qmakebuiltins.cpp @@ -34,15 +34,15 @@ #include "qmakeparser.h" #include "ioutils.h" -#include <QByteArray> -#include <QDir> -#include <QFile> -#include <QFileInfo> -#include <QList> -#include <QRegExp> -#include <QSet> -#include <QStringList> -#include <QTextStream> +#include <qbytearray.h> +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qlist.h> +#include <qregexp.h> +#include <qset.h> +#include <qstringlist.h> +#include <qtextstream.h> #ifdef Q_OS_UNIX #include <time.h> @@ -65,7 +65,7 @@ #define QT_PCLOSE pclose #endif -using namespace ProFileEvaluatorInternal; +using namespace QMakeInternal; QT_BEGIN_NAMESPACE @@ -315,8 +315,10 @@ QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::Open void QMakeEvaluator::runProcess(QProcess *proc, const QString &command) const { proc->setWorkingDirectory(currentDirectory()); +# ifdef PROEVALUATOR_SETENV if (!m_option->environment.isEmpty()) proc->setProcessEnvironment(m_option->environment); +# endif # ifdef Q_OS_WIN proc->setNativeArguments(QLatin1String("/v:off /s /c \"") + command + QLatin1Char('"')); proc->start(m_option->getEnv(QLatin1String("COMSPEC")), QStringList()); @@ -347,7 +349,7 @@ QByteArray QMakeEvaluator::getCommandOutput(const QString &args) const #else QByteArray out; if (FILE *proc = QT_POPEN(QString(QLatin1String("cd ") - + IoUtils::shellQuote(currentDirectory()) + + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory())) + QLatin1String(" && ") + args).toLocal8Bit().constData(), "r")) { while (!feof(proc)) { char buff[10 * 1024]; @@ -383,13 +385,12 @@ void QMakeEvaluator::populateDeps( } } -ProStringList QMakeEvaluator::evaluateExpandFunction( - const ProKey &func, const ushort *&tokPtr) +ProStringList QMakeEvaluator::evaluateBuiltinExpand( + const ProKey &func, const ProStringList &args) { - QHash<ProKey, ProFunctionDef>::ConstIterator it = - m_functionDefs.replaceFunctions.constFind(func); - if (it != m_functionDefs.replaceFunctions.constEnd()) - return evaluateFunction(*it, prepareFunctionArgs(tokPtr), 0); + ProStringList ret; + + traceMsg("calling built-in $$%s(%s)", dbgKey(func), dbgSepStrList(args)); ExpandFunc func_t = ExpandFunc(statics.expands.value(func)); if (func_t == 0) { @@ -401,11 +402,6 @@ ProStringList QMakeEvaluator::evaluateExpandFunction( deprecationWarning(fL1S("Using uppercased builtin functions is deprecated.")); } } - - //why don't the builtin functions just use args_list? --Sam - const ProStringList &args = expandVariableReferences(tokPtr, 5, true); - ProStringList ret; - switch (func_t) { case E_BASENAME: case E_DIRNAME: @@ -684,7 +680,7 @@ ProStringList QMakeEvaluator::evaluateExpandFunction( ProValueMap vars; QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1))); fn.detach(); - if (evaluateFileInto(fn, QMakeHandler::EvalAuxFile, &vars, LoadProOnly)) + if (evaluateFileInto(fn, &vars, LoadProOnly)) ret = vars.value(map(args.at(1))); } break; @@ -945,17 +941,9 @@ ProStringList QMakeEvaluator::evaluateExpandFunction( if (args.count() != 1) { evalError(fL1S("shadowed(path) requires one argument.")); } else { - QString val = resolvePath(args.at(0).toQString(m_tmp1)); - QString rstr; - if (m_option->source_root.isEmpty()) { - rstr = val; - } else if (val.startsWith(m_option->source_root) - && (val.length() == m_option->source_root.length() - || val.at(m_option->source_root.length()) == QLatin1Char('/'))) { - rstr = m_option->build_root + val.mid(m_option->source_root.length()); - } else { + QString rstr = m_option->shadowedPath(resolvePath(args.at(0).toQString(m_tmp1))); + if (rstr.isEmpty()) break; - } ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0))); } break; @@ -1044,19 +1032,12 @@ ProStringList QMakeEvaluator::evaluateExpandFunction( return ret; } -QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( - const ProKey &function, const ushort *&tokPtr) +QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( + const ProKey &function, const ProStringList &args) { - QHash<ProKey, ProFunctionDef>::ConstIterator it = - m_functionDefs.testFunctions.constFind(function); - if (it != m_functionDefs.testFunctions.constEnd()) - return evaluateBoolFunction(*it, prepareFunctionArgs(tokPtr), function); + traceMsg("calling built-in %s(%s)", dbgKey(function), dbgSepStrList(args)); TestFunc func_t = (TestFunc)statics.functions.value(function); - - //why don't the builtin functions just use args_list? --Sam - const ProStringList &args = expandVariableReferences(tokPtr, 5, true); - switch (func_t) { case T_DEFINED: { if (args.count() < 1 || args.count() > 2) { @@ -1087,18 +1068,19 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( return ReturnFalse; } const ProKey &var = map(args.at(0)); - for (int i = m_valuemapStack.size(); --i > 0; ) { - ProValueMap::Iterator it = m_valuemapStack[i].find(var); - if (it != m_valuemapStack.at(i).end()) { + for (ProValueMapStack::Iterator vmi = m_valuemapStack.end(); + --vmi != m_valuemapStack.begin(); ) { + ProValueMap::Iterator it = (*vmi).find(var); + if (it != (*vmi).end()) { if (it->constBegin() == statics.fakeValue.constBegin()) { // This is stupid, but qmake doesn't propagate deletions - m_valuemapStack[0][var] = ProStringList(); + m_valuemapStack.first()[var] = ProStringList(); } else { - m_valuemapStack[0][var] = *it; + m_valuemapStack.first()[var] = *it; } - m_valuemapStack[i].erase(it); - while (--i) - m_valuemapStack[i].remove(var); + (*vmi).erase(it); + while (--vmi != m_valuemapStack.begin()) + (*vmi).remove(var); break; } } @@ -1111,7 +1093,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( ProValueMap vars; QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1))); fn.detach(); - if (!evaluateFileInto(fn, QMakeHandler::EvalAuxFile, &vars, LoadProOnly)) + if (!evaluateFileInto(fn, &vars, LoadProOnly)) return ReturnFalse; if (args.count() == 2) return returnBool(vars.contains(map(args.at(1)))); @@ -1137,8 +1119,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( #endif case T_EVAL: { VisitReturn ret = ReturnFalse; - ProFile *pro = m_parser->parsedProBlock(fL1S("(eval)"), - args.join(statics.field_sep)); + ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep), + m_current.pro->fileName(), m_current.line); if (pro) { if (m_cumulative || pro->isOk()) { m_locationStack.push(m_current); @@ -1155,7 +1137,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( evalError(fL1S("if(condition) requires one argument.")); return ReturnFalse; } - return returnBool(evaluateConditional(args.at(0).toQString(), fL1S("(if)"))); + return returnBool(evaluateConditional(args.at(0).toQString(), + m_current.pro->fileName(), m_current.line)); } case T_CONFIG: { if (args.count() < 1 || args.count() > 2) { @@ -1323,10 +1306,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( fn.detach(); bool ok; if (parseInto.isEmpty()) { - ok = evaluateFile(fn, QMakeHandler::EvalIncludeFile, LoadProOnly | flags); + ok = evaluateFileChecked(fn, QMakeHandler::EvalIncludeFile, LoadProOnly | flags); } else { ProValueMap symbols; - if ((ok = evaluateFileInto(fn, QMakeHandler::EvalAuxFile, &symbols, LoadAll | flags))) { + if ((ok = evaluateFileInto(fn, &symbols, LoadAll | flags))) { ProValueMap newMap; for (ProValueMap::ConstIterator it = m_valuemapStack.top().constBegin(), @@ -1360,9 +1343,20 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( return returnBool(evaluateFeatureFile(m_option->expandEnvVars(args.at(0).toQString()), ignore_error) || ignore_error); } - case T_DEBUG: - // Yup - do nothing. Nothing is going to enable debug output anyway. - return ReturnFalse; + case T_DEBUG: { +#ifdef PROEVALUATOR_DEBUG + if (args.count() != 2) { + evalError(fL1S("debug(level, message) requires two arguments.")); + return ReturnFalse; + } + int level = args.at(0).toInt(); + if (level <= m_debugLevel) { + const QString &msg = m_option->expandEnvVars(args.at(1).toQString(m_tmp2)); + debugMsg(level, "Project DEBUG: %s", qPrintable(msg)); + } +#endif + return ReturnTrue; + } case T_LOG: case T_ERROR: case T_WARNING: @@ -1400,7 +1394,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( return returnBool(proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0); #else return returnBool(system((QLatin1String("cd ") - + IoUtils::shellQuote(currentDirectory()) + + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory())) + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()) == 0); #endif } diff --git a/src/shared/proparser/qmakeevaluator.cpp b/src/shared/proparser/qmakeevaluator.cpp index dd82e3d72b..2a44bdd441 100644 --- a/src/shared/proparser/qmakeevaluator.cpp +++ b/src/shared/proparser/qmakeevaluator.cpp @@ -34,20 +34,20 @@ #include "qmakeevaluator_p.h" #include "ioutils.h" -#include <QByteArray> -#include <QDateTime> -#include <QDebug> -#include <QDir> -#include <QFile> -#include <QFileInfo> -#include <QList> -#include <QRegExp> -#include <QSet> -#include <QStack> -#include <QString> -#include <QStringList> +#include <qbytearray.h> +#include <qdatetime.h> +#include <qdebug.h> +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qlist.h> +#include <qregexp.h> +#include <qset.h> +#include <qstack.h> +#include <qstring.h> +#include <qstringlist.h> #ifdef PROEVALUATOR_THREAD_SAFE -# include <QThreadPool> +# include <qthreadpool.h> #endif #ifdef Q_OS_UNIX @@ -59,7 +59,7 @@ #include <stdio.h> #include <stdlib.h> -using namespace ProFileEvaluatorInternal; +using namespace QMakeInternal; QT_BEGIN_NAMESPACE @@ -94,7 +94,7 @@ QMakeBaseEnv::~QMakeBaseEnv() delete evaluator; } -namespace ProFileEvaluatorInternal { +namespace QMakeInternal { QMakeStatics statics; } @@ -163,7 +163,11 @@ const ProKey &QMakeEvaluator::map(const ProKey &var) QMakeEvaluator::QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeHandler *handler) - : m_option(option), m_parser(parser), m_handler(handler) + : +#ifdef PROEVALUATOR_DEBUG + m_debugLevel(option->debugLevel), +#endif + m_option(option), m_parser(parser), m_handler(handler) { // So that single-threaded apps don't have to call initialize() for now. initStatics(); @@ -398,40 +402,56 @@ static ALWAYS_INLINE void addStrList( void QMakeEvaluator::evaluateExpression( const ushort *&tokPtr, ProStringList *ret, bool joined) { + debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression"); if (joined) *ret << ProString(); bool pending = false; forever { ushort tok = *tokPtr++; - if (tok & TokNewStr) + if (tok & TokNewStr) { + debugMsg(2, "new string"); pending = false; + } ushort maskedTok = tok & TokMask; switch (maskedTok) { case TokLine: m_current.line = *tokPtr++; break; - case TokLiteral: - addStr(getStr(tokPtr), ret, pending, joined); - break; - case TokHashLiteral: - addStr(getHashStr(tokPtr), ret, pending, joined); - break; - case TokVariable: - addStrList(values(map(getHashStr(tokPtr))), tok, ret, pending, joined); - break; - case TokProperty: - addStr(propertyValue(getHashStr(tokPtr)).setSource(currentProFile()), - ret, pending, joined); - break; - case TokEnvVar: - addStrList(split_value_list(m_option->getEnv(getStr(tokPtr).toQString(m_tmp1))), - tok, ret, pending, joined); - break; + case TokLiteral: { + const ProString &val = getStr(tokPtr); + debugMsg(2, "literal %s", dbgStr(val)); + addStr(val, ret, pending, joined); + break; } + case TokHashLiteral: { + const ProKey &val = getHashStr(tokPtr); + debugMsg(2, "hashed literal %s", dbgStr(val.toString())); + addStr(val, ret, pending, joined); + break; } + case TokVariable: { + const ProKey &var = getHashStr(tokPtr); + const ProStringList &val = values(map(var)); + debugMsg(2, "variable %s => %s", dbgKey(var), dbgStrList(val)); + addStrList(val, tok, ret, pending, joined); + break; } + case TokProperty: { + const ProKey &var = getHashStr(tokPtr); + const ProString &val = propertyValue(var); + debugMsg(2, "property %s => %s", dbgKey(var), dbgStr(val)); + addStr(val, ret, pending, joined); + break; } + case TokEnvVar: { + const ProString &var = getStr(tokPtr); + const ProStringList &val = split_value_list(m_option->getEnv(var.toQString(m_tmp1))); + debugMsg(2, "env var %s => %s", dbgStr(var), dbgStrList(val)); + addStrList(val, tok, ret, pending, joined); + break; } case TokFuncName: { const ProKey &func = getHashStr(tokPtr); + debugMsg(2, "function %s", dbgKey(func)); addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined); break; } default: + debugMsg(2, "evaluated expression => %s", dbgStrList(*ret)); tokPtr--; return; } @@ -489,6 +509,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( const ushort *tokPtr) { + traceMsg("entering block"); ProStringList curr; bool okey = true, or_op = false, invert = false; uint blockLen; @@ -525,12 +546,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( m_skipLevel--; #endif } else { - if (okey) + if (okey) { + traceMsg("taking 'then' branch"); ret = blockLen ? visitProBlock(tokPtr) : ReturnTrue; + traceMsg("finished 'then' branch"); + } tokPtr += blockLen; blockLen = getBlockLen(tokPtr); - if (!okey) + if (!okey) { + traceMsg("taking 'else' branch"); ret = blockLen ? visitProBlock(tokPtr) : ReturnTrue; + traceMsg("finished 'else' branch"); + } } tokPtr += blockLen; okey = true, or_op = false; // force next evaluation @@ -554,6 +581,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( uint exprLen = getBlockLen(tokPtr); tokPtr += exprLen; blockLen = getBlockLen(tokPtr); + traceMsg("skipped loop"); ret = ReturnTrue; } tokPtr += blockLen; @@ -565,7 +593,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( const ProKey &name = getHashStr(tokPtr); blockLen = getBlockLen(tokPtr); visitProFunctionDef(tok, name, tokPtr); + traceMsg("defined %s function %s", + tok == TokTestDef ? "test" : "replace", dbgKey(name)); } else { + traceMsg("skipped function definition"); skipHashStr(tokPtr); blockLen = getBlockLen(tokPtr); } @@ -573,12 +604,15 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( okey = true, or_op = false; // force next evaluation continue; case TokNot: + traceMsg("NOT"); invert ^= true; continue; case TokAnd: + traceMsg("AND"); or_op = false; continue; case TokOr: + traceMsg("OR"); or_op = true; continue; case TokCondition: @@ -588,8 +622,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( evalError(fL1S("Conditional must expand to exactly one word.")); okey = false; } else { - okey = isActiveConfig(curr.at(0).toQString(m_tmp2), true) ^ invert; + okey = isActiveConfig(curr.at(0).toQString(m_tmp2), true); + traceMsg("condition %s is %s", dbgStr(curr.at(0)), dbgBool(okey)); + okey ^= invert; } + } else { + traceMsg("skipped condition %s", curr.size() == 1 ? dbgStr(curr.at(0)) : "<invalid>"); } or_op = !okey; // tentatively force next evaluation invert = false; @@ -603,12 +641,16 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( skipExpression(tokPtr); okey = false; } else { + traceMsg("evaluating test function %s", dbgStr(curr.at(0))); ret = evaluateConditionalFunction(curr.at(0).toKey(), tokPtr); switch (ret) { case ReturnTrue: okey = true; break; case ReturnFalse: okey = false; break; - default: return ret; + default: + traceMsg("aborting block, function status: %s", dbgReturn(ret)); + return ret; } + traceMsg("test function returned %s", dbgBool(okey)); okey ^= invert; } } else if (m_cumulative) { @@ -622,6 +664,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( #endif } else { skipExpression(tokPtr); + traceMsg("skipped test function %s", curr.size() == 1 ? dbgStr(curr.at(0)) : "<invalid>"); } or_op = !okey; // tentatively force next evaluation invert = false; @@ -638,8 +681,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( case TokNext: ret = ReturnNext; ctrlstm: - if (!m_skipLevel && okey != or_op) + if (!m_skipLevel && okey != or_op) { + traceMsg("flow control statement '%s', aborting block", dbgReturn(ret)); return ret; + } + traceMsg("skipped flow control statement '%s'", dbgReturn(ret)); okey = false, or_op = true; // force next evaluation continue; default: { @@ -651,9 +697,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( Q_ASSERT_X(false, "visitProBlock", "unexpected item type"); continue; } - if (ret != ReturnTrue && ret != ReturnFalse) + if (ret != ReturnTrue && ret != ReturnFalse) { + traceMsg("aborting block, status: %s", dbgReturn(ret)); return ret; + } } + traceMsg("leaving block, okey=%s", dbgBool(okey)); return returnBool(okey); } @@ -713,6 +762,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( } } + if (infinite) + traceMsg("entering infinite loop for %s", dbgKey(variable)); + else + traceMsg("entering loop for %s over %s", dbgKey(variable), dbgStrList(list)); + forever { if (infinite) { if (!variable.isEmpty()) @@ -721,6 +775,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( evalError(fL1S("Ran into infinite loop (> 1000 iterations).")); break; } + traceMsg("loop iteration %d", index); } else { ProString val; do { @@ -728,6 +783,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( goto do_break; val = list.at(index++); } while (val.isEmpty()); // stupid, but qmake is like that + traceMsg("loop iteration %s", dbgStr(val)); m_valuemapStack.top()[variable] = ProStringList(val); } @@ -748,6 +804,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( } do_break: + traceMsg("done looping"); + if (!variable.isEmpty()) m_valuemapStack.top()[variable] = oldVarVal; return ret; @@ -798,6 +856,7 @@ void QMakeEvaluator::visitProVariable( // We could make a union of modified and unmodified values, // but this will break just as much as it fixes, so leave it as is. replaceInList(&valuesRef(varName), regexp, replace, global, m_tmp2); + debugMsg(2, "replaced %s with %s", dbgQStr(pattern), dbgQStr(replace)); } else { ProStringList varVal = expandVariableReferences(tokPtr, sizeHint); switch (tok) { @@ -828,13 +887,16 @@ void QMakeEvaluator::visitProVariable( } } } + debugMsg(2, "assigning"); break; case TokAppendUnique: // *= insertUnique(&valuesRef(varName), varVal); + debugMsg(2, "appending unique"); break; case TokAppend: // += zipEmpty(&varVal); valuesRef(varName) += varVal; + debugMsg(2, "appending"); break; case TokRemove: // -= if (!m_cumulative) { @@ -842,9 +904,11 @@ void QMakeEvaluator::visitProVariable( } else { // We are stingy with our values, too. } + debugMsg(2, "removing"); break; } } + traceMsg("%s := %s", dbgKey(varName), dbgStrList(values(varName))); if (varName == statics.strTEMPLATE) setTemplate(); @@ -1047,7 +1111,7 @@ bool QMakeEvaluator::loadSpecInternal() if (!evaluateFeatureFile(QLatin1String("spec_pre.prf"))) return false; QString spec = m_qmakespec + QLatin1String("/qmake.conf"); - if (!evaluateFileDirect(spec, QMakeHandler::EvalConfigFile, LoadProOnly)) { + if (!evaluateFile(spec, QMakeHandler::EvalConfigFile, LoadProOnly)) { evalError(fL1S("Could not read qmake configuration file %1.").arg(spec)); return false; } @@ -1087,17 +1151,17 @@ bool QMakeEvaluator::loadSpec() QMakeEvaluator evaluator(m_option, m_parser, m_handler); if (!m_superfile.isEmpty()) { valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile); - if (!evaluator.evaluateFileDirect(m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly)) + if (!evaluator.evaluateFile(m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly)) return false; } if (!m_conffile.isEmpty()) { valuesRef(ProKey("_QMAKE_CONF_")) << ProString(m_conffile); - if (!evaluator.evaluateFileDirect(m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly)) + if (!evaluator.evaluateFile(m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly)) return false; } if (!m_cachefile.isEmpty()) { valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile); - if (!evaluator.evaluateFileDirect(m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly)) + if (!evaluator.evaluateFile(m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly)) return false; } if (qmakespec.isEmpty()) { @@ -1133,18 +1197,18 @@ bool QMakeEvaluator::loadSpec() m_qmakespec = QDir::cleanPath(qmakespec); if (!m_superfile.isEmpty() - && !evaluateFileDirect(m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly)) { + && !evaluateFile(m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly)) { return false; } if (!loadSpecInternal()) return false; updateFeaturePaths(); // The spec extends the feature search path, so rebuild the cache. if (!m_conffile.isEmpty() - && !evaluateFileDirect(m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly)) { + && !evaluateFile(m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly)) { return false; } if (!m_cachefile.isEmpty() - && !evaluateFileDirect(m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly)) { + && !evaluateFile(m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly)) { return false; } return true; @@ -1161,10 +1225,10 @@ void QMakeEvaluator::setupProject() vars[ProKey("OUT_PWD")] << ProString(m_outputDir).setSource(proFile); } -void QMakeEvaluator::visitCmdLine(const QString &cmds) +void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where) { if (!cmds.isEmpty()) { - if (ProFile *pro = m_parser->parsedProBlock(fL1S("(command line)"), cmds)) { + if (ProFile *pro = m_parser->parsedProBlock(cmds, where, -1)) { if (pro->isOk()) { m_locationStack.push(m_current); visitProBlock(pro, pro->tokPtr()); @@ -1175,6 +1239,28 @@ void QMakeEvaluator::visitCmdLine(const QString &cmds) } } +void QMakeEvaluator::evaluateConfigFeatures() +{ + QSet<QString> processed; + forever { + bool finished = true; + ProStringList configs = values(statics.strCONFIG); + for (int i = configs.size() - 1; i >= 0; --i) { + QString config = configs.at(i).toQString(m_tmp1).toLower(); + if (!processed.contains(config)) { + config.detach(); + processed.insert(config); + if (evaluateFeatureFile(config, true)) { + finished = false; + break; + } + } + } + if (finished) + break; + } +} + QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile( ProFile *pro, QMakeHandler::EvalFileType type, LoadFlags flags) { @@ -1243,6 +1329,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile( loadDefaults(); } + for (ProValueMap::ConstIterator it = m_extraVars.constBegin(); + it != m_extraVars.constEnd(); ++it) + m_valuemapStack.first().insert(it.key(), it.value()); + m_handler->aboutToEval(currentProFile(), pro, type); m_profileStack.push(pro); valuesRef(ProKey("PWD")) = ProStringList(ProString(currentDirectory())); @@ -1251,34 +1341,29 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile( evaluateFeatureFile(QLatin1String("default_pre.prf")); - visitCmdLine(m_option->precmds); + evaluateCommand(m_option->precmds, fL1S("(command line)")); + + // After user configs, to override them + if (!m_extraConfigs.isEmpty()) + evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(fL1S(" ")), fL1S("(extra configs)")); } + debugMsg(1, "visiting file %s", qPrintable(pro->fileName())); visitProBlock(pro, pro->tokPtr()); + debugMsg(1, "done visiting file %s", qPrintable(pro->fileName())); if (flags & LoadPostFiles) { - visitCmdLine(m_option->postcmds); + evaluateCommand(m_option->postcmds, fL1S("(command line -after)")); + + // Again, to ensure the project does not mess with us. + // Specifically, do not allow a project to override debug/release within a + // debug_and_release build pass - it's too late for that at this point anyway. + if (!m_extraConfigs.isEmpty()) + evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(fL1S(" ")), fL1S("(extra configs)")); evaluateFeatureFile(QLatin1String("default_post.prf")); - QSet<QString> processed; - forever { - bool finished = true; - ProStringList configs = values(statics.strCONFIG); - for (int i = configs.size() - 1; i >= 0; --i) { - QString config = configs.at(i).toQString(m_tmp1).toLower(); - if (!processed.contains(config)) { - config.detach(); - processed.insert(config); - if (evaluateFeatureFile(config, true)) { - finished = false; - break; - } - } - } - if (finished) - break; - } + evaluateConfigFeatures(); } m_profileStack.pop(); valuesRef(ProKey("PWD")) = ProStringList(ProString(currentDirectory())); @@ -1550,10 +1635,40 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction( return ReturnFalse; } -bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &context) +QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( + const ProKey &func, const ushort *&tokPtr) +{ + QHash<ProKey, ProFunctionDef>::ConstIterator it = + m_functionDefs.testFunctions.constFind(func); + if (it != m_functionDefs.testFunctions.constEnd()) { + const QList<ProStringList> args = prepareFunctionArgs(tokPtr); + traceMsg("calling %s(%s)", dbgKey(func), dbgStrListList(args)); + return evaluateBoolFunction(*it, args, func); + } + + //why don't the builtin functions just use args_list? --Sam + return evaluateBuiltinConditional(func, expandVariableReferences(tokPtr, 5, true)); +} + +ProStringList QMakeEvaluator::evaluateExpandFunction( + const ProKey &func, const ushort *&tokPtr) +{ + QHash<ProKey, ProFunctionDef>::ConstIterator it = + m_functionDefs.replaceFunctions.constFind(func); + if (it != m_functionDefs.replaceFunctions.constEnd()) { + const QList<ProStringList> args = prepareFunctionArgs(tokPtr); + traceMsg("calling $$%s(%s)", dbgKey(func), dbgStrListList(args)); + return evaluateFunction(*it, args, 0); + } + + //why don't the builtin functions just use args_list? --Sam + return evaluateBuiltinExpand(func, expandVariableReferences(tokPtr, 5, true)); +} + +bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &where, int line) { bool ret = false; - ProFile *pro = m_parser->parsedProBlock(context, cond, QMakeParser::TestGrammar); + ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar); if (pro) { if (pro->isOk()) { m_locationStack.push(m_current); @@ -1570,22 +1685,24 @@ void QMakeEvaluator::checkRequirements(const ProStringList &deps) { ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS")); foreach (const ProString &dep, deps) - if (!evaluateConditional(dep.toQString(), fL1S("(requires)"))) + if (!evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line)) failed << dep; } #endif ProValueMap *QMakeEvaluator::findValues(const ProKey &variableName, ProValueMap::Iterator *rit) { - for (int i = m_valuemapStack.size(); --i >= 0; ) { - ProValueMap::Iterator it = m_valuemapStack[i].find(variableName); - if (it != m_valuemapStack[i].end()) { + ProValueMapStack::Iterator vmi = m_valuemapStack.end(); + do { + --vmi; + ProValueMap::Iterator it = (*vmi).find(variableName); + if (it != (*vmi).end()) { if (it->constBegin() == statics.fakeValue.constBegin()) return 0; *rit = it; - return &m_valuemapStack[i]; + return &(*vmi); } - } + } while (vmi != m_valuemapStack.begin()); return 0; } @@ -1597,28 +1714,34 @@ ProStringList &QMakeEvaluator::valuesRef(const ProKey &variableName) it->clear(); return *it; } - for (int i = m_valuemapStack.size() - 1; --i >= 0; ) { - ProValueMap::ConstIterator it = m_valuemapStack.at(i).constFind(variableName); - if (it != m_valuemapStack.at(i).constEnd()) { - ProStringList &ret = m_valuemapStack.top()[variableName]; - if (it->constBegin() != statics.fakeValue.constBegin()) - ret = *it; - return ret; - } + ProValueMapStack::Iterator vmi = m_valuemapStack.end(); + if (--vmi != m_valuemapStack.begin()) { + do { + --vmi; + ProValueMap::ConstIterator it = (*vmi).constFind(variableName); + if (it != (*vmi).constEnd()) { + ProStringList &ret = m_valuemapStack.top()[variableName]; + if (it->constBegin() != statics.fakeValue.constBegin()) + ret = *it; + return ret; + } + } while (vmi != m_valuemapStack.begin()); } return m_valuemapStack.top()[variableName]; } ProStringList QMakeEvaluator::values(const ProKey &variableName) const { - for (int i = m_valuemapStack.size(); --i >= 0; ) { - ProValueMap::ConstIterator it = m_valuemapStack.at(i).constFind(variableName); - if (it != m_valuemapStack.at(i).constEnd()) { + ProValueMapStack::ConstIterator vmi = m_valuemapStack.constEnd(); + do { + --vmi; + ProValueMap::ConstIterator it = (*vmi).constFind(variableName); + if (it != (*vmi).constEnd()) { if (it->constBegin() == statics.fakeValue.constBegin()) break; return *it; } - } + } while (vmi != m_valuemapStack.constBegin()); return ProStringList(); } @@ -1630,7 +1753,7 @@ ProString QMakeEvaluator::first(const ProKey &variableName) const return ProString(); } -bool QMakeEvaluator::evaluateFileDirect( +bool QMakeEvaluator::evaluateFile( const QString &fileName, QMakeHandler::EvalFileType type, LoadFlags flags) { if (ProFile *pro = m_parser->parsedProFile(fileName, true)) { @@ -1648,13 +1771,13 @@ bool QMakeEvaluator::evaluateFileDirect( #endif return ok; } else { - if (!(flags & LoadSilent) && IoUtils::exists(fileName)) - languageWarning(fL1S("Include file %1 not found").arg(fileName)); + if (!(flags & LoadSilent) && !IoUtils::exists(fileName)) + evalError(fL1S("WARNING: Include file %1 not found").arg(fileName)); return false; } } -bool QMakeEvaluator::evaluateFile( +bool QMakeEvaluator::evaluateFileChecked( const QString &fileName, QMakeHandler::EvalFileType type, LoadFlags flags) { if (fileName.isEmpty()) @@ -1667,7 +1790,7 @@ bool QMakeEvaluator::evaluateFile( return false; } } while ((ref = ref->m_caller)); - return evaluateFileDirect(fileName, type, flags); + return evaluateFile(fileName, type, flags); } bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName, bool silent) @@ -1700,7 +1823,7 @@ bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName, bool silent) goto cool; #endif if (!silent) - languageWarning(fL1S("Cannot find feature %1").arg(fileName)); + evalError(fL1S("Cannot find feature %1").arg(fileName)); return false; cool: @@ -1719,7 +1842,7 @@ bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName, bool silent) #endif // The path is fully normalized already. - bool ok = evaluateFileDirect(fn, QMakeHandler::EvalFeatureFile, LoadProOnly); + bool ok = evaluateFile(fn, QMakeHandler::EvalFeatureFile, LoadProOnly); #ifdef PROEVALUATOR_CUMULATIVE m_cumulative = cumulative; @@ -1727,14 +1850,13 @@ bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName, bool silent) return ok; } -bool QMakeEvaluator::evaluateFileInto(const QString &fileName, QMakeHandler::EvalFileType type, - ProValueMap *values, LoadFlags flags) +bool QMakeEvaluator::evaluateFileInto(const QString &fileName, ProValueMap *values, LoadFlags flags) { QMakeEvaluator visitor(m_option, m_parser, m_handler); visitor.m_caller = this; visitor.m_outputDir = m_outputDir; visitor.m_featureRoots = m_featureRoots; - if (!visitor.evaluateFile(fileName, type, flags)) + if (!visitor.evaluateFileChecked(fileName, QMakeHandler::EvalAuxFile, flags)) return false; *values = visitor.m_valuemapStack.top(); #ifdef PROEVALUATOR_FULL @@ -1751,7 +1873,117 @@ void QMakeEvaluator::message(int type, const QString &msg) const { if (!m_skipLevel) m_handler->message(type, msg, - m_current.line ? m_current.pro->fileName() : QString(), m_current.line); + m_current.line ? m_current.pro->fileName() : QString(), + m_current.line != 0xffff ? m_current.line : -1); +} + +#ifdef PROEVALUATOR_DEBUG +void QMakeEvaluator::debugMsgInternal(int level, const char *fmt, ...) const +{ + va_list ap; + + if (level <= m_debugLevel) { + fprintf(stderr, "DEBUG %d: ", level); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputc('\n', stderr); + } +} + +void QMakeEvaluator::traceMsgInternal(const char *fmt, ...) const +{ + va_list ap; + + if (!m_current.pro) + fprintf(stderr, "DEBUG 1: "); + else if (m_current.line <= 0) + fprintf(stderr, "DEBUG 1: %s: ", qPrintable(m_current.pro->fileName())); + else + fprintf(stderr, "DEBUG 1: %s:%d: ", qPrintable(m_current.pro->fileName()), m_current.line); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputc('\n', stderr); +} + +QString QMakeEvaluator::formatValue(const ProString &val, bool forceQuote) +{ + QString ret; + ret.reserve(val.size() + 2); + const QChar *chars = val.constData(); + bool quote = forceQuote || val.isEmpty(); + for (int i = 0, l = val.size(); i < l; i++) { + QChar c = chars[i]; + ushort uc = c.unicode(); + if (uc < 32) { + switch (uc) { + case '\r': + ret += QLatin1String("\\r"); + break; + case '\n': + ret += QLatin1String("\\n"); + break; + case '\t': + ret += QLatin1String("\\t"); + break; + default: + ret += QString::fromLatin1("\\x%1").arg(uc, 2, 16, QLatin1Char('0')); + break; + } + } else { + switch (uc) { + case '\\': + ret += QLatin1String("\\\\"); + break; + case '"': + ret += QLatin1String("\\\""); + break; + case '\'': + ret += QLatin1String("\\'"); + break; + case 32: + quote = true; + // fallthrough + default: + ret += c; + break; + } + } + } + if (quote) { + ret.prepend(QLatin1Char('"')); + ret.append(QLatin1Char('"')); + } + return ret; +} + +QString QMakeEvaluator::formatValueList(const ProStringList &vals, bool commas) +{ + QString ret; + + foreach (const ProString &str, vals) { + if (!ret.isEmpty()) { + if (commas) + ret += QLatin1Char(','); + ret += QLatin1Char(' '); + } + ret += formatValue(str); + } + return ret; } +QString QMakeEvaluator::formatValueListList(const QList<ProStringList> &lists) +{ + QString ret; + + foreach (const ProStringList &list, lists) { + if (!ret.isEmpty()) + ret += QLatin1String(", "); + ret += formatValueList(list); + } + return ret; +} +#endif + QT_END_NAMESPACE diff --git a/src/shared/proparser/qmakeevaluator.h b/src/shared/proparser/qmakeevaluator.h index 9f727482b1..6ac7db9c28 100644 --- a/src/shared/proparser/qmakeevaluator.h +++ b/src/shared/proparser/qmakeevaluator.h @@ -37,13 +37,14 @@ #include "qmakeparser.h" #include "ioutils.h" -#include <QList> -#include <QSet> -#include <QStack> -#include <QString> -#include <QStringList> +#include <qlist.h> +#include <qlinkedlist.h> +#include <qset.h> +#include <qstack.h> +#include <qstring.h> +#include <qstringlist.h> #ifndef QT_BOOTSTRAPPED -# include <QProcess> +# include <qprocess.h> #endif QT_BEGIN_NAMESPACE @@ -70,6 +71,17 @@ public: virtual void doneWithEval(ProFile *parent) = 0; }; +// We use a QLinkedList based stack instead of a QVector based one (QStack), so that +// the addresses of value maps stay constant. The qmake generators rely on that. +class QMAKE_EXPORT ProValueMapStack : public QLinkedList<ProValueMap> +{ +public: + inline void push(const ProValueMap &t) { append(t); } + inline ProValueMap pop() { return takeLast(); } + ProValueMap &top() { return last(); } + const ProValueMap &top() const { return last(); } +}; + class QMAKE_EXPORT QMakeEvaluator { public: @@ -88,11 +100,18 @@ public: QMakeHandler *handler); ~QMakeEvaluator(); + void setExtraVars(const ProValueMap &extraVars) { m_extraVars = extraVars; } + void setExtraConfigs(const ProStringList &extraConfigs) { m_extraConfigs = extraConfigs; } + void setOutputDir(const QString &outputDir) { m_outputDir = outputDir; } + ProStringList values(const ProKey &variableName) const; ProStringList &valuesRef(const ProKey &variableName); ProString first(const ProKey &variableName) const; ProString propertyValue(const ProKey &val) const; + ProString dirSep() const { return m_dirSep; } + bool isHostBuild() const { return m_hostBuild; } + enum VisitReturn { ReturnFalse, ReturnTrue, @@ -119,7 +138,7 @@ public: bool loadSpec(); void initFrom(const QMakeEvaluator &other); void setupProject(); - void visitCmdLine(const QString &cmds); + void evaluateCommand(const QString &cmds, const QString &where); VisitReturn visitProFile(ProFile *pro, QMakeHandler::EvalFileType type, LoadFlags flags); VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr); @@ -143,16 +162,17 @@ public: QString currentDirectory() const; ProFile *currentProFile() const; QString resolvePath(const QString &fileName) const - { return ProFileEvaluatorInternal::IoUtils::resolvePath(currentDirectory(), fileName); } + { return QMakeInternal::IoUtils::resolvePath(currentDirectory(), fileName); } - bool evaluateFileDirect(const QString &fileName, QMakeHandler::EvalFileType type, - LoadFlags flags); bool evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type, LoadFlags flags); + bool evaluateFileChecked(const QString &fileName, QMakeHandler::EvalFileType type, + LoadFlags flags); bool evaluateFeatureFile(const QString &fileName, bool silent = false); - bool evaluateFileInto(const QString &fileName, QMakeHandler::EvalFileType type, + bool evaluateFileInto(const QString &fileName, ProValueMap *values, // output-only LoadFlags flags); + void evaluateConfigFeatures(); void message(int type, const QString &msg) const; void evalError(const QString &msg) const { message(QMakeHandler::EvalError, msg); } @@ -171,7 +191,10 @@ public: ProStringList evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr); VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr); - bool evaluateConditional(const QString &cond, const QString &context); + ProStringList evaluateBuiltinExpand(const ProKey &function, const ProStringList &args); + VisitReturn evaluateBuiltinConditional(const ProKey &function, const ProStringList &args); + + bool evaluateConditional(const QString &cond, const QString &where, int line = -1); #ifdef PROEVALUATOR_FULL void checkRequirements(const ProStringList &deps); #endif @@ -204,17 +227,35 @@ public: enum { m_skipLevel = 0 }; #endif +#ifdef PROEVALUATOR_DEBUG + void debugMsgInternal(int level, const char *fmt, ...) const; + void traceMsgInternal(const char *fmt, ...) const; + static QString formatValue(const ProString &val, bool forceQuote = false); + static QString formatValueList(const ProStringList &vals, bool commas = false); + static QString formatValueListList(const QList<ProStringList> &vals); + + const int m_debugLevel; +#else + ALWAYS_INLINE void debugMsgInternal(int, const char *, ...) const {} + ALWAYS_INLINE void traceMsgInternal(const char *, ...) const {} + + enum { m_debugLevel = 0 }; +#endif + struct Location { Location() : pro(0), line(0) {} - Location(ProFile *_pro, int _line) : pro(_pro), line(_line) {} + Location(ProFile *_pro, ushort _line) : pro(_pro), line(_line) {} + void clear() { pro = 0; line = 0; } ProFile *pro; - int line; + ushort line; }; Location m_current; // Currently evaluated location QStack<Location> m_locationStack; // All execution location changes QStack<ProFile *> m_profileStack; // Includes only + ProValueMap m_extraVars; + ProStringList m_extraConfigs; QString m_outputDir; int m_listCount; @@ -234,7 +275,7 @@ public: ProString m_dirSep; ProFunctionDefs m_functionDefs; ProStringList m_returnValue; - QStack<ProValueMap> m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii. + ProValueMapStack m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii. QString m_tmp1, m_tmp2, m_tmp3, m_tmp[2]; // Temporaries for efficient toQString mutable QString m_mtmp; diff --git a/src/shared/proparser/qmakeevaluator_p.h b/src/shared/proparser/qmakeevaluator_p.h index 3302fbe49e..d61a43c671 100644 --- a/src/shared/proparser/qmakeevaluator_p.h +++ b/src/shared/proparser/qmakeevaluator_p.h @@ -32,11 +32,38 @@ #include "proitems.h" -#include <QRegExp> +#include <qregexp.h> + +#define debugMsg if (!m_debugLevel) {} else debugMsgInternal +#define traceMsg if (!m_debugLevel) {} else traceMsgInternal +#ifdef PROEVALUATOR_DEBUG +# define dbgBool(b) (b ? "true" : "false") +# define dbgReturn(r) \ + (r == ReturnError ? "error" : \ + r == ReturnBreak ? "break" : \ + r == ReturnNext ? "next" : \ + r == ReturnReturn ? "return" : \ + "<invalid>") +# define dbgKey(s) qPrintable(s.toString().toQString()) +# define dbgStr(s) qPrintable(formatValue(s, true)) +# define dbgStrList(s) qPrintable(formatValueList(s)) +# define dbgSepStrList(s) qPrintable(formatValueList(s, true)) +# define dbgStrListList(s) qPrintable(formatValueListList(s)) +# define dbgQStr(s) dbgStr(ProString(s)) +#else +# define dbgBool(b) 0 +# define dbgReturn(r) 0 +# define dbgKey(s) 0 +# define dbgStr(s) 0 +# define dbgStrList(s) 0 +# define dbgSepStrList(s) 0 +# define dbgStrListList(s) 0 +# define dbgQStr(s) 0 +#endif QT_BEGIN_NAMESPACE -namespace ProFileEvaluatorInternal { +namespace QMakeInternal { struct QMakeStatics { QString field_sep; diff --git a/src/shared/proparser/qmakeglobals.cpp b/src/shared/proparser/qmakeglobals.cpp index be1ba77577..1d5bd98fa6 100644 --- a/src/shared/proparser/qmakeglobals.cpp +++ b/src/shared/proparser/qmakeglobals.cpp @@ -32,21 +32,21 @@ #include "qmakeevaluator.h" #include "ioutils.h" -#include <QByteArray> -#include <QDateTime> -#include <QDebug> -#include <QDir> -#include <QFile> -#include <QFileInfo> -#include <QList> -#include <QRegExp> -#include <QSet> -#include <QStack> -#include <QString> -#include <QStringList> -#include <QTextStream> +#include <qbytearray.h> +#include <qdatetime.h> +#include <qdebug.h> +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qlist.h> +#include <qregexp.h> +#include <qset.h> +#include <qstack.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qtextstream.h> #ifdef PROEVALUATOR_THREAD_SAFE -# include <QThreadPool> +# include <qthreadpool.h> #endif #ifdef Q_OS_UNIX @@ -93,6 +93,9 @@ QMakeGlobals::QMakeGlobals() do_cache = true; +#ifdef PROEVALUATOR_DEBUG + debugLevel = 0; +#endif #ifdef Q_OS_WIN dirlist_sep = QLatin1Char(';'); dir_sep = QLatin1Char('\\'); @@ -108,43 +111,120 @@ QMakeGlobals::~QMakeGlobals() qDeleteAll(baseEnvs); } -void QMakeGlobals::setCommandLineArguments(const QStringList &args) +QString QMakeGlobals::cleanSpec(QMakeCmdLineParserState &state, const QString &spec) { - QStringList _precmds, _preconfigs, _postcmds, _postconfigs; - bool after = false; + QString ret = QDir::cleanPath(spec); + if (ret.contains(QLatin1Char('/'))) { + QString absRet = QDir(state.pwd).absoluteFilePath(ret); + if (QFile::exists(absRet)) + ret = QDir::cleanPath(absRet); + } + return ret; +} - bool isConf = false; - foreach (const QString &arg, args) { - if (isConf) { - isConf = false; - if (after) - _postconfigs << arg; +QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments( + QMakeCmdLineParserState &state, QStringList &args, int *pos) +{ + enum { ArgNone, ArgConfig, ArgSpec, ArgXSpec, ArgTmpl, ArgTmplPfx, ArgCache } argState = ArgNone; + for (; *pos < args.count(); (*pos)++) { + QString arg = args.at(*pos); + switch (argState) { + case ArgConfig: + if (state.after) + state.postconfigs << arg; else - _preconfigs << arg; - } else if (arg.startsWith(QLatin1Char('-'))) { - if (arg == QLatin1String("-after")) { - after = true; - } else if (arg == QLatin1String("-config")) { - isConf = true; - } else if (arg == QLatin1String("-win32")) { - dir_sep = QLatin1Char('\\'); - } else if (arg == QLatin1String("-unix")) { - dir_sep = QLatin1Char('/'); + state.preconfigs << arg; + break; + case ArgSpec: + qmakespec = args[*pos] = cleanSpec(state, arg); + break; + case ArgXSpec: + xqmakespec = args[*pos] = cleanSpec(state, arg); + break; + case ArgTmpl: + user_template = arg; + break; + case ArgTmplPfx: + user_template_prefix = arg; + break; + case ArgCache: + cachefile = args[*pos] = QDir::cleanPath(QDir(state.pwd).absoluteFilePath(arg)); + break; + default: + if (arg.startsWith(QLatin1Char('-'))) { + if (arg == QLatin1String("-after")) { + state.after = true; + } else if (arg == QLatin1String("-config")) { + argState = ArgConfig; + } else if (arg == QLatin1String("-nocache")) { + do_cache = false; + } else if (arg == QLatin1String("-cache")) { + argState = ArgCache; + } else if (arg == QLatin1String("-platform") || arg == QLatin1String("-spec")) { + argState = ArgSpec; + } else if (arg == QLatin1String("-xplatform") || arg == QLatin1String("-xspec")) { + argState = ArgXSpec; + } else if (arg == QLatin1String("-template") || arg == QLatin1String("-t")) { + argState = ArgTmpl; + } else if (arg == QLatin1String("-template_prefix") || arg == QLatin1String("-tp")) { + argState = ArgTmplPfx; + } else if (arg == QLatin1String("-win32")) { + dir_sep = QLatin1Char('\\'); + } else if (arg == QLatin1String("-unix")) { + dir_sep = QLatin1Char('/'); + } else { + return ArgumentUnknown; + } + } else if (arg.contains(QLatin1Char('='))) { + if (state.after) + state.postcmds << arg; + else + state.precmds << arg; + } else { + return ArgumentUnknown; } - } else if (arg.contains(QLatin1Char('='))) { - if (after) - _postcmds << arg; - else - _precmds << arg; + continue; } + argState = ArgNone; + } + if (argState != ArgNone) + return ArgumentMalformed; + return ArgumentsOk; +} + +void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state) +{ + if (!state.preconfigs.isEmpty()) + state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(fL1S(" "))); + precmds = state.precmds.join(fL1S("\n")); + if (!state.postconfigs.isEmpty()) + state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(fL1S(" "))); + postcmds = state.postcmds.join(fL1S("\n")); + + if (xqmakespec.isEmpty()) + xqmakespec = qmakespec; +} + +void QMakeGlobals::useEnvironment() +{ + if (xqmakespec.isEmpty()) + xqmakespec = getEnv(QLatin1String("XQMAKESPEC")); + if (qmakespec.isEmpty()) { + qmakespec = getEnv(QLatin1String("QMAKESPEC")); + if (xqmakespec.isEmpty()) + xqmakespec = qmakespec; } +} - if (!_preconfigs.isEmpty()) - _precmds << (fL1S("CONFIG += ") + _preconfigs.join(fL1S(" "))); - precmds = _precmds.join(fL1S("\n")); - if (!_postconfigs.isEmpty()) - _postcmds << (fL1S("CONFIG += ") + _postconfigs.join(fL1S(" "))); - postcmds = _postcmds.join(fL1S("\n")); +void QMakeGlobals::setCommandLineArguments(const QString &pwd, const QStringList &_args) +{ + QStringList args = _args; + + QMakeCmdLineParserState state(pwd); + for (int pos = 0; pos < args.size(); pos++) + addCommandLineArguments(state, args, &pos); + commitCommandLineArguments(state); + useEnvironment(); } void QMakeGlobals::setDirectories(const QString &input_dir, const QString &output_dir) @@ -167,13 +247,25 @@ void QMakeGlobals::setDirectories(const QString &input_dir, const QString &outpu } } +QString QMakeGlobals::shadowedPath(const QString &fileName) const +{ + if (source_root.isEmpty()) + return fileName; + if (fileName.startsWith(source_root) + && (fileName.length() == source_root.length() + || fileName.at(source_root.length()) == QLatin1Char('/'))) { + return build_root + fileName.mid(source_root.length()); + } + return QString(); +} + QString QMakeGlobals::getEnv(const QString &var) const { -#ifndef QT_BOOTSTRAPPED - if (!environment.isEmpty()) - return environment.value(var); -#endif +#ifdef PROEVALUATOR_SETENV + return environment.value(var); +#else return QString::fromLocal8Bit(qgetenv(var.toLocal8Bit().constData())); +#endif } QStringList QMakeGlobals::getPathListEnv(const QString &var) const @@ -201,6 +293,7 @@ QString QMakeGlobals::expandEnvVars(const QString &str) const return string; } +#ifndef QT_BUILD_QMAKE #ifdef PROEVALUATOR_INIT_PROPS bool QMakeGlobals::initProperties() { @@ -257,5 +350,6 @@ void QMakeGlobals::setProperties(const QHash<QString, QString> &props) properties.insert(ProKey(it.key()), ProString(it.value())); } #endif +#endif // QT_BUILD_QMAKE QT_END_NAMESPACE diff --git a/src/shared/proparser/qmakeglobals.h b/src/shared/proparser/qmakeglobals.h index 2211274e08..18ae12e687 100644 --- a/src/shared/proparser/qmakeglobals.h +++ b/src/shared/proparser/qmakeglobals.h @@ -33,14 +33,18 @@ #include "qmake_global.h" #include "proitems.h" -#include <QHash> -#include <QStringList> +#ifdef QT_BUILD_QMAKE +# include <property.h> +#endif + +#include <qhash.h> +#include <qstringlist.h> #ifndef QT_BOOTSTRAPPED -# include <QProcess> +# include <qprocess.h> #endif #ifdef PROEVALUATOR_THREAD_SAFE -# include <QMutex> -# include <QWaitCondition> +# include <qmutex.h> +# include <qwaitcondition.h> #endif QT_BEGIN_NAMESPACE @@ -76,6 +80,15 @@ public: QMakeEvaluator *evaluator; }; +class QMAKE_EXPORT QMakeCmdLineParserState +{ +public: + QMakeCmdLineParserState(const QString &_pwd) : pwd(_pwd), after(false) {} + QString pwd; + QStringList precmds, preconfigs, postcmds, postconfigs; + bool after; +}; + class QMAKE_EXPORT QMakeGlobals { public: @@ -85,37 +98,55 @@ public: bool do_cache; QString dir_sep; QString dirlist_sep; - QString qmakespec; - QString xqmakespec; QString cachefile; -#ifndef QT_BOOTSTRAPPED +#ifdef PROEVALUATOR_SETENV QProcessEnvironment environment; #endif - QString sysroot; QString qmake_abslocation; + + QString qmakespec, xqmakespec; QString user_template, user_template_prefix; + QString precmds, postcmds; - // -nocache, -cache, -spec, QMAKESPEC - // -set persistent value - void setCommandLineArguments(const QStringList &args); +#ifdef PROEVALUATOR_DEBUG + int debugLevel; +#endif + + enum ArgumentReturn { ArgumentUnknown, ArgumentMalformed, ArgumentsOk }; + ArgumentReturn addCommandLineArguments(QMakeCmdLineParserState &state, + QStringList &args, int *pos); + void commitCommandLineArguments(QMakeCmdLineParserState &state); + void setCommandLineArguments(const QString &pwd, const QStringList &args); + void useEnvironment(); void setDirectories(const QString &input_dir, const QString &output_dir); -#ifdef PROEVALUATOR_INIT_PROPS - bool initProperties(); +#ifdef QT_BUILD_QMAKE + void setQMakeProperty(QMakeProperty *prop) { property = prop; } + ProString propertyValue(const ProKey &name) const { return property->value(name); } #else +# ifdef PROEVALUATOR_INIT_PROPS + bool initProperties(); +# else void setProperties(const QHash<QString, QString> &props); -#endif +# endif ProString propertyValue(const ProKey &name) const { return properties.value(name); } +#endif QString expandEnvVars(const QString &str) const; + QString shadowedPath(const QString &fileName) const; private: QString getEnv(const QString &) const; QStringList getPathListEnv(const QString &var) const; + QString cleanSpec(QMakeCmdLineParserState &state, const QString &spec); + QString source_root, build_root; - QString precmds, postcmds; +#ifdef QT_BUILD_QMAKE + QMakeProperty *property; +#else QHash<ProKey, ProString> properties; +#endif #ifdef PROEVALUATOR_THREAD_SAFE QMutex mutex; diff --git a/src/shared/proparser/qmakeparser.cpp b/src/shared/proparser/qmakeparser.cpp index be8bd86859..847039682a 100644 --- a/src/shared/proparser/qmakeparser.cpp +++ b/src/shared/proparser/qmakeparser.cpp @@ -30,11 +30,11 @@ #include "qmakeparser.h" #include "ioutils.h" -using namespace ProFileEvaluatorInternal; +using namespace QMakeInternal; -#include <QFile> +#include <qfile.h> #ifdef PROPARSER_THREAD_SAFE -# include <QThreadPool> +# include <qthreadpool.h> #endif QT_BEGIN_NAMESPACE @@ -199,10 +199,11 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, bool cache) return pro; } -ProFile *QMakeParser::parsedProBlock(const QString &name, const QString &contents, SubGrammar grammar) +ProFile *QMakeParser::parsedProBlock( + const QString &contents, const QString &name, int line, SubGrammar grammar) { ProFile *pro = new ProFile(name); - if (!read(pro, contents, grammar)) { + if (!read(pro, contents, line, grammar)) { delete pro; pro = 0; } @@ -219,9 +220,17 @@ bool QMakeParser::read(ProFile *pro) return false; } - QString content(QString::fromLocal8Bit(file.readAll())); + QByteArray bcont = file.readAll(); + if (bcont.startsWith(QByteArray("\xef\xbb\xbf"))) { + // UTF-8 BOM will cause subtle errors + m_handler->message(QMakeParserHandler::ParserIoError, + fL1S("Unexpected UTF-8 BOM in %1").arg(pro->fileName())); + return false; + } + QString content(QString::fromLocal8Bit(bcont)); + bcont.clear(); file.close(); - return read(pro, content, FullGrammar); + return read(pro, content, 1, FullGrammar); } void QMakeParser::putTok(ushort *&tokPtr, ushort tok) @@ -261,10 +270,10 @@ void QMakeParser::finalizeHashStr(ushort *buf, uint len) buf[-2] = (ushort)(hash >> 16); } -bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) +bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar) { m_proFile = pro; - m_lineNo = 1; + m_lineNo = line; // Final precompiled token stream buffer QString tokBuff; @@ -315,7 +324,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) m_operator = NoOperator; m_markLine = m_lineNo; m_inError = false; - Context context = CtxTest; int parens = 0; // Braces in value context int argc = 0; int wordCount = 0; // Number of words in currently accumulated expression @@ -326,8 +334,15 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) ushort quote = 0; ushort term = 0; - ushort *ptr = buf; - ptr += 4; + Context context; + ushort *ptr; + if (grammar == ValueGrammar) { + context = CtxPureValue; + ptr = tokPtr + 2; + } else { + context = CtxTest; + ptr = buf + 4; + } ushort *xprPtr = ptr; #define FLUSH_LHS_LITERAL() \ @@ -379,11 +394,23 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) putTok(tokPtr, TokValueTerminator); \ } while (0) + const ushort *end; // End of this line + const ushort *cptr; // Start of next line + bool lineCont; + int indent; + + if (context == CtxPureValue) { + end = (const ushort *)in.unicode() + in.length(); + cptr = 0; + lineCont = false; + indent = 0; // just gcc being stupid + goto nextChr; + } + forever { ushort c; // First, skip leading whitespace - int indent; for (indent = 0; ; ++cur, ++indent) { c = *cur; if (c == '\n') { @@ -398,8 +425,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) } // Then strip comments. Yep - no escaping is possible. - const ushort *end; // End of this line - const ushort *cptr; // Start of next line for (cptr = cur;; ++cptr) { c = *cptr; if (c == '#') { @@ -428,7 +453,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) } // Then look for line continuations. Yep - no escaping here as well. - bool lineCont; forever { // We don't have to check for underrun here, as we already determined // that the line is non-empty. @@ -503,6 +527,8 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) if (tok == TokVariable && c == '(') tok = TokFuncName; notfunc: + if (ptr == xprPtr) + languageWarning(fL1S("Missing name in expansion")); if (quote) tok |= TokQuoted; if (needSep) { @@ -586,7 +612,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) *ptr++ = ' '; } goto nextChr; - } else if (c == ' ' || c == '\t') { + } else if ((c == ' ' || c == '\t') && context != CtxPureValue) { putSpace = true; goto nextChr; } else if (c == '!' && ptr == xprPtr && context == CtxTest) { @@ -596,12 +622,12 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) } else if (c == '\'' || c == '"') { quote = c; goto nextChr; - } else if (c == ' ' || c == '\t') { - FLUSH_LITERAL(); - goto nextWord; } else if (context == CtxArgs) { // Function arg context - if (c == '(') { + if (c == ' ' || c == '\t') { + FLUSH_RHS_LITERAL(); + goto nextWord; + } else if (c == '(') { ++parens; } else if (c == ')') { if (--parens < 0) { @@ -637,7 +663,10 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) } } else if (context == CtxTest) { // Test or LHS context - if (c == '(') { + if (c == ' ' || c == '\t') { + FLUSH_LHS_LITERAL(); + goto nextWord; + } else if (c == '(') { FLUSH_LHS_LITERAL(); if (wordCount != 1) { if (wordCount) @@ -733,8 +762,11 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) ptr = ++tokPtr; goto nextToken; } - } else { // context == CtxValue - if (c == '{') { + } else if (context == CtxValue) { + if (c == ' ' || c == '\t') { + FLUSH_RHS_LITERAL(); + goto nextWord; + } else if (c == '{') { ++parens; } else if (c == '}') { if (!parens) { @@ -790,6 +822,8 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) if (context == CtxValue) { tokPtr[-1] = 0; // sizehint putTok(tokPtr, TokValueTerminator); + } else if (context == CtxPureValue) { + putTok(tokPtr, TokValueTerminator); } else { bogusTest(tokPtr); } @@ -797,6 +831,9 @@ bool QMakeParser::read(ProFile *pro, const QString &in, SubGrammar grammar) FLUSH_VALUE_LIST(); if (parens) languageWarning(fL1S("Possible braces mismatch")); + } else if (context == CtxPureValue) { + tokPtr = ptr; + putTok(tokPtr, TokValueTerminator); } else { finalizeCond(tokPtr, buf, ptr, wordCount); } diff --git a/src/shared/proparser/qmakeparser.h b/src/shared/proparser/qmakeparser.h index 5515c75b4c..c319f44d3a 100644 --- a/src/shared/proparser/qmakeparser.h +++ b/src/shared/proparser/qmakeparser.h @@ -32,11 +32,12 @@ #include "qmake_global.h" #include "proitems.h" -#include <QHash> -#include <QStack> + +#include <qhash.h> +#include <qstack.h> #ifdef PROPARSER_THREAD_SAFE -# include <QMutex> -# include <QWaitCondition> +# include <qmutex.h> +# include <qwaitcondition.h> #endif QT_BEGIN_NAMESPACE @@ -75,10 +76,10 @@ public: QMakeParser(ProFileCache *cache, QMakeParserHandler *handler); - enum SubGrammar { FullGrammar, TestGrammar }; + enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar }; // fileName is expected to be absolute and cleanPath()ed. ProFile *parsedProFile(const QString &fileName, bool cache = false); - ProFile *parsedProBlock(const QString &name, const QString &contents, + ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0, SubGrammar grammar = FullGrammar); private: @@ -104,7 +105,7 @@ private: StCond // Conditionals met on current line }; - enum Context { CtxTest, CtxValue, CtxArgs }; + enum Context { CtxTest, CtxValue, CtxPureValue, CtxArgs }; struct ParseCtx { int parens; // Nesting of non-functional parentheses int argc; // Number of arguments in current function call @@ -115,7 +116,7 @@ private: }; bool read(ProFile *pro); - bool read(ProFile *pro, const QString &content, SubGrammar grammar); + bool read(ProFile *pro, const QString &content, int line, SubGrammar grammar); ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok); ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len); diff --git a/src/tools/QtcTool.qbs b/src/tools/QtcTool.qbs index 7669496dca..a8b4f4d522 100644 --- a/src/tools/QtcTool.qbs +++ b/src/tools/QtcTool.qbs @@ -1,8 +1,9 @@ import qbs.base 1.0 +import "../../qbs/defaults.js" as Defaults Application { Depends { name: "cpp" } - cpp.defines: project.additionalCppDefines + cpp.defines: Defaults.defines(qbs) cpp.linkerFlags: { if (qbs.buildVariant == "release" && (qbs.toolchain == "gcc" || qbs.toolchain == "mingw")) return ["-Wl,-s"] diff --git a/src/tools/qml2puppet/qml2puppet.pro b/src/tools/qml2puppet/qml2puppet.pro new file mode 100644 index 0000000000..b8e17814be --- /dev/null +++ b/src/tools/qml2puppet/qml2puppet.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs + +include(../../../qtcreator.pri) + +greaterThan(QT_MAJOR_VERSION, 4) { + QT += declarative-private core-private + SUBDIRS += qml2puppet +} + diff --git a/src/tools/qml2puppet/qml2puppet/qml2puppet.pro b/src/tools/qml2puppet/qml2puppet/qml2puppet.pro new file mode 100644 index 0000000000..f791416d76 --- /dev/null +++ b/src/tools/qml2puppet/qml2puppet/qml2puppet.pro @@ -0,0 +1,10 @@ +TARGET = qml2puppet + +TEMPLATE = app + +include(../../../../qtcreator.pri) + +DESTDIR = $$IDE_BIN_PATH +include(../../../rpath.pri) + +include(../../../../share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri) diff --git a/src/tools/qtcdebugger/qtcdebugger.qbs b/src/tools/qtcdebugger/qtcdebugger.qbs index bc416fb95b..5b86287746 100644 --- a/src/tools/qtcdebugger/qtcdebugger.qbs +++ b/src/tools/qtcdebugger/qtcdebugger.qbs @@ -21,6 +21,6 @@ QtcTool { files: [ "main.cpp", "../../shared/registryaccess/registryaccess.cpp", - "../../shared/registryaccess/registryaccess.h" + "../../shared/registryaccess/registryaccess.h", ] } diff --git a/src/tools/qtcreatorcrashhandler/backtracecollector.cpp b/src/tools/qtcreatorcrashhandler/backtracecollector.cpp new file mode 100644 index 0000000000..e62e2432c1 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/backtracecollector.cpp @@ -0,0 +1,128 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "backtracecollector.h" + +#include <QDebug> +#include <QScopedPointer> +#include <QTemporaryFile> + +const char GdbBatchCommands[] = + "set height 0\n" + "set width 0\n" + "thread\n" + "thread apply all backtrace full\n"; + +class BacktraceCollectorPrivate +{ +public: + BacktraceCollectorPrivate() : errorOccurred(false) {} + + bool errorOccurred; + QScopedPointer<QTemporaryFile> commandFile; + QProcess debugger; + QString output; +}; + +BacktraceCollector::BacktraceCollector(QObject *parent) : + QObject(parent), d(new BacktraceCollectorPrivate) +{ + connect(&d->debugger, SIGNAL(finished(int,QProcess::ExitStatus)), + SLOT(onDebuggerFinished(int,QProcess::ExitStatus))); + connect(&d->debugger, SIGNAL(error(QProcess::ProcessError)), + SLOT(onDebuggerError(QProcess::ProcessError))); + connect(&d->debugger, SIGNAL(readyRead()), SLOT(onDebuggerOutputAvailable())); + d->debugger.setProcessChannelMode(QProcess::MergedChannels); +} + +BacktraceCollector::~BacktraceCollector() +{ + delete d; +} + +void BacktraceCollector::run(Q_PID pid) +{ + d->debugger.start(QLatin1String("gdb"), QStringList() + << QLatin1String("--nw") // Do not use a window interface. + << QLatin1String("--nx") // Do not read .gdbinit file. + << QLatin1String("--batch") // Exit after processing options. + << QLatin1String("--command") << createTemporaryCommandFile() + << QLatin1String("--pid") << QString::number(pid) + ); +} + +bool BacktraceCollector::isRunning() const +{ + return d->debugger.state() == QProcess::Running; +} + +void BacktraceCollector::kill() +{ + d->debugger.kill(); +} + +void BacktraceCollector::onDebuggerFinished(int exitCode, QProcess::ExitStatus /*exitStatus*/) +{ + if (d->errorOccurred) { + emit error(QLatin1String("QProcess: ") + d->debugger.errorString()); + return; + } + if (exitCode != 0) { + emit error(QString::fromLatin1("Debugger exited with code %1.").arg(exitCode)); + return; + } + emit backtrace(d->output); +} + +void BacktraceCollector::onDebuggerError(QProcess::ProcessError /*error*/) +{ + d->errorOccurred = true; +} + +QString BacktraceCollector::createTemporaryCommandFile() +{ + d->commandFile.reset(new QTemporaryFile); + if (!d->commandFile->open()) { + emit error(QLatin1String("Error: Could not create temporary command file.")); + return QString(); + } + if (d->commandFile->write(GdbBatchCommands) == -1) { + emit error(QLatin1String("Error: Could not write temporary command file.")); + return QString(); + } + d->commandFile->close(); + return d->commandFile->fileName(); +} + +void BacktraceCollector::onDebuggerOutputAvailable() +{ + const QString newChunk = d->debugger.readAll(); + d->output.append(newChunk); + emit backtraceChunk(newChunk); +} diff --git a/src/tools/qtcreatorcrashhandler/backtracecollector.h b/src/tools/qtcreatorcrashhandler/backtracecollector.h new file mode 100644 index 0000000000..0fc14a4cd6 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/backtracecollector.h @@ -0,0 +1,64 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef BACKTRACECOLLECTOR_H +#define BACKTRACECOLLECTOR_H + +#include <QProcess> + +class BacktraceCollectorPrivate; + +class BacktraceCollector : public QObject +{ + Q_OBJECT +public: + explicit BacktraceCollector(QObject *parent = 0); + ~BacktraceCollector(); + + void run(Q_PID pid); + bool isRunning() const; + void kill(); + +signals: + void error(const QString &errorMessage); + void backtrace(const QString &backtrace); + void backtraceChunk(const QString &chunk); + +private slots: + void onDebuggerOutputAvailable(); + void onDebuggerFinished(int exitCode, QProcess::ExitStatus exitStatus); + void onDebuggerError(QProcess::ProcessError err); + +private: + QString createTemporaryCommandFile(); + + BacktraceCollectorPrivate *d; +}; + +#endif // BACKTRACECOLLECTOR_H diff --git a/src/tools/qtcreatorcrashhandler/crashhandler.cpp b/src/tools/qtcreatorcrashhandler/crashhandler.cpp new file mode 100644 index 0000000000..7521802716 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/crashhandler.cpp @@ -0,0 +1,313 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "crashhandler.h" +#include "crashhandlerdialog.h" +#include "backtracecollector.h" +#include "utils.h" + +#include <utils/environment.h> + +#include <QApplication> +#include <QDebug> +#include <QDesktopServices> +#include <QDir> +#include <QFile> +#include <QRegExp> +#include <QTextStream> +#include <QUrl> +#include <QVector> + +#include <stdio.h> +#include <stdlib.h> + +#include <errno.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/wait.h> + +static const char FileDistroInformation[] = "/etc/lsb-release"; +static const char FileKernelVersion[] = "/proc/version"; +static const char QtCreatorExecutable[] = "qtcreator"; + +static QString collectLinuxDistributionInfo() +{ + return QString::fromLatin1(fileContents(QLatin1String(FileDistroInformation))); +} + +static QString collectKernelVersionInfo() +{ + return QString::fromLatin1(fileContents(QLatin1String(FileKernelVersion))); +} + +// Convience class for interacting with exec() family of functions. +class CExecList : public QVector<char *> +{ +public: + CExecList(const QStringList &list) + { + foreach (const QString &item, list) + append(qstrdup(item.toLatin1().data())); + append(0); + } + + ~CExecList() + { + for (int i = 0; i < size(); ++i) + delete[] value(i); + } +}; + +class CrashHandlerPrivate +{ +public: + CrashHandlerPrivate(pid_t pid, const QString &signalName, CrashHandler *crashHandler) + : pid(pid), + creatorInPath(Utils::Environment::systemEnvironment().searchInPath(QtCreatorExecutable)), + dialog(crashHandler, signalName) {} + + const pid_t pid; + const QString creatorInPath; // Backup debugger. + + BacktraceCollector backtraceCollector; + CrashHandlerDialog dialog; + + QStringList restartAppCommandLine; + QStringList restartAppEnvironment; +}; + +CrashHandler::CrashHandler(pid_t pid, const QString &signalName, QObject *parent) + : QObject(parent), d(new CrashHandlerPrivate(pid, signalName, this)) +{ + connect(&d->backtraceCollector, SIGNAL(error(QString)), SLOT(onError(QString))); + connect(&d->backtraceCollector, SIGNAL(backtraceChunk(QString)), SLOT(onBacktraceChunk(QString))); + connect(&d->backtraceCollector, SIGNAL(backtrace(QString)), SLOT(onBacktraceFinished(QString))); + + d->dialog.appendDebugInfo(collectKernelVersionInfo()); + d->dialog.appendDebugInfo(collectLinuxDistributionInfo()); + + if (!collectRestartAppData()) { + d->dialog.disableRestartAppCheckBox(); + if (d->creatorInPath.isEmpty()) + d->dialog.disableDebugAppButton(); + } + + d->dialog.show(); +} + +CrashHandler::~CrashHandler() +{ + delete d; +} + +void CrashHandler::run() +{ + d->backtraceCollector.run(d->pid); +} + +void CrashHandler::onError(const QString &errorMessage) +{ + d->dialog.setToFinalState(); + + QTextStream(stderr) << errorMessage; + const QString text = QLatin1String("There occured a problem providing the backtrace. " + "Please make sure to have the debugger \"gdb\" installed.\n"); + d->dialog.appendDebugInfo(text); + d->dialog.appendDebugInfo(errorMessage); +} + +void CrashHandler::onBacktraceChunk(const QString &chunk) +{ + d->dialog.appendDebugInfo(chunk); + QTextStream(stdout) << chunk; +} + +void CrashHandler::onBacktraceFinished(const QString &backtrace) +{ + d->dialog.setToFinalState(); + + // Select first line of relevant thread. + + // Example debugger output: + // ... + // [Current thread is 1 (Thread 0x7f1c33c79780 (LWP 975))] + // ... + // Thread 1 (Thread 0x7f1c33c79780 (LWP 975)): + // ... + QRegExp rx("\\[Current thread is (\\d+)"); + const int pos = rx.indexIn(backtrace); + if (pos == -1) + return; + const QString threadNumber = rx.cap(1); + const QString textToSelect = QString::fromLatin1("Thread %1").arg(threadNumber); + d->dialog.selectLineWithContents(textToSelect); +} + +void CrashHandler::openBugTracker() +{ + QDesktopServices::openUrl(QUrl(URL_BUGTRACKER)); +} + +bool CrashHandler::collectRestartAppData() +{ + const QString procDir = QString::fromLatin1("/proc/%1").arg(d->pid); + + // Get command line. + // man 5 proc: /proc/[pid]/cmdline + // The command-line arguments appear in this file as a set of strings separated by + // null bytes ('\0'), with a further null byte after the last string. + const QString procCmdFileName = procDir + QLatin1String("/cmdline"); + QList<QByteArray> commandLine = fileContents(procCmdFileName).split('\0'); + if (commandLine.size() < 2) { + qWarning("%s: Unexpected format in file '%s'.\n", Q_FUNC_INFO, qPrintable(procCmdFileName)); + return false; + } + commandLine.removeLast(); + foreach (const QByteArray &item, commandLine) + d->restartAppCommandLine.append(QString::fromLatin1(item)); + + // Get environment. + // man 5 proc: /proc/[pid]/environ + // The entries are separated by null bytes ('\0'), and there may be a null byte at the end. + const QString procEnvFileName = procDir + QLatin1String("/environ"); + QList<QByteArray> environment = fileContents(procEnvFileName).split('\0'); + if (environment.isEmpty()) { + qWarning("%s: Unexpected format in file '%s'.\n", Q_FUNC_INFO, qPrintable(procEnvFileName)); + return false; + } + if (environment.last().isEmpty()) + environment.removeLast(); + foreach (const QByteArray &item, environment) + d->restartAppEnvironment.append(QString::fromLatin1(item)); + + return true; +} + +void CrashHandler::runCommand(QStringList commandLine, QStringList environment, WaitMode waitMode) +{ + // TODO: If QTBUG-2284 is resolved, use QProcess::startDetached() here. + // We can't use QProcess::startDetached because of bug + // + // QTBUG-2284 + // QProcess::startDetached does not support setting an environment for the new process + // + // therefore, we use fork-exec. + + pid_t pid = fork(); + switch (pid) { + case -1: // error + qFatal("%s: fork() failed.", Q_FUNC_INFO); + break; + case 0: { // child + CExecList argv(commandLine); + CExecList envp(environment); + qDebug("Running\n"); + for (int i = 0; argv[i]; ++i) + qDebug(" %s", argv[i]); + if (!environment.isEmpty()) { + qDebug("\nwith environment:\n"); + for (int i = 0; envp[i]; ++i) + qDebug(" %s", envp[i]); + } + + // The standards pipes must be open, otherwise the application will + // receive a SIGPIPE as soon as these are used. + if (freopen("/dev/null", "r", stdin) == 0) + qFatal("%s: freopen() failed for stdin: %s.\n", Q_FUNC_INFO, strerror(errno)); + if (freopen("/dev/null", "w", stdout) == 0) + qFatal("%s: freopen() failed for stdout: %s.\n", Q_FUNC_INFO, strerror(errno)); + if (freopen("/dev/null", "w", stderr) == 0) + qFatal("%s: freopen() failed for stderr: %s.\n.", Q_FUNC_INFO, strerror(errno)); + + if (environment.isEmpty()) + execv(argv[0], argv.data()); + else + execve(argv[0], argv.data(), envp.data()); + _exit(EXIT_FAILURE); + } default: // parent + if (waitMode == WaitForExit) { + while (true) { + int status; + if (waitpid(pid, &status, 0) == -1) { + if (errno == EINTR) // Signal handler of QProcess for SIGCHLD was triggered. + continue; + perror("waitpid() failed unexpectedly"); + } + if (WIFEXITED(status)) { + qDebug("Child exited with exit code %d.", WEXITSTATUS(status)); + break; + } else if (WIFSIGNALED(status)) { + qDebug("Child terminated by signal %d.", WTERMSIG(status)); + break; + } + } + } + break; + } +} + +void CrashHandler::restartApplication() +{ + runCommand(d->restartAppCommandLine, d->restartAppEnvironment, DontWaitForExit); +} + +void CrashHandler::debugApplication() +{ + // User requested to debug the app while our debugger is running. + if (d->backtraceCollector.isRunning()) { + if (!d->dialog.runDebuggerWhileBacktraceNotFinished()) + return; + if (d->backtraceCollector.isRunning()) { + d->backtraceCollector.disconnect(); + d->backtraceCollector.kill(); + d->dialog.setToFinalState(); + d->dialog.appendDebugInfo(tr("\n\nCollecting backtrace aborted by user.")); + QCoreApplication::processEvents(); // Show the last appended output immediately. + } + } + + // Prepare command. + QString executable = d->creatorInPath; + if (!d->restartAppCommandLine.isEmpty()) + executable = d->restartAppCommandLine.at(0); + const QStringList commandLine = QStringList() + << executable + << QLatin1String("-debug") + << QString::number(d->pid); + + QStringList environment; + if (!d->restartAppEnvironment.isEmpty()) + environment = d->restartAppEnvironment; + + // The UI is blocked/frozen anyway, so hide the dialog while debugging. + d->dialog.hide(); + runCommand(commandLine, environment, WaitForExit); + d->dialog.show(); +} diff --git a/src/tools/qtcreatorcrashhandler/crashhandler.h b/src/tools/qtcreatorcrashhandler/crashhandler.h new file mode 100644 index 0000000000..bf4c1991da --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/crashhandler.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CRASHHANDLER_H +#define CRASHHANDLER_H + +#include <QObject> + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +class ApplicationInfo; +class CrashHandlerPrivate; + +class CrashHandler : public QObject +{ + Q_OBJECT +public: + explicit CrashHandler(pid_t pid, const QString &signalName, QObject *parent = 0); + ~CrashHandler(); + + void run(); + +public slots: + void onError(const QString &errorMessage); + void onBacktraceChunk(const QString &chunk); + void onBacktraceFinished(const QString &backtrace); + + void openBugTracker(); + void restartApplication(); + void debugApplication(); + +private: + bool collectRestartAppData(); + + enum WaitMode { WaitForExit, DontWaitForExit }; + static void runCommand(QStringList commandLine, QStringList environment, WaitMode waitMode); + + CrashHandlerPrivate *d; +}; + +#endif // CRASHHANDLER_H diff --git a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp new file mode 100644 index 0000000000..5d23255753 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp @@ -0,0 +1,180 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "crashhandler.h" +#include "crashhandlerdialog.h" +#include "ui_crashhandlerdialog.h" +#include "utils.h" + +#include <app/app_version.h> +#include <utils/checkablemessagebox.h> + +#include <QClipboard> +#include <QIcon> +#include <QSettings> + +static const char SettingsApplication[] = "QtCreator"; +static const char SettingsKeySkipWarningAbortingBacktrace[] + = "CrashHandler/SkipWarningAbortingBacktrace"; + +CrashHandlerDialog::CrashHandlerDialog(CrashHandler *handler, const QString &signalName, + QWidget *parent) : + QDialog(parent), + m_crashHandler(handler), + m_ui(new Ui::CrashHandlerDialog) +{ + m_ui->setupUi(this); + m_ui->introLabel->setTextFormat(Qt::RichText); + m_ui->introLabel->setOpenExternalLinks(true); + m_ui->debugInfoEdit->setReadOnly(true); + m_ui->progressBar->setMinimum(0); + m_ui->progressBar->setMaximum(0); + + const QStyle * const style = QApplication::style(); + m_ui->closeButton->setIcon(style->standardIcon(QStyle::SP_DialogCloseButton)); + + const int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, 0); + QIcon icon = style->standardIcon(QStyle::SP_MessageBoxCritical); + m_ui->iconLabel->setPixmap(icon.pixmap(iconSize, iconSize)); + + connect(m_ui->copyToClipBoardButton, SIGNAL(clicked()), this, SLOT(copyToClipboardClicked())); + connect(m_ui->reportBugButton, SIGNAL(clicked()), m_crashHandler, SLOT(openBugTracker())); + connect(m_ui->debugAppButton, SIGNAL(clicked()), m_crashHandler, SLOT(debugApplication())); + connect(m_ui->closeButton, SIGNAL(clicked()), this, SLOT(close())); + + setApplicationInfo(signalName); +} + +CrashHandlerDialog::~CrashHandlerDialog() +{ + delete m_ui; +} + +bool CrashHandlerDialog::runDebuggerWhileBacktraceNotFinished() +{ + // Check settings. + QSettings settings(QSettings::IniFormat, QSettings::UserScope, + QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR), + QLatin1String(SettingsApplication)); + if (settings.value(QLatin1String(SettingsKeySkipWarningAbortingBacktrace), false).toBool()) + return true; + + // Ask user. + const QString title = tr("Run Debugger And Abort Collecting Backtrace?"); + const QString message = tr( + "<html><head/><body>" + "<p><b>Run the debugger and abort collecting backtrace?</b></p>" + "<p>You have requested to run the debugger while collecting the backtrace was not " + "finished.</p>" + "</body></html>"); + const QString checkBoxText = tr("Do not &ask again."); + bool checkBoxSetting = false; + const QDialogButtonBox::StandardButton button = Utils::CheckableMessageBox::question(this, + title, message, checkBoxText, &checkBoxSetting, + QDialogButtonBox::Yes|QDialogButtonBox::No, QDialogButtonBox::No); + if (checkBoxSetting) + settings.setValue(QLatin1String(SettingsKeySkipWarningAbortingBacktrace), checkBoxSetting); + + return button == QDialogButtonBox::Yes; +} + +void CrashHandlerDialog::setToFinalState() +{ + m_ui->progressBar->hide(); + m_ui->copyToClipBoardButton->setEnabled(true); + m_ui->reportBugButton->setEnabled(true); +} + +void CrashHandlerDialog::disableRestartAppCheckBox() +{ + m_ui->restartAppCheckBox->setDisabled(true); +} + +void CrashHandlerDialog::disableDebugAppButton() +{ + m_ui->debugAppButton->setDisabled(true); +} + +void CrashHandlerDialog::setApplicationInfo(const QString &signalName) +{ + const QString ideName = QLatin1String("Qt Creator"); + const QString title = tr("%1 has closed unexpectedly (Signal \"%2\")").arg(ideName, signalName); + const QString introLabelContents = tr( + "<p><b>%1.</b></p>" + "<p>Please file a <a href='%2'>bug report</a> with the debug information provided below.</p>") + .arg(title, QLatin1String(URL_BUGTRACKER)); + m_ui->introLabel->setText(introLabelContents); + setWindowTitle(title); + + QString revision; +#ifdef IDE_REVISION + revision = tr(" from revision %1").arg(QString::fromLatin1(Core::Constants::IDE_REVISION_STR).left(10)); +#endif + const QString versionInformation = tr( + "%1 %2%3, built on %4 at %5, based on Qt %6 (%7 bit)\n") + .arg(ideName, QLatin1String(Core::Constants::IDE_VERSION_LONG), revision, + QLatin1String(__DATE__), QLatin1String(__TIME__), QLatin1String(QT_VERSION_STR), + QString::number(QSysInfo::WordSize)); + m_ui->debugInfoEdit->append(versionInformation); +} + +void CrashHandlerDialog::appendDebugInfo(const QString &chunk) +{ + m_ui->debugInfoEdit->append(chunk); +} + +void CrashHandlerDialog::selectLineWithContents(const QString &text) +{ + // The selected line will be the first line visible. + + // Go to end. + QTextCursor cursor = m_ui->debugInfoEdit->textCursor(); + cursor.movePosition(QTextCursor::End); + m_ui->debugInfoEdit->setTextCursor(cursor); + + // Find text by searching backwards. + m_ui->debugInfoEdit->find(text, QTextDocument::FindCaseSensitively | QTextDocument::FindBackward); + + // Highlight whole line. + cursor = m_ui->debugInfoEdit->textCursor(); + cursor.select(QTextCursor::LineUnderCursor); + m_ui->debugInfoEdit->setTextCursor(cursor); +} + +void CrashHandlerDialog::copyToClipboardClicked() +{ + QApplication::clipboard()->setText(m_ui->debugInfoEdit->toPlainText()); +} + +void CrashHandlerDialog::close() +{ + if (m_ui->restartAppCheckBox->isEnabled() && m_ui->restartAppCheckBox->isChecked()) + m_crashHandler->restartApplication(); + qApp->quit(); +} diff --git a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.h b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.h new file mode 100644 index 0000000000..fc9ff7921a --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.h @@ -0,0 +1,71 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CRASHHANDLERDIALOG_H +#define CRASHHANDLERDIALOG_H + +#include <QDialog> + +QT_BEGIN_NAMESPACE +class QString; +namespace Ui { +class CrashHandlerDialog; +} +QT_END_NAMESPACE + +class CrashHandler; + +class CrashHandlerDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CrashHandlerDialog(CrashHandler *handler, const QString &signalName, + QWidget *parent = 0); + ~CrashHandlerDialog(); + +public: + void setApplicationInfo(const QString &signalName); + void appendDebugInfo(const QString &chunk); + void selectLineWithContents(const QString &text); + void setToFinalState(); + void disableRestartAppCheckBox(); + void disableDebugAppButton(); + bool runDebuggerWhileBacktraceNotFinished(); + +private slots: + void copyToClipboardClicked(); + void close(); + +private: + CrashHandler *m_crashHandler; + Ui::CrashHandlerDialog *m_ui; +}; + +#endif // CRASHHANDLERDIALOG_H diff --git a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.ui b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.ui new file mode 100644 index 0000000000..9a7b67a003 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.ui @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CrashHandlerDialog</class> + <widget class="QDialog" name="CrashHandlerDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>800</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>500</width> + <height>300</height> + </size> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="QLabel" name="iconLabel"> + <property name="text"> + <string>Icon</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="introLabel"> + <property name="text"> + <string>Some useful information here...</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="value"> + <number>24</number> + </property> + </widget> + </item> + <item> + <widget class="QTextEdit" name="debugInfoEdit"/> + </item> + <item alignment="Qt::AlignRight"> + <widget class="QCheckBox" name="restartAppCheckBox"> + <property name="text"> + <string>&Restart Qt Creator on close</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="copyToClipBoardButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Copy the whole contents to clipboard.</string> + </property> + <property name="text"> + <string>C&opy to clipboard</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="reportBugButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Open the bug tracker web site.</string> + </property> + <property name="text"> + <string>Report this &bug</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="debugAppButton"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="toolTip"> + <string>Debug the application with a new instance of Qt Creator. During debugging the crash handler will be hidden.</string> + </property> + <property name="text"> + <string>Attach and &Debug</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="closeButton"> + <property name="toolTip"> + <string>Quit the handler and the crashed application.</string> + </property> + <property name="text"> + <string>&Close</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp b/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp new file mode 100644 index 0000000000..cc48afa731 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp @@ -0,0 +1,134 @@ +/************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "crashhandlersetup.h" + +#include <QtGlobal> + +#if !defined(QT_NO_DEBUG) && defined(Q_OS_LINUX) +#define BUILD_CRASH_HANDLER +#endif + +#ifdef BUILD_CRASH_HANDLER + +#include <QApplication> +#include <QDebug> +#include <QString> + +#include <stdlib.h> + +#include <errno.h> +#include <signal.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#ifdef Q_WS_X11 +#include <qx11info_x11.h> +#include <X11/Xlib.h> +#endif + +static const char *crashHandlerPathC; +static void *signalHandlerStack; + +extern "C" void signalHandler(int signal) +{ +#ifdef Q_WS_X11 + // Kill window since it's frozen anyway. + if (QX11Info::display()) + close(ConnectionNumber(QX11Info::display())); +#endif + pid_t pid = fork(); + switch (pid) { + case -1: // error + break; + case 0: // child + execl(crashHandlerPathC, crashHandlerPathC, strsignal(signal), (char *) 0); + _exit(EXIT_FAILURE); + default: // parent + waitpid(pid, 0, 0); + _exit(EXIT_FAILURE); + break; + } +} +#endif // BUILD_CRASH_HANDLER + +void setupCrashHandler() +{ +#ifdef BUILD_CRASH_HANDLER + const QString crashHandlerPath = qApp->applicationDirPath() + + QLatin1String("/qtcreator_crash_handler"); + crashHandlerPathC = qstrdup(qPrintable(crashHandlerPath)); + + // Setup an alternative stack for the signal handler. This way we are able to handle SIGSEGV + // even if the normal process stack is exhausted. + stack_t ss; + ss.ss_sp = signalHandlerStack = malloc(SIGSTKSZ); // Usual requirements for alternative signal stack. + if (ss.ss_sp == 0) { + qWarning("Warning: Could not allocate space for alternative signal stack (%s).", Q_FUNC_INFO); + return; + } + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + if (sigaltstack(&ss, 0) == -1) { + qWarning("Warning: Failed to set alternative signal stack (%s).", Q_FUNC_INFO); + return; + } + + // Install signal handler for calling the crash handler. + struct sigaction sa; + if (sigemptyset(&sa.sa_mask) == -1) { + qWarning("Warning: Failed to empty signal set (%s).", Q_FUNC_INFO); + return; + } + sa.sa_handler = &signalHandler; + // SA_RESETHAND - Restore signal action to default after signal handler has been called. + // SA_NODEFER - Don't block the signal after it was triggered (otherwise blocked signals get + // inherited via fork() and execve()). Without this the signal will not be delivered to the + // restarted Qt Creator. + // SA_ONSTACK - Use alternative stack. + sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_ONSTACK; + const int signalsToHandle[] = { SIGILL, SIGFPE, SIGSEGV, SIGBUS, 0 }; + for (int i = 0; signalsToHandle[i]; ++i) { + if (sigaction(signalsToHandle[i], &sa, 0) == -1 ) { + qWarning("Warning: Failed to install signal handler for signal \"%s\" (%s).", + strsignal(signalsToHandle[i]), Q_FUNC_INFO); + } + } +#endif // BUILD_CRASH_HANDLER +} + +void cleanupCrashHandler() +{ +#ifdef BUILD_CRASH_HANDLER + delete[] crashHandlerPathC; + free(signalHandlerStack); +#endif +} diff --git a/src/tools/qtcreatorcrashhandler/crashhandlersetup.h b/src/tools/qtcreatorcrashhandler/crashhandlersetup.h new file mode 100644 index 0000000000..02c50ef230 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/crashhandlersetup.h @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CRASHHANDLERSETUP_H +#define CRASHHANDLERSETUP_H + +void setupCrashHandler(); +void cleanupCrashHandler(); + +#endif // CRASHHANDLERSETUP_H diff --git a/src/plugins/qmldesigner/designercore/include/metainfoparser.h b/src/tools/qtcreatorcrashhandler/main.cpp index f58db3963a..623520cf22 100644 --- a/src/plugins/qmldesigner/designercore/include/metainfoparser.h +++ b/src/tools/qtcreatorcrashhandler/main.cpp @@ -27,43 +27,42 @@ ** ****************************************************************************/ -#ifndef METAINFOPARSER_H -#define METAINFOPARSER_H +#include "crashhandler.h" +#include "utils.h" -#include "corelib_global.h" -#include <QXmlStreamReader> -#include <QString> +#include <QApplication> #include <QFile> -#include <metainfo.h> - -namespace QmlDesigner { - -class ItemLibraryEntry; - -namespace Internal { +#include <QProcess> +#include <QString> +#include <QStyle> +#include <QTextStream> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> -class TEST_CORESHARED_EXPORT MetaInfoParser +// Called by signal handler of qtcreator. +// Usage: $0 <name of signal causing the crash> +int main(int argc, char *argv[]) { -public: - MetaInfoParser(const MetaInfo &metaInfo); - - void parseFile(const QString &path); + QApplication app(argc, argv); + app.setApplicationName(QLatin1String(APPLICATION_NAME)); + app.setWindowIcon(QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical)); -protected: - void errorHandling(QXmlStreamReader &reader, QFile &file); - void tokenHandler(QXmlStreamReader &reader); - void metaInfoHandler(QXmlStreamReader &reader); - void handleMetaInfoElement(QXmlStreamReader &reader); - void handleNodeElement(QXmlStreamReader &reader); - void handleNodeItemLibraryEntryElement(QXmlStreamReader &reader, const QString &className, const QIcon &icon); - void handleItemLibraryEntryPropertyElement(QXmlStreamReader &reader, ItemLibraryEntry &itemLibraryEntry); - void handleItemLibraryEntryQmlElement(QXmlStreamReader &reader, ItemLibraryEntry &itemLibraryEntry); + // Check usage. + Q_PID parentPid = getppid(); + QString parentExecutable = QFile::symLinkTarget(QString::fromLatin1("/proc/%1/exe") + .arg(QString::number(parentPid))); + if (argc > 2 || !parentExecutable.contains("qtcreator")) { + QTextStream err(stderr); + err << QString::fromLatin1("This crash handler will be called by Qt Creator itself. " + "Do not call this manually.\n"); + return EXIT_FAILURE; + } -private: - MetaInfo m_metaInfo; -}; + // Run. + CrashHandler *crashHandler = new CrashHandler(parentPid, app.arguments().at(1)); + crashHandler->run(); + return app.exec(); } -} -#endif // METAINFOPARSER_H diff --git a/src/tools/qtcreatorcrashhandler/qtcreatorcrashhandler.pro b/src/tools/qtcreatorcrashhandler/qtcreatorcrashhandler.pro new file mode 100644 index 0000000000..bfcb41e303 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/qtcreatorcrashhandler.pro @@ -0,0 +1,31 @@ +include(../../../qtcreator.pri) + +TARGET = qtcreator_crash_handler +DESTDIR = $$IDE_BIN_PATH + +CONFIG -= app_bundle +TEMPLATE = app + +SOURCES += \ + main.cpp \ + backtracecollector.cpp \ + crashhandlerdialog.cpp \ + crashhandler.cpp \ + utils.cpp \ + ../../libs/utils/checkablemessagebox.cpp \ + ../../libs/utils/environment.cpp + + +HEADERS += \ + backtracecollector.h \ + crashhandlerdialog.h \ + crashhandler.h \ + utils.h \ + ../../libs/utils/checkablemessagebox.h \ + ../../libs/utils/environment.h + +FORMS += \ + crashhandlerdialog.ui + +target.path = /bin +INSTALLS += target diff --git a/src/tools/qtcreatorcrashhandler/qtcreatorcrashhandler.qbs b/src/tools/qtcreatorcrashhandler/qtcreatorcrashhandler.qbs new file mode 100644 index 0000000000..35d6187d56 --- /dev/null +++ b/src/tools/qtcreatorcrashhandler/qtcreatorcrashhandler.qbs @@ -0,0 +1,33 @@ +import qbs.base 1.0 +import "../QtcTool.qbs" as QtcTool + +QtcTool { + name: "qtcreator_crash_handler" + condition: qbs.targetOS == "linux" && qbs.buildVariant == "debug" + + cpp.includePaths: [ + buildDirectory, + "../../libs" + ] + + Depends { name: "cpp" } + Depends { name: "Qt.widgets" } + Depends { name: "app_version_header" } + + files: [ + "../../libs/utils/checkablemessagebox.cpp", + "../../libs/utils/checkablemessagebox.h", + "../../libs/utils/environment.cpp", + "../../libs/utils/environment.h", + "backtracecollector.cpp", + "backtracecollector.h", + "crashhandler.cpp", + "crashhandler.h", + "crashhandlerdialog.cpp", + "crashhandlerdialog.h", + "crashhandlerdialog.ui", + "main.cpp", + "utils.cpp", + "utils.h" + ] +} diff --git a/tests/auto/icheckbuild/tst_icheckbuild.cpp b/src/tools/qtcreatorcrashhandler/utils.cpp index f3a9fd00ab..2fe505b1f8 100644 --- a/tests/auto/icheckbuild/tst_icheckbuild.cpp +++ b/src/tools/qtcreatorcrashhandler/utils.cpp @@ -27,23 +27,17 @@ ** ****************************************************************************/ -#include <QtTest> -#include "ichecklib.h" -#include <QDebug> - -class tst_icheckbuild : public QObject -{ - Q_OBJECT +#include "utils.h" -private slots: - void doTests(); -}; +#include <QDebug> +#include <QFile> -void tst_icheckbuild::doTests() +QByteArray fileContents(const QString &filePath) { - qDebug() << "icheck build was successful"; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning("Warning: Could not open '%s'.", qPrintable(filePath)); + return QByteArray(); + } + return file.readAll(); } - -QTEST_MAIN(tst_icheckbuild) - -#include "tst_icheckbuild.moc" diff --git a/tests/manual/appwizards/qmlimportscenario_02/subfolder2/no/trolltech/QmlModule01/QmlComponent01.qml b/src/tools/qtcreatorcrashhandler/utils.h index dc3c1e0f54..0232db5ca1 100644 --- a/tests/manual/appwizards/qmlimportscenario_02/subfolder2/no/trolltech/QmlModule01/QmlComponent01.qml +++ b/src/tools/qtcreatorcrashhandler/utils.h @@ -27,19 +27,15 @@ ** ****************************************************************************/ -import Qt 4.7 +#ifndef UTILS_H +#define UTILS_H -Rectangle { - color: "#ddffdd" +#include <QByteArray> +#include <QString> - Image { - source: "apple.svg" - anchors.right: parent.right - anchors.bottom: parent.bottom - } +const char APPLICATION_NAME[] = "Qt Creator Crash Handler"; +const char URL_BUGTRACKER[] = "https://bugreports.qt-project.org/"; - Text { - text: "QmlComponent01" - font.pointSize: 14 - } -} +QByteArray fileContents(const QString &filePath); + +#endif // UTILS_H diff --git a/src/tools/sdktool/sdktool.qbs b/src/tools/sdktool/sdktool.qbs index 1ecea9e4c1..7d8e571a90 100644 --- a/src/tools/sdktool/sdktool.qbs +++ b/src/tools/sdktool/sdktool.qbs @@ -4,17 +4,16 @@ import "../QtcTool.qbs" as QtcTool QtcTool { name: "sdktool" - cpp.includePaths: [buildDirectory] - cpp.defines: base.concat([qbs.targetOS === "mac" - ? 'DATA_PATH="."' : 'DATA_PATH="../share/qtcreator"']) - Depends { name: "cpp" } Depends { name: "Qt.core" } Depends { name: "Utils" } Depends { name: "app_version_header" } + cpp.includePaths: "../../libs" + cpp.defines: base.concat([qbs.targetOS === "mac" + ? 'DATA_PATH="."' : 'DATA_PATH="../share/qtcreator"']) + files: [ - "main.cpp", "addkeysoperation.cpp", "addkeysoperation.h", "addkitoperation.cpp", @@ -29,8 +28,9 @@ QtcTool { "findvalueoperation.h", "getoperation.cpp", "getoperation.h", - "operation.h", + "main.cpp", "operation.cpp", + "operation.h", "rmkeysoperation.cpp", "rmkeysoperation.h", "rmkitoperation.cpp", @@ -40,6 +40,6 @@ QtcTool { "rmtoolchainoperation.cpp", "rmtoolchainoperation.h", "settings.cpp", - "settings.h" + "settings.h", ] } diff --git a/src/tools/tools.pro b/src/tools/tools.pro index 1f499584d5..3a48a7918f 100644 --- a/src/tools/tools.pro +++ b/src/tools/tools.pro @@ -2,6 +2,7 @@ TEMPLATE = subdirs SUBDIRS = qtpromaker \ qmlpuppet \ + ../plugins/cpaster/frontend \ sdktool win32 { @@ -21,5 +22,11 @@ win32 { QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH) !isEmpty(QT_BREAKPAD_ROOT_PATH) { SUBDIRS += qtcrashhandler +} else { + linux-* { + # Build only in debug mode. + debug_and_release|CONFIG(debug, debug|release) { + SUBDIRS += qtcreatorcrashhandler + } + } } - diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 4bb160e3d4..449876b36e 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -9,7 +9,6 @@ SUBDIRS += \ environment \ fakevim \ generichighlighter \ -# icheckbuild \ profilewriter \ ioutils \ qtcprocess \ diff --git a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp index 7e340d1202..c81c9cd6ab 100644 --- a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp +++ b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp @@ -116,6 +116,7 @@ private Q_SLOTS: void functionBodyAndBraces4(); void constructor1(); void constructor2(); + void constructor3(); void caseBody1(); void caseBody2(); void caseBody3(); @@ -1875,6 +1876,42 @@ void tst_CodeFormatter::constructor2() checkIndent(data); } +void tst_CodeFormatter::constructor3() +{ + QList<Line> data; + data << Line("class Foo {") + << Line(" Foo() : _a{0}, _b{1, {2, {3, \"foo\"}, 3}}") + << Line(" {") + << Line(" _b = 0") + << Line(" }") + << Line(" int _a;") + << Line(" Foo()") + << Line(" ~ : _foo{1},") + << Line(" ~ _bar{2},") + << Line(" ~ _carooooo(") + << Line(" ~ foo() + 12),") + << Line(" ~ _carooooo{foo(),") + << Line(" ~ 12}") + << Line(" {") + << Line(" _b = 0") + << Line(" }") + << Line(" int _b;") + << Line(" Foo()") + << Line(" ~ : _foo{1}") + << Line(" ~ , _bar{2}") + << Line(" ~ , _carooooo{") + << Line(" ~ foo() + 12}") + << Line(" ~ , _carooooo{foo(),") + << Line(" ~ 12}") + << Line(" {") + << Line(" _b = 0") + << Line(" }") + << Line("};") + ; + CppCodeStyleSettings codeStyle; + checkIndent(data); +} + void tst_CodeFormatter::caseBody1() { QList<Line> data; diff --git a/tests/auto/cplusplus/cxx11/data/aliasDecl.1.cpp b/tests/auto/cplusplus/cxx11/data/aliasDecl.1.cpp new file mode 100644 index 0000000000..99384acaa1 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/aliasDecl.1.cpp @@ -0,0 +1,4 @@ +using Foo = int; +using Bar = std::vector<int>::value_type; +using A [[foo]] = const float; +using B alignas(void*) = C *; diff --git a/tests/auto/cplusplus/cxx11/data/alignofAlignas.1.cpp b/tests/auto/cplusplus/cxx11/data/alignofAlignas.1.cpp new file mode 100644 index 0000000000..5ba43661ed --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/alignofAlignas.1.cpp @@ -0,0 +1,2 @@ +int i = alignof(int); +int t = alignof(C::foo) * 7 + alignof(Foo *); diff --git a/tests/auto/cplusplus/cxx11/data/braceInitializers.1.cpp b/tests/auto/cplusplus/cxx11/data/braceInitializers.1.cpp new file mode 100644 index 0000000000..94e8fae241 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/braceInitializers.1.cpp @@ -0,0 +1,18 @@ +Type var1 = { 1, 2, 3}; +Type var2{1, 2, 3}; +Type var3({1, 2, 3}); + +class C { + Type var1 = {1, 2, 3}; + Type var2{1, 2, 3}; +}; + +void main() { + var1 = {1, 2, {3, 4} }; + Type var2{{1, 2, 3}, 4}; + var3 += {1, 2}; +} + +T foo() { + return {1, 2, {"foo", 7}}; +} diff --git a/tests/auto/cplusplus/cxx11/data/braceInitializers.1.errors.txt b/tests/auto/cplusplus/cxx11/data/braceInitializers.1.errors.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/braceInitializers.1.errors.txt diff --git a/tests/auto/cplusplus/cxx11/data/braceInitializers.2.cpp b/tests/auto/cplusplus/cxx11/data/braceInitializers.2.cpp new file mode 100644 index 0000000000..4dc183d8f5 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/braceInitializers.2.cpp @@ -0,0 +1,7 @@ +class C { + C() : _x{12}, _y({12}) {} + C(int i) : _x{{{12, 2}, {"foo"}}, {bar}}... {} + C(int i) : _x({{12, 2}, {"foo"}}, {bar})... {} +}; + +void foo(int i = {1, 2, 3}); diff --git a/tests/auto/cplusplus/cxx11/data/braceInitializers.3.cpp b/tests/auto/cplusplus/cxx11/data/braceInitializers.3.cpp new file mode 100644 index 0000000000..5105b4690c --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/braceInitializers.3.cpp @@ -0,0 +1,6 @@ +auto x = int{}; +auto y = Foo{}; +auto z = typename Foo<T>{}; + +auto d = new C(1, abc...); +auto e = new C{1, 2, 3}; diff --git a/tests/auto/cplusplus/cxx11/data/declType.1.cpp b/tests/auto/cplusplus/cxx11/data/declType.1.cpp new file mode 100644 index 0000000000..fd86589abf --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/declType.1.cpp @@ -0,0 +1,11 @@ +template <class T, class R> +auto foo(T t, R r) -> decltype(t + r) +{} + +int x; +decltype(x) foo; +decltype(x) foo(); + +// this does not work yet, as decltype is only parsed as a simple-specifier +// and not also as a nested-name-specifier +//decltype(vec)::value_type a; diff --git a/tests/auto/cplusplus/cxx11/data/defaultdeleteInitializer.1.cpp b/tests/auto/cplusplus/cxx11/data/defaultdeleteInitializer.1.cpp new file mode 100644 index 0000000000..7ec9e9b91e --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/defaultdeleteInitializer.1.cpp @@ -0,0 +1,8 @@ +class C { + C() = default; + C(const C &) = delete; + C &operator=(const C &) = default; + + void foo() = delete; + template <class T> void bar(T) = delete; +}; diff --git a/tests/auto/cplusplus/cxx11/data/enums.1.cpp b/tests/auto/cplusplus/cxx11/data/enums.1.cpp new file mode 100644 index 0000000000..c8cd725ad0 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/enums.1.cpp @@ -0,0 +1,11 @@ +enum { A, B }; +enum : int; +enum : int { A, B }; +enum Foo1 { A, B }; +enum Foo2 : int; +enum Foo3 : int { A, B }; +enum class Foo4 : int; +enum struct Foo5; +enum class Foo6 { A, B }; +enum struct Foo7 { A, B }; +enum struct Foo8 : long long; diff --git a/tests/auto/cplusplus/cxx11/data/packExpansion.1.cpp b/tests/auto/cplusplus/cxx11/data/packExpansion.1.cpp new file mode 100644 index 0000000000..eca6796e38 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/packExpansion.1.cpp @@ -0,0 +1,4 @@ +template <class ... Args> +int foo(Args args...) { + bar(args..., {args...}, e, f); +} diff --git a/tests/auto/cplusplus/cxx11/data/rangeFor.1.cpp b/tests/auto/cplusplus/cxx11/data/rangeFor.1.cpp new file mode 100644 index 0000000000..3a9a2e7d4f --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/rangeFor.1.cpp @@ -0,0 +1,5 @@ +int main() { + for (int x : {1, 2, 3}) {} + for (int x : foo) ; + for (int& x : array) x += 2; +} diff --git a/tests/auto/cplusplus/cxx11/data/refQualifier.1.cpp b/tests/auto/cplusplus/cxx11/data/refQualifier.1.cpp new file mode 100644 index 0000000000..172ede9ae0 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/refQualifier.1.cpp @@ -0,0 +1,21 @@ +void foo() noexcept; +class C { + void foo() const noexcept final override; + void foo() const & noexcept final override; + void foo() const && noexcept final override; + auto foo() const noexcept -> void final override; + auto foo() const & noexcept -> void final override; + auto foo() const && noexcept -> void final override; + void foo(); + void foo() &; + void foo() &&; +}; + +int main() { + void (C::*p)() const; + void (C::*p)() const &; + void (C::*p)() const &&; + void (C::*p)(); + void (C::*p)() &; + void (C::*p)() &&; +} diff --git a/tests/auto/cplusplus/cxx11/data/templateGreaterGreater.1.cpp b/tests/auto/cplusplus/cxx11/data/templateGreaterGreater.1.cpp new file mode 100644 index 0000000000..c07d0a0e4f --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/templateGreaterGreater.1.cpp @@ -0,0 +1,10 @@ +template <class i, int j = 1> +class Y {}; +template <int i> +class X {}; + +Y<X<6>, 7> x; +Y<X<1>> y; +X< (1 >> 2) > z; +auto a = static_cast<X<1>>(X<1>()); + diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp index 31657dc86c..7f87a4e170 100644 --- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp +++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp @@ -39,11 +39,13 @@ using namespace CPlusPlus; #define VERIFY_ERRORS() \ do { \ - QFile e(testdata(errorFile)); \ QByteArray expectedErrors; \ - if (e.open(QFile::ReadOnly)) \ - expectedErrors = QTextStream(&e).readAll().toUtf8(); \ - QCOMPARE(errors, expectedErrors); \ + if (!errorFile.isEmpty()) { \ + QFile e(testdata(errorFile)); \ + if (e.open(QFile::ReadOnly)) \ + expectedErrors = QTextStream(&e).readAll().toUtf8(); \ + } \ + QCOMPARE(QString::fromLatin1(errors), QString::fromLatin1(expectedErrors)); \ } while (0) @@ -106,6 +108,8 @@ class tst_cxx11: public QObject doc->translationUnit()->setCxxOxEnabled(true); doc->check(); doc->control()->setDiagnosticClient(0); + } else { + qWarning() << "could not read file" << fileName; } return doc; } @@ -114,12 +118,8 @@ private Q_SLOTS: // // checks for the syntax // - void inlineNamespace_data(); - void inlineNamespace(); - void staticAssert(); - void staticAssert_data(); - void noExcept(); - void noExcept_data(); + void parse_data(); + void parse(); // // checks for the semantic @@ -128,15 +128,29 @@ private Q_SLOTS: }; -void tst_cxx11::inlineNamespace_data() +void tst_cxx11::parse_data() { QTest::addColumn<QString>("file"); QTest::addColumn<QString>("errorFile"); QTest::newRow("inlineNamespace.1") << "inlineNamespace.1.cpp" << "inlineNamespace.1.errors.txt"; + QTest::newRow("staticAssert.1") << "staticAssert.1.cpp" << "staticAssert.1.errors.txt"; + QTest::newRow("noExcept.1") << "noExcept.1.cpp" << "noExcept.1.errors.txt"; + QTest::newRow("braceInitializers.1") << "braceInitializers.1.cpp" << "braceInitializers.1.errors.txt"; + QTest::newRow("braceInitializers.2") << "braceInitializers.2.cpp" << ""; + QTest::newRow("braceInitializers.3") << "braceInitializers.3.cpp" << ""; + QTest::newRow("defaultdeleteInitializer.1") << "defaultdeleteInitializer.1.cpp" << ""; + QTest::newRow("refQualifier.1") << "refQualifier.1.cpp" << ""; + QTest::newRow("alignofAlignas.1") << "alignofAlignas.1.cpp" << ""; + QTest::newRow("rangeFor.1") << "rangeFor.1.cpp" << ""; + QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << ""; + QTest::newRow("enums.1") << "enums.1.cpp" << ""; + QTest::newRow("templateGreaterGreater.1") << "templateGreaterGreater.1.cpp" << ""; + QTest::newRow("packExpansion.1") << "packExpansion.1.cpp" << ""; + QTest::newRow("declType.1") << "declType.1.cpp" << ""; } -void tst_cxx11::inlineNamespace() +void tst_cxx11::parse() { QFETCH(QString, file); QFETCH(QString, errorFile); @@ -166,49 +180,5 @@ void tst_cxx11::inlineNamespaceLookup() QCOMPARE(results.size(), 1); // the symbol is visible from the global scope } -void tst_cxx11::staticAssert_data() -{ - QTest::addColumn<QString>("file"); - QTest::addColumn<QString>("errorFile"); - - QTest::newRow("staticAssert.1") << "staticAssert.1.cpp" << "staticAssert.1.errors.txt"; -} - -void tst_cxx11::staticAssert() -{ - QFETCH(QString, file); - QFETCH(QString, errorFile); - - QByteArray errors; - Document::Ptr doc = document(file, &errors); - - if (! qgetenv("DEBUG").isNull()) - printf("%s\n", errors.constData()); - - VERIFY_ERRORS(); -} - -void tst_cxx11::noExcept_data() -{ - QTest::addColumn<QString>("file"); - QTest::addColumn<QString>("errorFile"); - - QTest::newRow("noExcept.1") << "noExcept.1.cpp" << "noExcept.1.errors.txt"; -} - -void tst_cxx11::noExcept() -{ - QFETCH(QString, file); - QFETCH(QString, errorFile); - - QByteArray errors; - Document::Ptr doc = document(file, &errors); - - if (! qgetenv("DEBUG").isNull()) - printf("%s\n", errors.constData()); - - VERIFY_ERRORS(); -} - QTEST_APPLESS_MAIN(tst_cxx11) #include "tst_cxx11.moc" diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp index dc1f765ee7..0cc1381103 100644 --- a/tests/auto/cplusplus/findusages/tst_findusages.cpp +++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp @@ -77,6 +77,8 @@ class tst_FindUsages: public QObject private Q_SLOTS: void inlineMethod(); + void lambdaCaptureByValue(); + void lambdaCaptureByReference(); void shadowedNames_1(); void shadowedNames_2(); @@ -125,6 +127,70 @@ void tst_FindUsages::inlineMethod() QCOMPARE(findUsages.references().size(), 2); } +void tst_FindUsages::lambdaCaptureByValue() +{ + const QByteArray src = "\n" + "void f() {\n" + " int test;\n" + " [test] { ++test; };\n" + "}\n"; + Document::Ptr doc = Document::create("lambdaCaptureByValue"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Snapshot snapshot; + snapshot.insert(doc); + + Function *f = doc->globalSymbolAt(0)->asFunction(); + QVERIFY(f); + QCOMPARE(f->memberCount(), 1U); + Block *b = f->memberAt(0)->asBlock(); + QCOMPARE(b->memberCount(), 2U); + Declaration *d = b->memberAt(0)->asDeclaration(); + QVERIFY(d); + QCOMPARE(d->name()->identifier()->chars(), "test"); + + FindUsages findUsages(src, doc, snapshot); + findUsages(d); + QCOMPARE(findUsages.usages().size(), 3); +} + +void tst_FindUsages::lambdaCaptureByReference() +{ + const QByteArray src = "\n" + "void f() {\n" + " int test;\n" + " [&test] { ++test; };\n" + "}\n"; + Document::Ptr doc = Document::create("lambdaCaptureByReference"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Snapshot snapshot; + snapshot.insert(doc); + + Function *f = doc->globalSymbolAt(0)->asFunction(); + QVERIFY(f); + QCOMPARE(f->memberCount(), 1U); + Block *b = f->memberAt(0)->asBlock(); + QCOMPARE(b->memberCount(), 2U); + Declaration *d = b->memberAt(0)->asDeclaration(); + QVERIFY(d); + QCOMPARE(d->name()->identifier()->chars(), "test"); + + FindUsages findUsages(src, doc, snapshot); + findUsages(d); + QCOMPARE(findUsages.usages().size(), 3); +} + void tst_FindUsages::shadowedNames_1() { const QByteArray src = "\n" diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index 1b30a95a04..9644621cf7 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -486,7 +486,7 @@ void tst_Semantic::template_instance_1() FullySpecifiedType genTy = DeprecatedGenTemplateInstance::instantiate(templId, decl, control); Overview oo; - oo.setShowReturnTypes(true); + oo.showReturnTypes = true; const QString genDecl = oo.prettyType(genTy); QCOMPARE(genDecl, QString::fromLatin1("void (const int &)")); diff --git a/tests/auto/cplusplus/typeprettyprinter/tst_typeprettyprinter.cpp b/tests/auto/cplusplus/typeprettyprinter/tst_typeprettyprinter.cpp index 3b678c2210..01af142187 100644 --- a/tests/auto/cplusplus/typeprettyprinter/tst_typeprettyprinter.cpp +++ b/tests/auto/cplusplus/typeprettyprinter/tst_typeprettyprinter.cpp @@ -208,7 +208,7 @@ void tst_TypePrettyPrinter::basic() QFETCH(QString, result); Overview o; - o.setShowReturnTypes(true); + o.showReturnTypes = true; TypePrettyPrinter pp(&o); QCOMPARE(pp(type, name), result); } diff --git a/tests/auto/icheckbuild/icheckbuild.pro b/tests/auto/icheckbuild/icheckbuild.pro deleted file mode 100644 index e7ea6b4b96..0000000000 --- a/tests/auto/icheckbuild/icheckbuild.pro +++ /dev/null @@ -1,20 +0,0 @@ -CONFIG += testcase - -include(../../../qtcreator.pri) -include($$IDE_SOURCE_TREE/src/libs/cplusplus/cplusplus.pri) -include($$IDE_SOURCE_TREE/src/plugins/cpptools/cpptools.pri) - -QT += testlib - -DEFINES += ICHECK_BUILD ICHECK_APP_BUILD - -INCLUDEPATH += $$IDE_SOURCE_TREE/src/libs/cplusplus -INCLUDEPATH += $$IDE_SOURCE_TREE/src/plugins -LIBS += $$IDE_SOURCE_TREE/lib/qtcreator/plugins - -HEADERS += ichecklib.h \ - ichecklib_global.h \ - parsemanager.h -SOURCES += ichecklib.cpp \ - parsemanager.cpp \ - tst_icheckbuild.cpp diff --git a/tests/auto/icheckbuild/ichecklib.cpp b/tests/auto/icheckbuild/ichecklib.cpp deleted file mode 100644 index 30d017dd87..0000000000 --- a/tests/auto/icheckbuild/ichecklib.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "ichecklib.h" -#include "parsemanager.h" -#include <QCoreApplication> -#include <QString> -#include <QStringList> -#include <iostream> -#include <QDebug> -#include <QDir> -#include <QFile> -#include <QFileInfo> -#include <QProcess> - -QStringList getQTIncludePath() -{ - QStringList ret; - QStringList processevironment = QProcess::systemEnvironment(); - foreach(QString item, processevironment){ - if(item.indexOf("QTDIR=") == 0){ - QString qtpath = item.remove("QTDIR="); - ret << qtpath + "/include"; - ret << qtpath + "/include/ActiveQt"; - ret << qtpath + "/include/phonon"; - ret << qtpath + "/include/phonon_compat"; - ret << qtpath + "/include/Qt"; - ret << qtpath + "/include/Qt3Support"; - ret << qtpath + "/include/QtAssistant"; - ret << qtpath + "/include/QtCore"; - ret << qtpath + "/include/QtDBus"; - ret << qtpath + "/include/QtDeclarative"; - ret << qtpath + "/include/QtDesigner"; - ret << qtpath + "/include/QtGui"; - ret << qtpath + "/include/QtHelp"; - ret << qtpath + "/include/QtMultimedia"; - ret << qtpath + "/include/QtNetwork"; - ret << qtpath + "/include/QtOpenGL"; - ret << qtpath + "/include/QtOpenVG"; - ret << qtpath + "/include/QtScript"; - ret << qtpath + "/include/QtScriptTools"; - ret << qtpath + "/include/QtSql"; - ret << qtpath + "/include/QtSvg"; - ret << qtpath + "/include/QtTest"; - ret << qtpath + "/include/QtUiTools"; - ret << qtpath + "/include/QtWebKit"; - ret << qtpath + "/include/QtXml"; - ret << qtpath + "/include/QtXmlPatterns"; - break; - } - } - return ret; -} - -ICheckLib::ICheckLib() -: pParseManager(0) -{ -} - -void ICheckLib::ParseHeader(const QStringList& includePath, const QStringList& filelist) -{ - if(pParseManager) - delete pParseManager; - pParseManager = 0; - pParseManager = new CPlusPlus::ParseManager(); - pParseManager->setIncludePath(includePath); - pParseManager->parse(filelist); -} - -bool ICheckLib::check(const ICheckLib& ichecklib /*ICheckLib from interface header*/, QString outputfile) -{ - if(pParseManager){ - CPlusPlus::ParseManager* cpparsemanager = ichecklib.pParseManager; - return pParseManager->checkAllMetadatas(cpparsemanager, outputfile); - } - return false; -} - -QStringList ICheckLib::getErrorMsg() -{ - QStringList ret; - if(pParseManager){ - ret.append(pParseManager->getErrorMsg()); - } - else - ret << "no file was parsed."; - return ret; -} diff --git a/tests/auto/icheckbuild/ichecklib_global.h b/tests/auto/icheckbuild/ichecklib_global.h deleted file mode 100644 index de2ba03a08..0000000000 --- a/tests/auto/icheckbuild/ichecklib_global.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef ICHECKLIB_GLOBAL_H -#define ICHECKLIB_GLOBAL_H - -#include <qglobal.h> - - -#ifdef ICHECK_APP_BUILD -# define ICHECKLIBSHARED_EXPORT -#else -# if defined(ICHECKLIB_LIBRARY) -# define ICHECKLIBSHARED_EXPORT Q_DECL_EXPORT -# else -# define ICHECKLIBSHARED_EXPORT Q_DECL_IMPORT -# endif -#endif - -#endif // ICHECKLIB_GLOBAL_H diff --git a/tests/auto/icheckbuild/parsemanager.cpp b/tests/auto/icheckbuild/parsemanager.cpp deleted file mode 100644 index 6184856dc8..0000000000 --- a/tests/auto/icheckbuild/parsemanager.cpp +++ /dev/null @@ -1,1528 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "parsemanager.h" -#include "cplusplus/CppDocument.h" -#include "Control.h" -#include "Literals.h" -#include "Overview.h" -#include "Scope.h" -#include "TranslationUnit.h" -#include "AST.h" -#include "Symbols.h" -#include "Bind.h" -#include <QDebug> -#include "Name.h" -#include "cpptools/cppmodelmanager.h" -#include <QTextStream> - -using namespace CppTools; -using namespace CppTools::Internal; - - -using namespace CPlusPlus; - -//<------------------------------------------------------- Compare function for the internal structures -/********************************** -Compares function with function -with return type, function name -and their arguments and arguments -types. -**********************************/ -bool FUNCTIONITEM::isEqualTo(FUNCTIONITEM *cpfct, bool ignoreName/* = true*/) -{ - if(ignoreName) - return function->isEqualTo(cpfct->function, true); - return function->isEqualTo(cpfct->function); -} - -/***************************************************************** -Compares two property regarding -of their function definition, -type definition, function arguments -and function types. - -Q_PROPERTY( ConnectionState state READ state NOTIFY stateChanged); -******************************************************************/ -bool PROPERTYITEM::isEqualTo(PROPERTYITEM *cpppt) -{ - if (!ast->type_id || !cpppt->ast->type_id) - return false; - if (type != cpppt->type) - return false; - - if (!ast->property_name || !ast->property_name->name || !ast->property_name->name->identifier()) - return false; - QString thistypename = ast->property_name->name->identifier()->chars(); - - if (!cpppt->ast->property_name || !cpppt->ast->property_name->name || !cpppt->ast->property_name->name->identifier()) - return false; - QString cppttypename = cpppt->ast->property_name->name->identifier()->chars(); - if(thistypename != cppttypename) - return false; - - if ((this->readAst == 0) != (cpppt->readAst == 0)) - return false; - if((this->writeAst == 0) != (cpppt->writeAst == 0)) - return false; - if((this->resetAst == 0) != (cpppt->resetAst == 0)) - return false; - if((this->notifyAst == 0) != (cpppt->notifyAst == 0)) - return false; - //check for read function - if(this->readAst){ - if(!this->readFct || !cpppt->readFct) - return false; - if(!this->readFct->isEqualTo(cpppt->readFct)) - return false; - } - //check for write function - if(this->writeAst){ - if(!this->writeFct || !cpppt->writeFct) - return false; - if(!this->writeFct->isEqualTo(cpppt->writeFct)) - return false; - } - //check for reset function - if(this->resetAst){ - if(!this->resetFct || !cpppt->resetFct) - return false; - if(!this->resetFct->isEqualTo(cpppt->resetFct)) - return false; - } - //check for notify function - if(this->notifyAst){ - if(!this->notifyFct || !cpppt->notifyFct) - return false; - if(!this->notifyFct->isEqualTo(cpppt->notifyFct)) - return false; - } - return true; -} - -/***************************************************************** -Compares two enums regarding -of their values created by the getEnumValueStringList function. -*****************************************************************/ -bool QENUMITEM::isEqualTo(QENUMITEM *cpenum) -{ - if(this->values.count() != cpenum->values.count()) - return false; - foreach(QString str, this->values){ - if(!cpenum->values.contains(str)) - return false; - } - return true; -} - -/***************************************************************** -Compares two flags regarding -of their enum definitions and their -values created by the getEnumValueStringList function. -*****************************************************************/ -bool QFLAGITEM::isEqualTo(QFLAGITEM *cpflag) -{ - if(this->enumvalues.count() != cpflag->enumvalues.count()) - return false; - foreach(QString str, this->enumvalues){ - if(!cpflag->enumvalues.contains(str)) - return false; - } - return true; -} - - - -ParseManager::ParseManager() -: pCppPreprocessor(0) -{ - -} - -ParseManager::~ParseManager() -{ - if(pCppPreprocessor) - delete pCppPreprocessor; - if(::m_resultFile){ - ::m_resultFile->close(); - delete ::m_resultFile; - ::m_resultFile = 0; - } -} - -/************************************** -Function for setting the include -Paths -**************************************/ -void ParseManager::setIncludePath(const QStringList &includePath) -{ - m_includePaths = includePath; -} - -/************************************** -public Function that starts the parsing -all of the files in the sourceFiles -string list. -**************************************/ -void ParseManager::parse(const QStringList &sourceFiles) -{ - m_errormsgs.clear(); - if(pCppPreprocessor){ - delete pCppPreprocessor; - pCppPreprocessor = 0; - } - - if (! sourceFiles.isEmpty()) { - m_strHeaderFile = sourceFiles[0]; - pCppPreprocessor = new CppTools::Internal::CppPreprocessor(QPointer<CPlusPlus::ParseManager>(this)); - pCppPreprocessor->setIncludePaths(m_includePaths); - pCppPreprocessor->setFrameworkPaths(m_frameworkPaths); - parse(pCppPreprocessor, sourceFiles); - } -} - -/********************************************* -private function that prepare the filelist -to parse and starts the parser. -*********************************************/ -void ParseManager::parse(CppTools::Internal::CppPreprocessor *preproc, - const QStringList &files) -{ - if (files.isEmpty()) - return; - - //check if file is C++ header file - QStringList headers; - foreach (const QString &file, files) { - const QFileInfo fileInfo(file); - QString ext = fileInfo.suffix(); - if (ext.toLower() == "h") - headers.append(file); - } - - foreach (const QString &file, files) { - preproc->snapshot.remove(file); - } - preproc->setTodo(headers); - QString conf = QLatin1String("<configuration>"); - - preproc->run(conf); - for (int i = 0; i < headers.size(); ++i) { - QString fileName = headers.at(i); - preproc->run(fileName); - } -} - -//This function creates a class list for each class and its base classes in -//the header file that needs to be checked. -//e.g. -// Cl1 Cl2 -// __|__ __|__ -// | | | | -// Cl11 Cl12 Cl21 Cl22 -// -//==> list[0] = {Cl1, Cl11, Cl12} -// list[1] = {Cl2, Cl21, Cl22} - -QList<CLASSTREE*> ParseManager::CreateClassLists(bool isInterfaceHeader) -{ - QList<CLASSTREE*>ret; - QList<CLASSLISTITEM*> classlist; - QList<CLASSLISTITEM*> allclasslist; - - Trace("Following classes scaned for header file: " + m_strHeaderFile); - //Iteration over all parsed documents - if(getPreProcessor()){ - for (Snapshot::const_iterator it = getPreProcessor()->snapshot.begin() - ; it != getPreProcessor()->snapshot.end(); ++it) - { - Document::Ptr doc = (*it); - if(doc){ - QFileInfo fileinf(doc->fileName()); - QFileInfo fileinf1(m_strHeaderFile); - //Get the Translated unit - Control* ctrl = doc->control(); - TranslationUnit* trlUnit = ctrl->translationUnit(); - AST* pAst = trlUnit->ast(); - TranslationUnitAST *ptrAst = 0; - if(pAst && (ptrAst = pAst->asTranslationUnit())){ - //iteration over all translated declaration in this document - for (DeclarationListAST *pDecllist = ptrAst->declaration_list; pDecllist; pDecllist = pDecllist->next) { - if(pDecllist->value){ - SimpleDeclarationAST *pSimpleDec = pDecllist->value->asSimpleDeclaration(); - if(pSimpleDec){ - //Iteration over class specifier - for (SpecifierListAST *pSimpleDecDecllist = pSimpleDec->decl_specifier_list; pSimpleDecDecllist; pSimpleDecDecllist = pSimpleDecDecllist->next) { - ClassSpecifierAST * pclassspec = pSimpleDecDecllist->value->asClassSpecifier(); - if(pclassspec){ - CLASSLISTITEM* item = new CLASSLISTITEM(); - item->classspec = pclassspec; - item->trlUnit = trlUnit; - allclasslist.push_back(item); - QString classname = item->trlUnit->spell(item->classspec->name->firstToken()); - Trace("- " + classname + " class scaned"); - - //We found a class that is defined in the header file that needs to be checked - if(fileinf.fileName().toLower() == fileinf1.fileName().toLower()){ - CLASSTREE* cltree = new CLASSTREE(); - cltree->highestlevelclass = item; - cltree->classlist.push_back(item); - ret.push_back(cltree); - } - } - } - } - } - } - } - } - } - } - //after we search for the classes we need to search for the baseclasses - Trace("Following classes found in Header file: " + m_strHeaderFile); - foreach(CLASSTREE *cltree, ret){ - QString classname = cltree->highestlevelclass->trlUnit->spell(cltree->highestlevelclass->classspec->name->firstToken()); - Trace("- " + classname + " class found"); - QList<CLASSLISTITEM*> baseclasslist; - getBaseClasses(cltree->highestlevelclass, baseclasslist, allclasslist, 0, isInterfaceHeader); - cltree->classlist.append(baseclasslist); - } - return ret; -} - -/******************************************** -Gets all the baseclass from a class and -add those base classes into the baseclasslist -********************************************/ -void ParseManager::getBaseClasses(const CLASSLISTITEM* pclass - , QList<CLASSLISTITEM*> &baseclasslist - , const QList<CLASSLISTITEM*> &allclasslist - , int level - , bool isInterfaceHeader) -{ - //iteration over the base_clause_list of the current class - QString levelmarker = " "; - for(int i = 0; i < level; i++) - levelmarker += " "; - levelmarker += "|- "; - QList<CLASSLISTITEM*>child; - - for(BaseSpecifierListAST *pBaseSpecList = pclass->classspec->base_clause_list; pBaseSpecList; pBaseSpecList = pBaseSpecList->next) - { - BaseSpecifierAST *pBaseSpec = pBaseSpecList->value; - bool found = false; - foreach(CLASSLISTITEM* pclspec, allclasslist) - { - if(pclspec->classspec->symbol->name() - && pBaseSpec->symbol->name() - && pclspec->classspec->symbol->name()->isEqualTo(pBaseSpec->symbol->name())) - { - child.push_back(pclspec); - baseclasslist.push_back(pclspec); - QString classname = pclspec->trlUnit->spell(pclspec->classspec->name->firstToken()); - Trace(levelmarker + classname + " class found"); - found = true; - break; - } - } - if(!found && pBaseSpec->name){ - QString classname = pclass->trlUnit->spell(pBaseSpec->name->firstToken()); - if(isInterfaceHeader) - Trace(levelmarker + classname + " class not found! Interface classes should not be inherited from Qt Objects!"); - else - Trace(levelmarker + classname + " class not found!"); - } - } - //call the function recursive because all the basclasses can have other base classes - foreach(CLASSLISTITEM* pchclass, child){ - getBaseClasses(pchclass, baseclasslist, allclasslist, ++level, isInterfaceHeader); - } -} - -/************************************************** -This function finds and creates all Elements wich -are significant for MetaDatas. -Those element will be added in the aparameter -lists. -**************************************************/ -void ParseManager::getElements(QList<FUNCTIONITEM*> &functionlist - , QList<PROPERTYITEM*> &propertylist - , QList<QENUMITEM*> &qenumlist - , QList<ENUMITEM*> &enumlist - , QList<QFLAGITEM*> &qflaglist - , QList<QDECLAREFLAGSITEM*> &qdeclareflaglist - , const QList<CLASSLISTITEM*> classitems - , const CLASSLISTITEM* highestlevelclass) -{ - foreach(CLASSLISTITEM* classitem, classitems){ - QString classname = ""; - if(classitem->classspec->name) - classname = classitem->trlUnit->spell(classitem->classspec->name->firstToken()); - for (DeclarationListAST *pmemberlist = classitem->classspec->member_specifier_list; pmemberlist; pmemberlist = pmemberlist->next) { - /********** - Functions - **********/ - if (FunctionDefinitionAST *pfctdef = pmemberlist->value->asFunctionDefinition()){ - FUNCTIONITEM* item = new FUNCTIONITEM; - item->trlUnit = classitem->trlUnit; - item->function = pfctdef->symbol; - item->classAst = classitem->classspec; - item->highestlevelclass = highestlevelclass; - functionlist.push_back(item); - if(isMetaObjFunction(item)) - Trace(" - " + getTraceFuntionString(item, classname) + " found"); - } - - SimpleDeclarationAST *pdecl = pmemberlist->value->asSimpleDeclaration(); - if(pdecl){ - for(List<Symbol*>* decllist = pdecl->symbols; decllist; decllist = decllist->next) - { - Function* pfct = decllist->value->type()->asFunctionType(); - if(pfct){ - FUNCTIONITEM* item = new FUNCTIONITEM(); - item->trlUnit = classitem->trlUnit; - item->function = pfct; - item->classAst = classitem->classspec; - item->highestlevelclass = highestlevelclass; - functionlist.push_back(item); - if(isMetaObjFunction(item)) - Trace(" - " + getTraceFuntionString(item, classname) + " found"); - } - } - /****** - enum - ******/ - for(List<SpecifierAST*>* decllist = pdecl->decl_specifier_list; decllist; decllist = decllist->next) - { - EnumSpecifierAST * penum = decllist->value->asEnumSpecifier(); - if(penum){ - ENUMITEM* item = new ENUMITEM(); - item->ast = penum; - item->highestlevelclass = highestlevelclass; - item->trlUnit = classitem->trlUnit; - enumlist.push_back(item); - } - } - } - else{ - /********** - Q_PROPERTY - **********/ - if(QtPropertyDeclarationAST *ppdecl = pmemberlist->value->asQtPropertyDeclaration()) { - propertylist.push_back(PROPERTYITEM::create(ppdecl, highestlevelclass)); - if (ppdecl->property_name && ppdecl->property_name->name && ppdecl->property_name->name->identifier()) { - Trace(" - Q_PROPERTY: " + QLatin1String(ppdecl->property_name->name->identifier()->chars()) + " found"); - } - } else{ - /********** - Q_ENUM - **********/ - if (QtEnumDeclarationAST *pqenum = pmemberlist->value->asQtEnumDeclaration()) { - for (NameListAST *plist = pqenum->enumerator_list; plist; plist = plist->next) { - QENUMITEM* item = new QENUMITEM; - item->name = plist->value->name->identifier()->chars(); - item->highestlevelclass = highestlevelclass; - qenumlist.push_back(item); - Trace(" - Q_ENUM: " + classname + "::" + item->name + " found"); - } - } - else{ - /********** - Q_FLAGS - **********/ - if (QtFlagsDeclarationAST *pqflags = pmemberlist->value->asQtFlagsDeclaration()){ - for (NameListAST *plist = pqflags->flag_enums_list; plist; plist = plist->next) { - QFLAGITEM* item = new QFLAGITEM; - item->name = plist->value->name; - item->highestlevelclass = highestlevelclass; - qflaglist.push_back(item); - Trace(" - Q_FLAGS: " + classname + "::" + item->name->identifier()->chars() + " found"); - } - } -#if 0 - /*The code for Q_DECLARE_FLAGS was wrong. It's optional, and only does a typedef. - That means, if you do the typedef yourself and not use Q_DECLARE_FLAGS, that *is* valid. - Meaning, if one would want to do a check like the ones in this app, one has to check the defined types in the class scope.*/ - else { - /**************** - Q_DECLARE_FLAGS - ****************/ - QtDeclareFlagsDeclarationAST *pqdeclflags = pmemberlist->value->asQDeclareFlagsDeclarationAST(); - if(pqdeclflags){ - QDECLAREFLAGSITEM* item = new QDECLAREFLAGSITEM(); - item->ast = pqdeclflags; - item->highestlevelclass = highestlevelclass; - item->trlUnit = classitem->trlUnit; - qdeclareflaglist.push_back(item); - } - } -#endif - } - } - } - } - } -} - -/********************************************* -Function that starts the comare between the -parser result and their metadata content. -*********************************************/ -bool ParseManager::checkAllMetadatas(ParseManager* pInterfaceParserManager, QString resultfile) -{ - bool ret = true; - - //Create output file - if(resultfile != "" && ::m_resultFile == 0){ - ::m_resultFile = new QFile(resultfile); - if (!::m_resultFile->open(QFile::WriteOnly | QFile::Truncate)) { - delete ::m_resultFile; - ::m_resultFile = 0; - } - } - - /************************************************ - Get all elements from the interface header file - ************************************************/ - Trace("### Get all elements from the interface header file ###"); - QList<CLASSTREE*> ilookuplist = pInterfaceParserManager->CreateClassLists(true); - QList<QList<FUNCTIONITEM*> > ifunctionslookuplist; - QList<QList<PROPERTYITEM*> > ipropertieslookuplist; - QList<QList<QENUMITEM*> > iqenumlookuplist; - QList<QList<ENUMITEM*> > ienumlookuplist; - QList<QList<QFLAGITEM*> > iqflaglookuplist; - QList<QList<QDECLAREFLAGSITEM*> > iqdeclareflaglookuplist; - Trace("Following MetaData found:"); - foreach(CLASSTREE* iclasstree, ilookuplist){ - QList<FUNCTIONITEM*>functionlist; - QList<PROPERTYITEM*>propertylist; - QList<QENUMITEM*>qenumlist; - QList<ENUMITEM*>enumlist; - QList<QFLAGITEM*> qflaglist; - QList<QDECLAREFLAGSITEM*> qdeclareflag; - getElements(functionlist - , propertylist - , qenumlist - , enumlist - , qflaglist - , qdeclareflag - , iclasstree->classlist - , iclasstree->highestlevelclass); - if(functionlist.size() > 0) - ifunctionslookuplist.append(functionlist); - if(propertylist.size() > 0) - ipropertieslookuplist.append(propertylist); - if(qenumlist.size() > 0) - iqenumlookuplist.append(qenumlist); - if(enumlist.size() > 0) - ienumlookuplist.append(enumlist); - if(qflaglist.size() > 0) - iqflaglookuplist.append(qflaglist); - if(qdeclareflag.size() > 0) - iqdeclareflaglookuplist.append(qdeclareflag); - } - - /************************************************ - Get all elements from the compare header file - ************************************************/ - Trace("\n"); - Trace("### Get all elements from the compare header file ###"); - QList<CLASSTREE*> lookuplist = CreateClassLists(false); - QList<QList<FUNCTIONITEM*> > functionslookuplist; - QList<QList<PROPERTYITEM*> > propertieslookuplist; - QList<QList<QENUMITEM*> > qenumlookuplist; - QList<QList<ENUMITEM*> > enumlookuplist; - QList<QList<QFLAGITEM*> > qflaglookuplist; - QList<QList<QDECLAREFLAGSITEM*> > qdeclareflaglookuplist; - Trace("Following MetaData found:"); - foreach(CLASSTREE* classtree, lookuplist){ - QList<FUNCTIONITEM*>functionlist; - QList<PROPERTYITEM*>propertylist; - QList<QENUMITEM*>qenumlist; - QList<ENUMITEM*>enumlist; - QList<QFLAGITEM*> qflaglist; - QList<QDECLAREFLAGSITEM*> qdeclareflag; - getElements(functionlist - , propertylist - , qenumlist - , enumlist - , qflaglist - , qdeclareflag - , classtree->classlist - , classtree->highestlevelclass); - if(functionlist.size() > 0) - functionslookuplist.append(functionlist); - if(propertylist.size() > 0) - propertieslookuplist.append(propertylist); - if(qenumlist.size() > 0) - qenumlookuplist.append(qenumlist); - if(enumlist.size() > 0) - enumlookuplist.append(enumlist); - if(qflaglist.size() > 0) - qflaglookuplist.append(qflaglist); - if(qdeclareflag.size() > 0) - qdeclareflaglookuplist.append(qdeclareflag); - } - - Trace("\n"); - Trace("### Result: ###"); - /****************************** - Check for function - ******************************/ - Trace("Compare all interface MetaData functions:"); - QList<FUNCTIONITEM*> missingifcts = checkMetadataFunctions(functionslookuplist, ifunctionslookuplist); - if(missingifcts.size() > 0){ - foreach(FUNCTIONITEM* ifct, missingifcts){ - m_errormsgs.append(getErrorMessage(ifct)); - } - ret = false; - Trace("- Failed!"); - } - else{ - Trace("- OK"); - } - - /****************************** - Check for properies - ******************************/ - Trace("Compare all interface MetaData properties:"); - QList<PROPERTYITEM*> missingippts = checkMetadataProperties(propertieslookuplist, functionslookuplist, ipropertieslookuplist, ifunctionslookuplist); - if(missingippts.size() > 0){ - foreach(PROPERTYITEM* ippt, missingippts){ - m_errormsgs.append(getErrorMessage(ippt)); - } - ret = false; - Trace("- Failed!"); - } - else{ - Trace("- OK"); - } - - /****************************** - Check for enums - ******************************/ - Trace("Compare all interface MetaData enums:"); - QList<QENUMITEM*> missingiqenums = checkMetadataEnums(qenumlookuplist, enumlookuplist, iqenumlookuplist, ienumlookuplist); - if(missingiqenums.size() > 0){ - foreach(QENUMITEM* ienum, missingiqenums){ - m_errormsgs.append(getErrorMessage(ienum)); - } - ret = false; - Trace("- Failed!"); - } - else{ - Trace("- OK"); - } - - /****************************** - Check for flags - ******************************/ - Trace("Compare all interface MetaData flags:"); - QList<QFLAGITEM*> missingiqflags = checkMetadataFlags(qflaglookuplist, qdeclareflaglookuplist, enumlookuplist - , iqflaglookuplist, iqdeclareflaglookuplist, ienumlookuplist); - if(missingiqflags.size() > 0){ - foreach(QFLAGITEM* iflags, missingiqflags){ - m_errormsgs.append(getErrorMessage(iflags)); - } - ret = false; - Trace("- Failed!"); - } - else{ - Trace("- OK"); - } - - /****************************** - Add summary - ******************************/ - Trace("\n"); - Trace("### summary ###"); - if(m_errormsgs.size() > 0){ - Trace("- Folowing interface items are missing:"); - foreach(QString msg, m_errormsgs) - Trace(" - " + msg); - } - else - Trace("Interface is full defined."); - - //now delet all Classitems - foreach(CLASSTREE* l, ilookuplist){ - l->classlist.clear(); - } - foreach(CLASSTREE* l, lookuplist){ - l->classlist.clear(); - } - //delete all functionitems - foreach(QList<FUNCTIONITEM*>l, ifunctionslookuplist){ - l.clear(); - } - foreach(QList<FUNCTIONITEM*>l, functionslookuplist){ - l.clear(); - } - //delete all properties - foreach(QList<PROPERTYITEM*>l, ipropertieslookuplist){ - l.clear(); - } - foreach(QList<PROPERTYITEM*>l, propertieslookuplist){ - l.clear(); - } - //delete all qenums - foreach(QList<QENUMITEM*>l, iqenumlookuplist){ - l.clear(); - } - foreach(QList<QENUMITEM*>l, iqenumlookuplist){ - l.clear(); - } - //delete all enums - foreach(QList<ENUMITEM*>l, ienumlookuplist){ - l.clear(); - } - foreach(QList<ENUMITEM*>l, enumlookuplist){ - l.clear(); - } - //delete all qflags - foreach(QList<QFLAGITEM*>l, iqflaglookuplist){ - l.clear(); - } - foreach(QList<QFLAGITEM*>l, qflaglookuplist){ - l.clear(); - } - //delete all qdeclareflags - foreach(QList<QDECLAREFLAGSITEM*>l, iqdeclareflaglookuplist){ - l.clear(); - } - foreach(QList<QDECLAREFLAGSITEM*>l, qdeclareflaglookuplist){ - l.clear(); - } - - return ret; -} - -//<------------------------------------------------------- Start of MetaData functions -/*********************************** -Function that checks all functions -which will occur in the MetaData -***********************************/ -QList<FUNCTIONITEM*> ParseManager::checkMetadataFunctions(const QList<QList<FUNCTIONITEM*> > &classfctlist, const QList<QList<FUNCTIONITEM*> > &iclassfctlist) -{ - QList<FUNCTIONITEM*> missingifcts; - //Compare each function from interface with function from header (incl. baseclass functions) - QList<FUNCTIONITEM*> ifcts; - foreach(QList<FUNCTIONITEM*>ifunctionlist, iclassfctlist){ - ifcts.clear(); - //check if one header class contains all function from one interface header class - if(classfctlist.count() > 0){ - foreach(QList<FUNCTIONITEM*>functionlist, classfctlist){ - QList<FUNCTIONITEM*> tmpl = containsAllMetadataFunction(functionlist, ifunctionlist); - if(tmpl.size() == 0){ - ifcts.clear(); - break; - } - else - ifcts.append(tmpl); - } - } - else { - foreach(FUNCTIONITEM *pfct, ifunctionlist) - pfct->classWichIsNotFound << "<all classes>"; - ifcts.append(ifunctionlist); - } - missingifcts.append(ifcts); - } - return missingifcts; -} - -/********************************************* -Helper function to check if a function will -occure in the MetaData. -*********************************************/ -bool ParseManager::isMetaObjFunction(FUNCTIONITEM* fct) -{ - if(fct->function->isInvokable() - || fct->function->isSignal() - || fct->function->isSlot()) - return true; - return false; -} - -/**************************************************** -Check if all function from iclassfctlist are defined -in the classfctlist as well. -It will return all the function they are missing. -****************************************************/ -QList<FUNCTIONITEM*> ParseManager::containsAllMetadataFunction(const QList<FUNCTIONITEM*> &classfctlist, const QList<FUNCTIONITEM*> &iclassfctlist) -{ - QList<FUNCTIONITEM*> ret; - foreach(FUNCTIONITEM* ifct, iclassfctlist){ - if(isMetaObjFunction(ifct)){ - bool found = false; - QStringList missingimplinclasses; - ClassSpecifierAST* clspec = 0; - QString classname = ""; - foreach(FUNCTIONITEM* fct, classfctlist){ - if(clspec != fct->highestlevelclass->classspec){ - clspec = fct->highestlevelclass->classspec; - //get the classname - unsigned int firsttoken = clspec->name->firstToken(); - classname += fct->trlUnit->spell(firsttoken); - if(missingimplinclasses.indexOf(classname) < 0) - missingimplinclasses.push_back(classname); - } - if(fct->isEqualTo(ifct, false)){ - found = true; - missingimplinclasses.clear(); - Trace("- " + getTraceFuntionString(fct, classname) + " implemented"); - break; - } - } - if(!found){ - ifct->classWichIsNotFound.append(missingimplinclasses); - ret.push_back(ifct); - QString classname = ifct->trlUnit->spell(ifct->highestlevelclass->classspec->name->firstToken()); - Trace("- " + getTraceFuntionString(ifct, classname) + " not implemented!"); - } - } - } - return ret; -} - -/************************************ -Function that gives back an error -string for a MetaData function -mismatch. -************************************/ -QStringList ParseManager::getErrorMessage(FUNCTIONITEM* fct) -{ - QStringList ret; - QString fctstring = ""; - QString fcttype = ""; - - foreach(QString classname, fct->classWichIsNotFound){ - QString tmp; - QTextStream out(&tmp); - - fcttype = ""; - fctstring = classname; - fctstring += "::"; - - unsigned int token = fct->function->sourceLocation() - 1; - while(fct->trlUnit->tokenAt(token).isNot(T_EOF_SYMBOL)){ - fctstring += fct->trlUnit->tokenAt(token).spell(); - if(*fct->trlUnit->tokenAt(token).spell() == ')') - break; - fctstring += " "; - token++; - } - - Function* pfct = fct->function; - if(pfct){ - fcttype = "type: "; - //Check for private, protected and public - if(pfct->isPublic()) - fcttype = "public "; - if(pfct->isProtected()) - fcttype = "protected "; - if(pfct->isPrivate()) - fcttype = "private "; - - if(pfct->isVirtual()) - fcttype += "virtual "; - if(pfct->isPureVirtual()) - fcttype += "pure virtual "; - - if(pfct->isSignal()) - fcttype += "Signal "; - if(pfct->isSlot()) - fcttype += "Slot "; - if(pfct->isNormal()) - fcttype += "Normal "; - if(pfct->isInvokable()) - fcttype += "Invokable "; - } - out << fcttype << fctstring; - ret << tmp; - } - return ret; -} -//---> - -//<------------------------------------------------------- Start of Q_PROPERTY checks -/*********************************** -Function that checks all Property -which will occur in the MetaData -***********************************/ -QList<PROPERTYITEM*> ParseManager::checkMetadataProperties(const QList<QList<PROPERTYITEM*> > &classproplist - , const QList<QList<FUNCTIONITEM*> > &classfctlist - , const QList<QList<PROPERTYITEM*> > &iclassproplist - , const QList<QList<FUNCTIONITEM*> > &iclassfctlist) -{ - QList<PROPERTYITEM*> missingiprops; - //assign the property functions - foreach(QList<PROPERTYITEM*>proplist, classproplist){ - foreach(PROPERTYITEM* prop, proplist){ - assignPropertyFunctions(prop, classfctlist); - } - } - - foreach(QList<PROPERTYITEM*>proplist, iclassproplist){ - foreach(PROPERTYITEM* prop, proplist){ - assignPropertyFunctions(prop, iclassfctlist); - } - } - - //Compare each qproperty from interface with qproperty from header (incl. baseclass functions) - QList<PROPERTYITEM*> ippts; - foreach(QList<PROPERTYITEM*>ipropertylist, iclassproplist){ - ippts.clear(); - //check if one header class contains all function from one interface header class - if(classproplist.count() > 0){ - foreach(QList<PROPERTYITEM*>propertylist, classproplist){ - QList<PROPERTYITEM*> tmpl = containsAllPropertyFunction(propertylist, ipropertylist); - if(tmpl.size() == 0) - ippts.clear(); - else - ippts.append(tmpl); - } - } - else { - foreach(PROPERTYITEM *pprop, ipropertylist){ - pprop->classWichIsNotFound << "<all classes>"; - QString name = pprop->ast->property_name->name->identifier()->chars(); - Trace("- Property: <all classes>::" + name + " not found!"); - } - ippts.append(ipropertylist); - } - missingiprops.append(ippts); - } - return missingiprops; -} - -static QString findName(ExpressionAST *ast) -{ - // The "old" icheck code assumed that functions were only a single identifier, so I'll assume the same: - if (NameAST *nameAST = ast->asName()) - return nameAST->name->identifier()->chars(); - else - return QString(); -} - -/************************************** -Function that resolves the dependensies -between Q_PROPERTY -and thier READ, WRITE, NOTIFY and RESET -functions. -***************************************/ -void ParseManager::assignPropertyFunctions(PROPERTYITEM* prop, const QList<QList<FUNCTIONITEM*> > &fctlookuplist) -{ - //get the name of the needed functions - QString readfctname; - QString writefctname; - QString resetfctname; - QString notifyfctname; - - int needtofind = 0; - if(prop->readAst){ - readfctname = findName(prop->readAst); - needtofind++; - } - if(prop->writeAst){ - writefctname = findName(prop->writeAst); - needtofind++; - } - if(prop->resetAst){ - resetfctname = findName(prop->resetAst); - needtofind++; - } - if(prop->notifyAst){ - notifyfctname = findName(prop->notifyAst); - needtofind++; - } - //Now iterate over all function to find all functions wich are defined in the Q_PROPERTY macro - if(needtofind > 0){ - prop->foundalldefinedfct = false; - foreach(QList<FUNCTIONITEM*> fctlist, fctlookuplist){ - foreach(FUNCTIONITEM* pfct, fctlist){ - QString fctname = pfct->trlUnit->spell(pfct->function->sourceLocation()); - //check the function type against the property type - FullySpecifiedType retTy = pfct->function->returnType(); - - if (!fctname.isEmpty() && retTy.isValid()) { - if(prop->readAst && fctname == readfctname){ - if (prop->type != retTy) - continue; - prop->readFct = pfct; - needtofind--; - } - if(prop->writeAst && fctname == writefctname){ - prop->writeFct = pfct; - needtofind--; - } - if(prop->resetAst && fctname == resetfctname){ - prop->resetFct = pfct; - needtofind--; - } - if(prop->notifyAst && fctname == notifyfctname){ - prop->notifyFct = pfct; - needtofind--; - } - if(needtofind <= 0){ - //a flag that indicates if a function was missing - prop->foundalldefinedfct = true; - return; - } - } - } - } - } -} - -/************************************** -Function that checks if all functions -dependencies in Q_PROPERTY have the -same arguments and retunr value. -***************************************/ -QList<PROPERTYITEM*> ParseManager::containsAllPropertyFunction(const QList<PROPERTYITEM*> &classproplist, const QList<PROPERTYITEM*> &iclassproplist) -{ - QList<PROPERTYITEM*> ret; - foreach(PROPERTYITEM* ipropt, iclassproplist){ - if(ipropt->foundalldefinedfct){ - bool found = false; - QStringList missingimplinclasses; - ClassSpecifierAST* clspec = 0; - QString classname = ""; - foreach(PROPERTYITEM* propt, classproplist){ - if(clspec != propt->highestlevelclass->classspec){ - clspec = propt->highestlevelclass->classspec; - //get the classname - unsigned int firsttoken = clspec->name->firstToken(); - classname += propt->trlUnit->spell(firsttoken); - if(missingimplinclasses.indexOf(classname) < 0) - missingimplinclasses.push_back(classname); - } - if(propt->isEqualTo(ipropt)){ - found = true; - missingimplinclasses.clear(); - Trace("- Property: " + classname + "::" + propt->ast->property_name->name->identifier()->chars() + " found"); - break; - } - } - if(!found){ - ipropt->classWichIsNotFound.append(missingimplinclasses); - ret.push_back(ipropt); - QString classname = ipropt->trlUnit->spell(ipropt->highestlevelclass->classspec->name->firstToken()); - Trace("- Property: " + classname + "::" + ipropt->ast->property_name->name->identifier()->chars() + " not found!"); - } - } - else{ - QString classname = ipropt->trlUnit->spell(ipropt->highestlevelclass->classspec->name->firstToken()); - Overview oo; - QString proptype = oo(ipropt->type); - Trace("- Property: " + classname + "::" + proptype + " functions are missing!"); - ret.push_back(ipropt); - } - } - return ret; -} - -/************************************ -Function that gives back an error -string for a Q_PROPERTY mismatch. -************************************/ -QStringList ParseManager::getErrorMessage(PROPERTYITEM* ppt) -{ - QStringList ret; - QString pptstring = ""; - - if(!ppt->foundalldefinedfct) - { - QString tmp; - QTextStream out(&tmp); - - unsigned int firsttoken = ppt->highestlevelclass->classspec->name->firstToken(); - unsigned int lasttoken = ppt->highestlevelclass->classspec->name->lastToken(); - for(unsigned int i = firsttoken; i < lasttoken; i++){ - out << ppt->trlUnit->spell(i); - } - out << "::"; - firsttoken = ppt->ast->firstToken(); - lasttoken = ppt->ast->lastToken(); - for(unsigned int i = firsttoken; i <= lasttoken; i++){ - out << ppt->trlUnit->spell(i) << " "; - } - out << endl << " -"; - if(ppt->readAst && !ppt->readFct) - out << "READ "; - if(ppt->writeAst && !ppt->writeFct) - out << "WRITE "; - if(ppt->resetAst && !ppt->resetFct) - out << "RESET."; - if(ppt->notifyAst && !ppt->notifyFct) - out << "NOTIFY "; - out << "functions missing." << endl; - ret << tmp; - } - for(int i = 0; i < ppt->classWichIsNotFound.size(); i++){ - QString tmp; - QTextStream out(&tmp); - - pptstring = ppt->classWichIsNotFound[i]; - pptstring += "::"; - - unsigned int firsttoken = ppt->ast->firstToken(); - unsigned int lasttoken = ppt->ast->lastToken(); - for(unsigned int i = firsttoken; i <= lasttoken; i++){ - pptstring += ppt->trlUnit->spell(i); - pptstring += " "; - } - - out << pptstring; - ret << tmp; - } - return ret; -} -//---> - - -//<------------------------------------------------------- Start of Q_ENUMS checks -/*********************************** -Function that checks all enums -which will occur in the MetaData -***********************************/ -QList<QENUMITEM*> ParseManager::checkMetadataEnums(const QList<QList<QENUMITEM*> > &classqenumlist - , const QList<QList<ENUMITEM*> > &classenumlist - , const QList<QList<QENUMITEM*> > &iclassqenumlist - , const QList<QList<ENUMITEM*> > &iclassenumlist) -{ - QList<QENUMITEM*> missingiqenums; - //assign the property functions - foreach(QList<QENUMITEM*>qenumlist, classqenumlist){ - foreach(QENUMITEM* qenum, qenumlist){ - assignEnumValues(qenum, classenumlist); - } - } - foreach(QList<QENUMITEM*>qenumlist, iclassqenumlist){ - foreach(QENUMITEM* qenum, qenumlist){ - assignEnumValues(qenum, iclassenumlist); - } - } - - //Compare each qenum from interface with qenum from header (incl. baseclass functions) - QList<QENUMITEM*> iqenums; - foreach(QList<QENUMITEM*>iqenumlist, iclassqenumlist){ - iqenums.clear(); - //check if one header class contains all function from one interface header class - if(classqenumlist.count() > 0){ - foreach(QList<QENUMITEM*>qenumlist, classqenumlist){ - QList<QENUMITEM*> tmpl = containsAllEnums(qenumlist, iqenumlist); - if(tmpl.size() == 0) - iqenums.clear(); - else - iqenums.append(tmpl); - - } - } - else { - foreach(QENUMITEM *qenum, iqenumlist){ - qenum->classWichIsNotFound << "<all classes>"; - Trace("- Enum: <all classes>::" + qenum->name + " not found!"); - } - iqenums.append(iqenumlist); - } - missingiqenums.append(iqenums); - } - - return missingiqenums; -} - -/********************************************* -Helper function which creates a string out of -an enumerator including its values. -*********************************************/ -QStringList ParseManager::getEnumValueStringList(ENUMITEM *penum, QString mappedenumname/* = ""*/) -{ - QStringList ret; - EnumSpecifierAST *penumsec = penum->ast; - QString enumname = penum->trlUnit->spell(penumsec->name->firstToken()); - int enumvalue = 0; - //now iterrate over all enumitems and create a string like following: - //EnumName.EnumItemName.Value - //ConnectionState.disconnected.0 - for (EnumeratorListAST *plist = penum->ast->enumerator_list; plist; plist = plist->next) { - QString value = enumname; - if(mappedenumname.size() > 0) - value = mappedenumname; - value += "."; - value += penum->trlUnit->spell(plist->value->identifier_token); - value += "."; - if(plist->value->equal_token > 0 && plist->value->expression){ - QString v = penum->trlUnit->spell(plist->value->expression->firstToken()); - bool ch; - int newval = enumvalue; - if(v.indexOf("0x") >= 0) - newval = v.toInt(&ch, 16); - else - newval = v.toInt(&ch, 10); - if(ch) - enumvalue = newval; - } - value += QString::number(enumvalue); - enumvalue++; - // now add this enumitem string in the VALUE list - ret << value; - } - return ret; -} - -/************************************** -Function that resolves the dependensies -between Q_ENUMS and enums. -***************************************/ -void ParseManager::assignEnumValues(QENUMITEM* qenum, const QList<QList<ENUMITEM*> > &enumlookuplist) -{ - //iterate over all enums and find the one with the same name like enumname - bool found = false; - foreach (QList<ENUMITEM*> penumlist, enumlookuplist) { - foreach(ENUMITEM *penum, penumlist){ - EnumSpecifierAST *penumsec = penum->ast; - QString enumname1 = penum->trlUnit->spell(penumsec->name->firstToken()); - if(qenum->name == enumname1){ - qenum->values << getEnumValueStringList(penum); - found = true; - break; - } - } - if(!found) - qenum->foundallenums = false; - } -} - -/*********************************** -Function that checkt if the Q_ENUMS -are completed defined and if the -Enum values are the same. -***********************************/ -QList<QENUMITEM*> ParseManager::containsAllEnums(const QList<QENUMITEM*> &classqenumlist, const QList<QENUMITEM*> &iclassqenumlist) -{ - Overview oo; - - QList<QENUMITEM*> ret; - foreach(QENUMITEM* iqenum, iclassqenumlist){ - bool found = false; - QStringList missingimplinclasses; - ClassSpecifierAST* clspec = 0; - QString classname = ""; - foreach(QENUMITEM* qenum, classqenumlist){ - if(clspec != qenum->highestlevelclass->classspec){ - clspec = qenum->highestlevelclass->classspec; - //get the classname - classname += oo(clspec->symbol); - if(missingimplinclasses.indexOf(classname) < 0) - missingimplinclasses.push_back(classname); - } - if(qenum->isEqualTo(iqenum)){ - found = true; - missingimplinclasses.clear(); - Trace("- Enum: " + classname + "::" + qenum->name + " found"); - break; - } - } - if(!found){ - iqenum->classWichIsNotFound.append(missingimplinclasses); - ret.push_back(iqenum); - QString classname = oo(iqenum->highestlevelclass->classspec->symbol); - Trace("- Enum: " + classname + "::" + iqenum->name + " not found!"); - } - } - return ret; -} - -/************************************ -Function that gives back an error -string for a Q_ENUMS mismatch. -************************************/ -QStringList ParseManager::getErrorMessage(QENUMITEM* qenum) -{ - Overview oo; - QStringList ret; - - if(!qenum->foundallenums) - { - QString tmp; - QTextStream out(&tmp); - - out << oo(qenum->highestlevelclass->classspec->symbol); - out << "::Q_ENUMS " << qenum->name << " enum missing."; - ret << tmp; - } - - for (int i = 0; i < qenum->classWichIsNotFound.size(); i++){ - QString tmp; - QTextStream out(&tmp); - - out << qenum->classWichIsNotFound[i] << "::Q_ENUMS " - << qenum->name; - ret << tmp; - } - return ret; -} -//---> - -//<------------------------------------------------------- Start of Q_FLAGS checks -/*********************************** -Function that checks all flags -which will occur in the MetaData -***********************************/ -QList<QFLAGITEM*> ParseManager::checkMetadataFlags(const QList<QList<QFLAGITEM*> > &classqflaglist - , const QList<QList<QDECLAREFLAGSITEM*> > &classqdeclareflaglist - , const QList<QList<ENUMITEM*> > &classenumlist - , const QList<QList<QFLAGITEM*> > &iclassqflaglist - , const QList<QList<QDECLAREFLAGSITEM*> > &iclassqdeclareflaglist - , const QList<QList<ENUMITEM*> > &iclassenumlist) -{ - QList<QFLAGITEM*> missingqflags; - //assign the enums to the flags - foreach(QList<QFLAGITEM*>qflaglist, classqflaglist){ - foreach(QFLAGITEM* qflag, qflaglist){ - assignFlagValues(qflag, classqdeclareflaglist, classenumlist); - } - } - foreach(QList<QFLAGITEM*>qflaglist, iclassqflaglist){ - foreach(QFLAGITEM* qflag, qflaglist){ - assignFlagValues(qflag, iclassqdeclareflaglist, iclassenumlist); - } - } - - //Compare each qenum from interface with qenum from header (incl. baseclass functions) - QList<QFLAGITEM*> iqflags; - foreach(QList<QFLAGITEM*>iqflaglist, iclassqflaglist){ - iqflags.clear(); - //check if one header class contains all function from one interface header class - if(classqflaglist.count() >0){ - foreach(QList<QFLAGITEM*>qflaglist, classqflaglist){ - QList<QFLAGITEM*> tmpl = containsAllFlags(qflaglist, iqflaglist); - if(tmpl.size() == 0) - iqflags.clear(); - else - iqflags.append(tmpl); - - } - } - else { - foreach(QFLAGITEM *pflag, iqflaglist){ - pflag->classWichIsNotFound << "<all classes>"; - QString name= pflag->name->identifier()->chars(); - Trace("- Flag: <all classes>::" + name + " not found!"); - } - iqflags.append(iqflaglist); - } - missingqflags.append(iqflags); - } - return missingqflags; -} - -/************************************** -Function that resolves the dependensies -between Q_FLAG, Q_DECLARE_FLAGS -and enums. -***************************************/ -void ParseManager::assignFlagValues(QFLAGITEM* qflags, const QList<QList<QDECLAREFLAGSITEM*> > &qdeclareflagslookuplist, const QList<QList<ENUMITEM*> > &enumlookuplist) -{ - QString enumname; - - //try to find if there is a deflare flag macro with the same name as in qflagname - Scope *classMembers = qflags->highestlevelclass->classspec->symbol; - Symbol *s = classMembers->find(qflags->name); - if (s->isTypedef()) { - FullySpecifiedType ty = s->type(); - if (Enum *e = ty->asEnumType()) { - enumname = e->name()->identifier()->chars(); - } - } - - //now we have the right enum name now we need to find the enum - bool found = false; - foreach(QList<ENUMITEM*> enumitemlist, enumlookuplist){ - foreach(ENUMITEM* enumitem, enumitemlist){ - EnumSpecifierAST *penumspec = enumitem->ast; - QString enumspecname = enumitem->trlUnit->spell(penumspec->name->firstToken()); - if(enumspecname == enumname){ - qflags->enumvalues << getEnumValueStringList(enumitem, qflags->name->identifier()->chars()); - found = true; - break; - } - } - if(found) - break; - } - if(!found) - qflags->foundallenums = false; -} - -/***************************************** -Function that compares if all enums -and flags assigned by using the Q_FLAGS -are complete defined. -*****************************************/ -QList<QFLAGITEM*> ParseManager::containsAllFlags(const QList<QFLAGITEM*> &classqflaglist, const QList<QFLAGITEM*> &iclassqflaglist) -{ - QList<QFLAGITEM*> ret; - foreach(QFLAGITEM* iqflags, iclassqflaglist){ - if(iqflags->foundallenums){ - bool found = false; - QStringList missingimplinclasses; - ClassSpecifierAST* clspec = 0; - QString classname = ""; - foreach(QFLAGITEM* qflags, classqflaglist){ - if(clspec != qflags->highestlevelclass->classspec){ - clspec = qflags->highestlevelclass->classspec; - //get the classname - classname += clspec->symbol->name()->identifier()->chars(); - if(missingimplinclasses.indexOf(classname) < 0) - missingimplinclasses.push_back(classname); - } - if(qflags->isEqualTo(iqflags)){ - found = true; - missingimplinclasses.clear(); - Trace("- Flag: " + classname + "::" + qflags->name->identifier()->chars() + " found"); - break; - } - } - if(!found){ - iqflags->classWichIsNotFound.append(missingimplinclasses); - ret.push_back(iqflags); - QString classname = iqflags->highestlevelclass->classspec->symbol->name()->identifier()->chars(); - Trace("- Flag: " + classname + "::" + iqflags->name->identifier()->chars() + " not found!"); - } - } - else - ret.push_back(iqflags); - } - return ret; -} - -/************************************ -Function that gives back an error -string for a Q_FLAGS mismatch. -************************************/ -QStringList ParseManager::getErrorMessage(QFLAGITEM* pfg) -{ - Overview oo; - QStringList ret; - - if(!pfg->foundallenums) - { - QString tmp; - QTextStream out(&tmp); - - out << oo(pfg->highestlevelclass->classspec->symbol->name()); - out << "::Q_FLAGS "<<pfg->name->identifier()->chars()<< ": enum missing."; - ret << tmp; - } - for(int i = 0; i < pfg->classWichIsNotFound.size(); i++){ - QString tmp; - QTextStream out(&tmp); - - out << pfg->classWichIsNotFound[i] << "::Q_FLAGS " << oo(pfg->name); - ret << tmp; - } - return ret; -} - -inline QString ParseManager::getTraceFuntionString(const FUNCTIONITEM *fctitem, const QString& classname) -{ - QString ret; - - if(fctitem->function->isPublic()) - ret = "public "; - if(fctitem->function->isProtected()) - ret = "protected "; - if(fctitem->function->isPrivate()) - ret = "private "; - - if(fctitem->function->isVirtual()) - ret += "virtual "; - if(fctitem->function->isPureVirtual()) - ret += "pure virtual "; - - if(fctitem->function->isSignal()) - ret += "Signal "; - if(fctitem->function->isSlot()) - ret += "Slot "; - if(fctitem->function->isNormal()) - ret += "Normal "; - if(fctitem->function->isInvokable()) - ret += "Invokable "; - - ret += classname; - ret += "::"; - ret += fctitem->trlUnit->spell(fctitem->function->sourceLocation()); - return ret; -} - -void ParseManager::Trace(QString value) -{ - if(::m_resultFile){ - QTextStream out(::m_resultFile); - if(value == "\n") - out << endl; - else - out << value << endl; - } -} - -PROPERTYITEM *PROPERTYITEM::create(QtPropertyDeclarationAST *ast, const CLASSLISTITEM *clazz) -{ - PROPERTYITEM *item = new PROPERTYITEM; - item->ast = ast; - item->highestlevelclass = clazz; - item->trlUnit = clazz->trlUnit; - - if (ast->type_id) { - Bind bind(item->trlUnit); - item->type = bind(ast->type_id, clazz->classspec->symbol); - } - - for (QtPropertyDeclarationItemListAST *it = ast->property_declaration_items; - it; it = it->next) { - if (!it->value->item_name_token) - continue; - const char *name = item->trlUnit->spell(it->value->item_name_token); - if (!qstrcmp(name, "READ")) - item->readAst = it->value->expression; - else if (!qstrcmp(name, "WRITE")) - item->writeAst = it->value->expression; - else if (!qstrcmp(name, "RESET")) - item->resetAst = it->value->expression; - else if (!qstrcmp(name, "NOTIFY")) - item->notifyAst = it->value->expression; - } - - return item; -} - -//---> diff --git a/tests/auto/icheckbuild/parsemanager.h b/tests/auto/icheckbuild/parsemanager.h deleted file mode 100644 index 3040ec0104..0000000000 --- a/tests/auto/icheckbuild/parsemanager.h +++ /dev/null @@ -1,304 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -/* -** Description: -** -** The ParseManager parses and compares to different header files -** of its metadata. This can be used for checking if an Interface -** is implemented complete. -** -** How to use it: -** -** //Parse the interface header -** ParseManager* iParseManager = new ParseManager(); -** iParseManager->setIncludePath(iIncludepathlist); -** iParseManager->parse(iFilelist); -** -** //Parse the header that needs to be compared against the interface header -** ParseManager* chParseManager = new ParseManager(); -** chIncludepathlist << getQTIncludePath(); -* chParseManager->setIncludePath(chIncludepathlist); -** chParseManager->parse(chFilelist); -** -** if(!chParseManager->checkAllMetadatas(iParseManager)){ -** cout << "Following interface items are missing:" << endl; -** QStringList errorlist = chParseManager->getErrorMsg(); -** foreach(QString msg, errorlist){ -** cout << (const char *)msg.toLatin1() << endl; -** } -** return -1; -** } -** else -** cout << "Interface is full defined."; -*/ - -#ifndef PARSEMANAGER_H -#define PARSEMANAGER_H - -#include "cplusplus/CppDocument.h" -#include "ASTfwd.h" -#include "FullySpecifiedType.h" - -#include <QObject> -#include <QList> -#include <QFuture> -#include <QStringList> -#include <QFile> - -namespace CppTools{ - namespace Internal{ - class CppPreprocessor; - } -} - -namespace CPlusPlus { - class CLASSLISTITEM - { - public: - CPlusPlus::TranslationUnit* trlUnit; - ClassSpecifierAST* classspec; - }; - class CLASSTREE - { - public: - CLASSLISTITEM* highestlevelclass; - QList<CLASSLISTITEM*> classlist; - }; - class FUNCTIONITEM - { - public: - const CLASSLISTITEM* highestlevelclass; - CPlusPlus::TranslationUnit* trlUnit; - ClassSpecifierAST* classAst; - QStringList classWichIsNotFound; - CPlusPlus::Function* function; - - bool isEqualTo(FUNCTIONITEM* cpfct, bool ignoreName = true); - - FUNCTIONITEM() - { - highestlevelclass = 0; - trlUnit = 0; - classAst = 0; - function = 0; - } - }; - class PROPERTYITEM - { - public: - const CLASSLISTITEM* highestlevelclass; - QStringList classWichIsNotFound; - QtPropertyDeclarationAST *ast; - CPlusPlus::TranslationUnit* trlUnit; - FullySpecifiedType type; - ExpressionAST *readAst; - FUNCTIONITEM *readFct; - ExpressionAST *writeAst; - FUNCTIONITEM *writeFct; - ExpressionAST *resetAst; - FUNCTIONITEM *resetFct; - ExpressionAST *notifyAst; - FUNCTIONITEM *notifyFct; - bool foundalldefinedfct; - - bool isEqualTo(PROPERTYITEM* cpppt); - PROPERTYITEM() - { - highestlevelclass = 0; - ast = 0; - trlUnit = 0; - readAst = 0; - readFct = 0; - writeAst = 0; - writeFct = 0; - resetAst = 0; - resetFct = 0; - notifyAst = 0; - notifyFct = 0; - foundalldefinedfct = false; - } - - static PROPERTYITEM *create(QtPropertyDeclarationAST *ast, const CLASSLISTITEM *clazz); - }; - - class QENUMITEM - { - public: - const CLASSLISTITEM* highestlevelclass; - QStringList classWichIsNotFound; - QString name; - //an item in this list will be shown like: - //EnumName.EnumItemName.Value - //ConnectionState.disconnected.0 - QStringList values; - bool foundallenums; - - bool isEqualTo(QENUMITEM *cpenum); - QENUMITEM() - { - highestlevelclass = 0; - values.clear(); - foundallenums = true; - } - }; - - class ENUMITEM - { - public: - const CLASSLISTITEM* highestlevelclass; - CPlusPlus::TranslationUnit* trlUnit; - QStringList classWichIsNotFound; - EnumSpecifierAST* ast; - - ENUMITEM() - { - highestlevelclass = 0; - trlUnit = 0; - ast = 0; - } - }; - - class QFLAGITEM - { - public: - const CLASSLISTITEM* highestlevelclass; - const Name *name; - QStringList classWichIsNotFound; - QStringList enumvalues; - bool foundallenums; - - bool isEqualTo(QFLAGITEM *cpflag); - QFLAGITEM() - { - highestlevelclass = 0; - enumvalues.clear(); - foundallenums = true; - } - }; - - class QDECLAREFLAGSITEM - { - public: - const CLASSLISTITEM* highestlevelclass; - CPlusPlus::TranslationUnit* trlUnit; - QStringList classWichIsNotFound; - QtFlagsDeclarationAST* ast; - - QDECLAREFLAGSITEM() - { - highestlevelclass = 0; - trlUnit = 0; - ast = 0; - } - }; - - static QFile* m_resultFile = 0; - class ParseManager : public QObject - { - Q_OBJECT - public: - ParseManager(); - virtual ~ParseManager(); - void setIncludePath(const QStringList &includePath); - void parse(const QStringList &sourceFiles); - bool checkAllMetadatas(ParseManager* pInterfaceParserManager, QString resultfile); - CppTools::Internal::CppPreprocessor *getPreProcessor() { return pCppPreprocessor; } - QList<CLASSTREE*> CreateClassLists(bool isInterfaceHeader); - QStringList getErrorMsg() { return m_errormsgs; } - - private: - void parse(CppTools::Internal::CppPreprocessor *preproc, const QStringList &files); - void Trace(QString value); - inline QString getTraceFuntionString(const FUNCTIONITEM* fctitem, const QString& classname); - void getBaseClasses(const CLASSLISTITEM* pclass - , QList<CLASSLISTITEM*> &baseclasslist - , const QList<CLASSLISTITEM*> &allclasslist - , int level - , bool isInterfaceHeader); - void getElements(QList<FUNCTIONITEM*> &functionlist - , QList<PROPERTYITEM*> &propertylist - , QList<QENUMITEM*> &qenumlist - , QList<ENUMITEM*> &enumlist - , QList<QFLAGITEM*> &qflaglist - , QList<QDECLAREFLAGSITEM*> &qdeclareflaglist - , const QList<CLASSLISTITEM*> classitems - , const CLASSLISTITEM* highestlevelclass); - - //<--- for Metadata functions checks - QList<FUNCTIONITEM*> checkMetadataFunctions(const QList<QList<FUNCTIONITEM*> > &classfctlist, const QList<QList<FUNCTIONITEM*> > &iclassfctlist); - bool isMetaObjFunction(FUNCTIONITEM* fct); - QList<FUNCTIONITEM*> containsAllMetadataFunction(const QList<FUNCTIONITEM*> &classfctlist, const QList<FUNCTIONITEM*> &iclassfctlist); - QStringList getErrorMessage(FUNCTIONITEM* fct); - //---> - - //<--- for Q_PROPERTY functions checks - QList<PROPERTYITEM*> checkMetadataProperties(const QList<QList<PROPERTYITEM*> > &classproplist - , const QList<QList<FUNCTIONITEM*> > &classfctlist - , const QList<QList<PROPERTYITEM*> > &iclassproplist - , const QList<QList<FUNCTIONITEM*> > &iclassfctlist); - void assignPropertyFunctions(PROPERTYITEM* prop, const QList<QList<FUNCTIONITEM*> > &fctlookuplist); - QList<PROPERTYITEM*> containsAllPropertyFunction(const QList<PROPERTYITEM*> &classproplist, const QList<PROPERTYITEM*> &iclassproplist); - QStringList getErrorMessage(PROPERTYITEM* ppt); - //---> - - //<--- for Q_ENUMS checks - QList<QENUMITEM*> checkMetadataEnums(const QList<QList<QENUMITEM*> > &classqenumlist - , const QList<QList<ENUMITEM*> > &classenumlist - , const QList<QList<QENUMITEM*> > &iclassqenumlist - , const QList<QList<ENUMITEM*> > &iclassenumlist); - QStringList getEnumValueStringList(ENUMITEM *penum, QString mappedenumname = ""); - void assignEnumValues(QENUMITEM* qenum, const QList<QList<ENUMITEM*> > &enumlookuplist); - QList<QENUMITEM*> containsAllEnums(const QList<QENUMITEM*> &classqenumlist, const QList<QENUMITEM*> &iclassqenumlist); - QStringList getErrorMessage(QENUMITEM* qenum); - //---> - - //<--- for QFlags checks ---> - QList<QFLAGITEM*> checkMetadataFlags(const QList<QList<QFLAGITEM*> > &classqflaglist - , const QList<QList<QDECLAREFLAGSITEM*> > &classqdeclareflaglist - , const QList<QList<ENUMITEM*> > &classenumlist - , const QList<QList<QFLAGITEM*> > &iclassqflaglist - , const QList<QList<QDECLAREFLAGSITEM*> > &iclassqdeclareflaglist - , const QList<QList<ENUMITEM*> > &iclassenumlist); - void assignFlagValues(QFLAGITEM* qflags, const QList<QList<QDECLAREFLAGSITEM*> > &qdeclareflagslookuplist, const QList<QList<ENUMITEM*> > &enumlookuplist); - QList<QFLAGITEM*> containsAllFlags(const QList<QFLAGITEM*> &classqflaglist, const QList<QFLAGITEM*> &iclassqflaglist); - QStringList getErrorMessage(QFLAGITEM* pfg); - //---> - - private: - // cache - QStringList m_includePaths; - QStringList m_frameworkPaths; - QByteArray m_definedMacros; - CppTools::Internal::CppPreprocessor* pCppPreprocessor; - QString m_strHeaderFile; - QStringList m_errormsgs; - }; -} -#endif // PARSEMANAGER_H diff --git a/tests/auto/profilewriter/tst_profilewriter.cpp b/tests/auto/profilewriter/tst_profilewriter.cpp index 7dc822f46c..fbcb1b7e78 100644 --- a/tests/auto/profilewriter/tst_profilewriter.cpp +++ b/tests/auto/profilewriter/tst_profilewriter.cpp @@ -38,8 +38,10 @@ static void print(const QString &fileName, int lineNo, const QString &msg) { - if (lineNo) + if (lineNo > 0) qWarning("%s(%d): %s", qPrintable(fileName), lineNo, qPrintable(msg)); + else if (lineNo) + qWarning("%s: %s", qPrintable(fileName), qPrintable(msg)); else qWarning("%s", qPrintable(msg)); } diff --git a/tests/auto/qml/qmldesigner/common/statichelpers.cpp b/tests/auto/qml/qmldesigner/common/statichelpers.cpp index 4b108c4331..7f393423d8 100644 --- a/tests/auto/qml/qmldesigner/common/statichelpers.cpp +++ b/tests/auto/qml/qmldesigner/common/statichelpers.cpp @@ -69,19 +69,6 @@ static QString bareTemplate("import Qt 4.6\n" "}"); static QString contentsTemplate(bareTemplate.arg("Text { id: textChild; x:10; y: 10; text: \"%1\"; %2 }")); - -void printErrors(const QList<QDeclarativeError> &errors, const QString &fileName) -{ - if (errors.isEmpty()) - return; - - qDebug() << "Error loading file \"" << fileName << "\":"; - - foreach (const QDeclarativeError &error, errors) { - qDebug() << error.line() << ":" << error.column() << ": " << error.description(); - } -} - // TODO: this need to e updated for states static bool compareProperty(const AbstractProperty &property1, const AbstractProperty &property2) { diff --git a/tests/auto/qml/qmldesigner/coretests/coretests.pro b/tests/auto/qml/qmldesigner/coretests/coretests.pro index b82c68f5a6..3bdf912656 100644 --- a/tests/auto/qml/qmldesigner/coretests/coretests.pro +++ b/tests/auto/qml/qmldesigner/coretests/coretests.pro @@ -1,21 +1,18 @@ -include(../../../qttest.pri) - -QTCREATOR_SOURCE=$$PWD/../../../../.. -QTCREATOR_BUILD=$$OUT_PWD/../../../../.. +IDE_SOURCE_TREE=$$PWD/../../../../.. +IDE_BUILD_TREE=$$OUT_PWD/../../../../.. # can we check that this is a valid build dir? - OUT_PWD_SAVE=$$OUT_PWD -OUT_PWD=QTCREATOR_BUILD +OUT_PWD=IDE_BUILD_TREE include($$IDE_SOURCE_TREE/src/plugins/qmldesigner/config.pri) +include(../../../qttest.pri) OUT_PWD=$$OUT_PWD_SAVE - LIBS += -L$$IDE_PLUGIN_PATH/QtProject +LIBS += -L$$IDE_LIBRARY_PATH unix: QMAKE_LFLAGS += \'-Wl,-rpath,$${IDE_LIBRARY_PATH}\' \'-Wl,-rpath,$${IDE_PLUGIN_PATH}/QtProject\' QT += script \ network \ - declarative \ webkit # DEFINES+=QTCREATOR_UTILS_STATIC_LIB QML_BUILD_STATIC_LIB @@ -24,10 +21,15 @@ DEFINES+=QT_CREATOR QTCREATOR_TEST INCLUDEPATH += $$IDE_SOURCE_TREE/src/plugins/qmldesigner/designercore/include INCLUDEPATH += $$IDE_SOURCE_TREE/src/plugins/qmldesigner/designercore +INCLUDEPATH += $$IDE_SOURCE_TREE//share/qtcreator/qml/qmlpuppet +INCLUDEPATH += $$IDE_SOURCE_TREE/src/plugins/qmldesigner -include($$IDE_SOURCE_TREE/src/plugins/qmldesigner/designercore/designercore.pri) -include($$IDE_SOURCE_TREE/src/libs/utils/utils.pri) + +include($$IDE_SOURCE_TREE/src/plugins/qmldesigner/designercore/designercore-lib.pri) include($$IDE_SOURCE_TREE/src/plugins/qmljstools/qmljstools.pri) +include($$IDE_SOURCE_TREE/src/libs/utils/utils.pri) +include($$IDE_SOURCE_TREE/src/libs/qmljs/qmljs.pri) +include($$IDE_SOURCE_TREE/src/libs/cplusplus/cplusplus.pri) CONFIG += console CONFIG -= app_bundle diff --git a/tests/auto/qml/qmldesigner/coretests/setupPath.bat b/tests/auto/qml/qmldesigner/coretests/setupPath.bat new file mode 100644 index 0000000000..7355f3c099 --- /dev/null +++ b/tests/auto/qml/qmldesigner/coretests/setupPath.bat @@ -0,0 +1 @@ +@set path=%PATH%;%CD%\..\..\..\..\..\lib\qtcreator\plugins\QtProject\ diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp index 1e9c69dcbf..f69bac1afd 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp @@ -55,17 +55,14 @@ #include <nodelistproperty.h> #include <nodeabstractproperty.h> #include <componenttextmodifier.h> -#include <instances/objectnodeinstance.h> #include <bytearraymodifier.h> #include "testrewriterview.h" +#include <utils/fileutils.h> #include <qmljs/qmljsinterpreter.h> #include <QPlainTextEdit> -#include <private/qdeclarativestate_p.h> -#include <private/qdeclarativemetatype_p.h> -#include <QDeclarativeItem> //TESTED_COMPONENT=src/plugins/qmldesigner/designercore @@ -74,6 +71,7 @@ using namespace QmlDesigner; #include "../common/statichelpers.cpp" #include <qmljstools/qmljsmodelmanager.h> +#include <qmljs/qmljsinterpreter.h> #ifdef Q_OS_MAC # define SHARE_PATH "/Resources" @@ -93,10 +91,17 @@ public: { loadQmlTypeDescriptions(resourcePath()); } - void loadFile(QString fileName) + void updateSourceFiles(const QStringList &files, bool emitDocumentOnDiskChanged) + { + refreshSourceFiles(files, emitDocumentOnDiskChanged).waitForFinished(); + } + + QmlJS::LibraryInfo builtins(const QmlJS::Document::Ptr &) const { - refreshSourceFiles(QStringList() << fileName, false).waitForFinished(); + return QmlJS::LibraryInfo(); } + + }; static void initializeMetaTypeSystem(const QString &resourcePath) @@ -107,9 +112,36 @@ static void initializeMetaTypeSystem(const QString &resourcePath) QDir::Files, QDir::Name); - const QStringList errors = QmlJS::Interpreter::CppQmlTypesLoader::loadQmlTypes(qmlFiles); - foreach (const QString &error, errors) - qWarning() << qPrintable(error); + QStringList errorsAndWarnings; + QmlJS::CppQmlTypesLoader::loadQmlTypes(qmlFiles, &errorsAndWarnings, &errorsAndWarnings); + foreach (const QString &errorAndWarning, errorsAndWarnings) + qWarning() << qPrintable(errorAndWarning); +} + +static QmlDesigner::Model* createModel(const QString &typeName, int major = 1, int minor = 1, Model *metaInfoPropxyModel = 0) +{ + QApplication::processEvents(); + + QmlDesigner::Model *model = QmlDesigner::Model::create(typeName, major, minor, metaInfoPropxyModel); + + QPlainTextEdit *textEdit = new QPlainTextEdit; + QObject::connect(model, SIGNAL(destroyed()), textEdit, SLOT(deleteLater())); + textEdit->setPlainText(QString("import %1 %3.%4; %2{}").arg(typeName.split(".").first()) + .arg(typeName.split(".").last()) + .arg(major) + .arg(minor)); + + NotIndentingTextEditModifier *modifier = new NotIndentingTextEditModifier(textEdit); + modifier->setParent(textEdit); + + QmlDesigner::RewriterView *rewriterView = new QmlDesigner::RewriterView(QmlDesigner::RewriterView::Validate, model); + rewriterView->setCheckSemanticErrors(false); + rewriterView->setTextModifier(modifier); + + model->attachView(rewriterView); + + return model; + } tst_TestCore::tst_TestCore() @@ -130,9 +162,9 @@ void tst_TestCore::initTestCase() // Load plugins #ifdef Q_OS_MAC - const QString pluginPath = QTCREATORDIR "/bin/Qt Creator.app/Contents/PlugIns/QmlDesigner"; + const QString pluginPath = QTCREATORDIR "/bin/Qt Creator.app/Contents/PlugIns/QtCreator/QmlDesigner"; #else - const QString pluginPath = QTCREATORDIR "/lib/qmldesigner"; + const QString pluginPath = QTCREATORDIR "/lib/qtcreator/qmldesigner"; #endif qDebug() << pluginPath; @@ -147,9 +179,18 @@ void tst_TestCore::cleanupTestCase() MetaInfo::clearGlobal(); } +void tst_TestCore::init() +{ + QApplication::processEvents(); +} +void tst_TestCore::cleanup() +{ + QApplication::processEvents(); +} + void tst_TestCore::testModelCreateCoreModel() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> testView(new TestView(model.data())); @@ -168,17 +209,17 @@ void tst_TestCore::loadEmptyCoreModel() textEdit1.setPlainText(file.readAll()); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); model1->attachView(testRewriterView1.data()); QPlainTextEdit textEdit2; - textEdit2.setPlainText("import Qt 4.7; Item{}"); + textEdit2.setPlainText("import QtQuick 1.1; Item{}"); NotIndentingTextEditModifier modifier2(&textEdit2); - QScopedPointer<Model> model2(Model::create("Qt/item")); + QScopedPointer<Model> model2(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView2(new TestRewriterView()); testRewriterView2->setTextModifier(&modifier2); @@ -191,10 +232,10 @@ void tst_TestCore::testRewriterView() { try { QPlainTextEdit textEdit; - textEdit.setPlainText("import Qt 4.7;\n\nItem {\n}\n"); + textEdit.setPlainText("import QtQuick 1.1;\n\nItem {\n}\n"); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -207,15 +248,15 @@ void tst_TestCore::testRewriterView() testRewriterView->setTextModifier(&textModifier); model->attachView(testRewriterView.data()); - ModelNode childNode(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data")); + ModelNode childNode(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data")); QVERIFY(childNode.isValid()); childNode.setId("childNode"); - ModelNode childNode2(addNodeListChild(childNode, "Qt/Rectangle", 4, 7, "data")); + ModelNode childNode2(addNodeListChild(childNode, "QtQuick.Rectangle", 1, 0, "data")); childNode2.setId("childNode2"); - ModelNode childNode3(addNodeListChild(childNode2, "Qt/Rectangle", 4, 7, "data")); + ModelNode childNode3(addNodeListChild(childNode2, "QtQuick.Rectangle", 1, 0, "data")); childNode3.setId("childNode3"); - ModelNode childNode4(addNodeListChild(childNode3, "Qt/Rectangle", 4, 7, "data")); + ModelNode childNode4(addNodeListChild(childNode3, "QtQuick.Rectangle", 1, 0, "data")); childNode4.setId("childNode4"); QVERIFY(childNode.isValid()); @@ -241,7 +282,7 @@ void tst_TestCore::testRewriterView() testRewriterView->modelToTextMerger()->applyChanges(); - childNode = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(testRewriterView->modelToTextMerger()->isNodeScheduledForAddition(childNode)); testRewriterView->modelToTextMerger()->applyChanges(); @@ -261,10 +302,10 @@ void tst_TestCore::testRewriterView() void tst_TestCore::testRewriterErrors() { QPlainTextEdit textEdit; - textEdit.setPlainText("import Qt 4.7;\n\nItem {\n}\n"); + textEdit.setPlainText("import QtQuick 1.1;\n\nItem {\n}\n"); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -278,16 +319,15 @@ void tst_TestCore::testRewriterErrors() model->attachView(testRewriterView.data()); QVERIFY(testRewriterView->errors().isEmpty()); - textEdit.setPlainText("import Qt 4.7;\n\nError {\n}\n"); + textEdit.setPlainText("import QtQuick 1.1;\nRectangle {\ntest: blah\n}\n"); QVERIFY(!testRewriterView->errors().isEmpty()); - textEdit.setPlainText("import Qt 4.7;\n\nItem {\n}\n"); + textEdit.setPlainText("import QtQuick 1.1;\n\nItem {\n}\n"); QVERIFY(testRewriterView->errors().isEmpty()); } void tst_TestCore::saveEmptyCoreModel() { - QList<QDeclarativeError> errors; QFile file(":/fx/empty.qml"); QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); @@ -295,7 +335,7 @@ void tst_TestCore::saveEmptyCoreModel() textEdit1.setPlainText(file.readAll()); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -307,10 +347,10 @@ void tst_TestCore::saveEmptyCoreModel() modifier1.save(&buffer); QPlainTextEdit textEdit2; - textEdit2.setPlainText("import Qt 4.7; Item{}"); + textEdit2.setPlainText("import QtQuick 1.1; Item{}"); NotIndentingTextEditModifier modifier2(&textEdit2); - QScopedPointer<Model> model2(Model::create("Qt/item")); + QScopedPointer<Model> model2(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView2(new TestRewriterView()); testRewriterView2->setTextModifier(&modifier2); @@ -322,7 +362,6 @@ void tst_TestCore::saveEmptyCoreModel() void tst_TestCore::loadAttributesInCoreModel() { - QList<QDeclarativeError> errors; QFile file(":/fx/attributes.qml"); QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); @@ -330,17 +369,17 @@ void tst_TestCore::loadAttributesInCoreModel() textEdit1.setPlainText(file.readAll()); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); model1->attachView(testRewriterView1.data()); QPlainTextEdit textEdit2; - textEdit2.setPlainText("import Qt 4.7; Item{}"); + textEdit2.setPlainText("import QtQuick 1.1; Item{}"); NotIndentingTextEditModifier modifier2(&textEdit2); - QScopedPointer<Model> model2(Model::create("Qt/item")); + QScopedPointer<Model> model2(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView2(new TestRewriterView()); testRewriterView2->setTextModifier(&modifier2); @@ -365,7 +404,7 @@ void tst_TestCore::saveAttributesInCoreModel() textEdit1.setPlainText(file.readAll()); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -381,7 +420,7 @@ void tst_TestCore::saveAttributesInCoreModel() textEdit2.setPlainText(buffer.data()); NotIndentingTextEditModifier modifier2(&textEdit2); - QScopedPointer<Model> model2(Model::create("Qt/Item")); + QScopedPointer<Model> model2(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView2(new TestRewriterView()); testRewriterView2->setTextModifier(&modifier2); @@ -396,7 +435,7 @@ void tst_TestCore::testModelCreateRect() { try { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -404,7 +443,7 @@ void tst_TestCore::testModelCreateRect() model->attachView(view.data()); QVERIFY(view->rootModelNode().isValid()); - ModelNode childNode = addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(childNode.isValid()); QVERIFY(view->rootModelNode().allDirectSubModelNodes().contains(childNode)); QVERIFY(childNode.parentProperty().parentModelNode() == view->rootModelNode()); @@ -423,7 +462,7 @@ void tst_TestCore::testModelCreateRect() QCOMPARE(childNode.propertyNames().count(), 4); QCOMPARE(childNode.variantProperty("scale").value(), QVariant()); - } catch (Exception &exception) { + } catch (Exception &) { QFAIL("Exception thrown"); } @@ -432,7 +471,7 @@ void tst_TestCore::testModelCreateRect() void tst_TestCore::testRewriterDynamicProperties() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " property int i\n" @@ -459,7 +498,7 @@ void tst_TestCore::testRewriterDynamicProperties() textEdit1.setPlainText(qmlString); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -549,10 +588,10 @@ void tst_TestCore::testRewriterDynamicProperties() // test model2text // QPlainTextEdit textEdit2; -// textEdit2.setPlainText("import Qt 4.7; Item{}"); +// textEdit2.setPlainText("import QtQuick 1.1; Item{}"); // NotIndentingTextEditModifier modifier2(&textEdit2); // -// QScopedPointer<Model> model2(Model::create("Qt/Item")); +// QScopedPointer<Model> model2(Model::create("QtQuick.Item")); // // QScopedPointer<TestRewriterView> testRewriterView2(new TestRewriterView()); // testRewriterView2->setTextModifier(&modifier2); @@ -566,7 +605,7 @@ void tst_TestCore::testRewriterDynamicProperties() void tst_TestCore::testRewriterGroupedProperties() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Text {\n" " font {\n" @@ -579,7 +618,7 @@ void tst_TestCore::testRewriterGroupedProperties() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier modifier1(&textEdit); - QScopedPointer<Model> model1(Model::create("Qt/Text")); + QScopedPointer<Model> model1(Model::create("QtQuick.Text")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -603,7 +642,7 @@ void tst_TestCore::testRewriterGroupedProperties() rootModelNode.removeProperty(QLatin1String("font.pointSize")); const QLatin1String expected("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Text {\n" "}\n"); @@ -614,7 +653,7 @@ void tst_TestCore::testRewriterGroupedProperties() void tst_TestCore::testRewriterPreserveOrder() { const QLatin1String qmlString1("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "width: 640\n" @@ -635,7 +674,7 @@ void tst_TestCore::testRewriterPreserveOrder() "}\n" "}\n"); const QLatin1String qmlString2("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "width: 640\n" @@ -661,7 +700,7 @@ void tst_TestCore::testRewriterPreserveOrder() textEdit.setPlainText(qmlString2); NotIndentingTextEditModifier modifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Text")); + QScopedPointer<Model> model(Model::create("QtQuick.Text")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&modifier); @@ -674,7 +713,7 @@ void tst_TestCore::testRewriterPreserveOrder() RewriterTransaction transaction = testRewriterView->beginRewriterTransaction(); - ModelNode newModelNode = testRewriterView->createModelNode("Qt/Rectangle", 4, 7); + ModelNode newModelNode = testRewriterView->createModelNode("QtQuick.Rectangle", 1, 0); newModelNode.setParentProperty(rootModelNode.nodeAbstractProperty("data")); @@ -696,7 +735,7 @@ void tst_TestCore::testRewriterPreserveOrder() textEdit.setPlainText(qmlString1); NotIndentingTextEditModifier modifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Text")); + QScopedPointer<Model> model(Model::create("QtQuick.Text")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&modifier); @@ -709,7 +748,7 @@ void tst_TestCore::testRewriterPreserveOrder() RewriterTransaction transaction = testRewriterView->beginRewriterTransaction(); - ModelNode newModelNode = testRewriterView->createModelNode("Qt/Rectangle", 4, 7); + ModelNode newModelNode = testRewriterView->createModelNode("QtQuick.Rectangle", 1, 0); newModelNode.setParentProperty(rootModelNode.nodeAbstractProperty("data")); @@ -730,7 +769,7 @@ void tst_TestCore::testRewriterPreserveOrder() void tst_TestCore::testRewriterActionCompression() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " id: root\n" @@ -750,7 +789,7 @@ void tst_TestCore::testRewriterActionCompression() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier modifier1(&textEdit); - QScopedPointer<Model> model1(Model::create("Qt/Rectangle")); + QScopedPointer<Model> model1(Model::create("QtQuick.Rectangle")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&modifier1); @@ -776,7 +815,7 @@ void tst_TestCore::testRewriterActionCompression() transaction.commit(); const QLatin1String expected("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " id: root\n" @@ -804,7 +843,7 @@ void tst_TestCore::testRewriterImports() textEdit.setPlainText(file.readAll()); NotIndentingTextEditModifier modifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); model->setFileUrl(QUrl::fromLocalFile(fileName)); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -815,12 +854,12 @@ void tst_TestCore::testRewriterImports() QVERIFY(model->imports().size() == 3); - // import Qt 4.7 + // import QtQuick 1.1 Import import = model->imports().at(0); QVERIFY(import.isLibraryImport()); - QCOMPARE(import.url(), QString("Qt")); + QCOMPARE(import.url(), QString("QtQuick")); QVERIFY(import.hasVersion()); - QCOMPARE(import.version(), QString("4.7")); + QCOMPARE(import.version(), QString("1.0")); QVERIFY(!import.hasAlias()); // import "subitems" @@ -843,7 +882,7 @@ void tst_TestCore::testRewriterImports() void tst_TestCore::testRewriterChangeImports() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {}\n"); @@ -851,7 +890,7 @@ void tst_TestCore::testRewriterChangeImports() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier modifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Rectangle")); + QScopedPointer<Model> model(Model::create("QtQuick.Rectangle")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView(0, RewriterView::Amend)); testRewriterView->setTextModifier(&modifier); @@ -870,7 +909,7 @@ void tst_TestCore::testRewriterChangeImports() model->changeImports(importList, QList<Import>()); const QLatin1String qmlWithImport("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "import QtWebKit 1.0\n" "\n" "Rectangle {}\n"); @@ -879,7 +918,7 @@ void tst_TestCore::testRewriterChangeImports() model->changeImports(QList<Import>(), importList); QCOMPARE(model->imports().size(), 1); - QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + QCOMPARE(model->imports().first(), Import::createLibraryImport("QtQuick", "1.1")); QCOMPARE(textEdit.toPlainText(), qmlString); @@ -887,45 +926,45 @@ void tst_TestCore::testRewriterChangeImports() // // Add / Remove an import in the model (with alias) // - model->changeImports(importList, QList<Import>()); + + Import webkitImportAlias = Import::createLibraryImport("QtWebKit", "1.0", "Web"); + + model->changeImports(QList<Import>() << webkitImportAlias, QList<Import>() << webkitImport); const QLatin1String qmlWithAliasImport("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "import QtWebKit 1.0 as Web\n" "\n" "Rectangle {}\n"); QCOMPARE(textEdit.toPlainText(), qmlWithAliasImport); - model->changeImports(QList<Import>(), importList); - - QCOMPARE(model->imports().size(), 1); - QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + model->changeImports(QList<Import>(), QList<Import>() << webkitImportAlias); + QCOMPARE(model->imports().first(), Import::createLibraryImport("QtQuick", "1.1")); QCOMPARE(textEdit.toPlainText(), qmlString); - // // Add / Remove an import in text // textEdit.setPlainText(qmlWithImport); QCOMPARE(model->imports().size(), 2); - QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + QCOMPARE(model->imports().first(), Import::createLibraryImport("QtQuick", "1.1")); QCOMPARE(model->imports().last(), Import::createLibraryImport("QtWebKit", "1.0")); textEdit.setPlainText(qmlWithAliasImport); QCOMPARE(model->imports().size(), 2); - QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + QCOMPARE(model->imports().first(), Import::createLibraryImport("QtQuick", "1.1")); QCOMPARE(model->imports().last(), Import::createLibraryImport("QtWebKit", "1.0", "Web")); textEdit.setPlainText(qmlString); QCOMPARE(model->imports().size(), 1); - QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + QCOMPARE(model->imports().first(), Import::createLibraryImport("QtQuick", "1.1")); } void tst_TestCore::testRewriterForGradientMagic() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " id: root\n" @@ -963,7 +1002,7 @@ void tst_TestCore::testRewriterForGradientMagic() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier modifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Text")); + QScopedPointer<Model> model(Model::create("QtQuick.Text")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&modifier); @@ -979,7 +1018,7 @@ void tst_TestCore::testRewriterForGradientMagic() myRect.variantProperty("rotation") = QVariant(45); QVERIFY(myRect.isValid()); - QScopedPointer<Model> model1(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model1(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model1.data()); QScopedPointer<TestView> view1(new TestView(model1.data())); @@ -987,7 +1026,7 @@ void tst_TestCore::testRewriterForGradientMagic() QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Item {}"); + textEdit1.setPlainText("import QtQuick 1.1; Item {}"); NotIndentingTextEditModifier modifier1(&textEdit1); testRewriterView1->setTextModifier(&modifier1); @@ -1013,7 +1052,7 @@ void tst_TestCore::loadSubItems() textEdit1.setPlainText(file.readAll()); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -1022,16 +1061,16 @@ void tst_TestCore::loadSubItems() void tst_TestCore::createInvalidCoreModel() { - QScopedPointer<Model> invalidModel(Model::create("ItemSUX")); + QScopedPointer<Model> invalidModel(createModel("ItemSUX")); //QVERIFY(!invalidModel.data()); //#no direct ype checking in model atm - QScopedPointer<Model> invalidModel2(Model::create("InvalidNode")); + QScopedPointer<Model> invalidModel2(createModel("InvalidNode")); //QVERIFY(!invalidModel2.data()); } void tst_TestCore::testModelCreateSubNode() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1043,7 +1082,7 @@ void tst_TestCore::testModelCreateSubNode() QCOMPARE(view->methodCalls(), expectedCalls); QVERIFY(view->rootModelNode().isValid()); - ModelNode childNode = addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(childNode.isValid()); QVERIFY(view->rootModelNode().allDirectSubModelNodes().contains(childNode)); QVERIFY(childNode.parentProperty().parentModelNode() == view->rootModelNode()); @@ -1077,7 +1116,7 @@ void tst_TestCore::testModelCreateSubNode() void tst_TestCore::testTypicalRewriterOperations() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1087,46 +1126,46 @@ void tst_TestCore::testTypicalRewriterOperations() ModelNode rootModelNode = view->rootModelNode(); QCOMPARE(rootModelNode.allDirectSubModelNodes().count(), 0); - QVERIFY(rootModelNode.property("test").isValid()); - QVERIFY(!rootModelNode.property("test").isVariantProperty()); - QVERIFY(!rootModelNode.property("test").isBindingProperty()); + QVERIFY(rootModelNode.property("x").isValid()); + QVERIFY(!rootModelNode.property("x").isVariantProperty()); + QVERIFY(!rootModelNode.property("x").isBindingProperty()); - QVERIFY(rootModelNode.variantProperty("test").isValid()); - QVERIFY(!rootModelNode.hasProperty("test")); + QVERIFY(rootModelNode.variantProperty("x").isValid()); + QVERIFY(!rootModelNode.hasProperty("x")); - rootModelNode.variantProperty("test") = 70; + rootModelNode.variantProperty("x") = 70; - QVERIFY(rootModelNode.hasProperty("test")); - QVERIFY(rootModelNode.property("test").isVariantProperty()); - QCOMPARE(rootModelNode.variantProperty("test").value(), QVariant(70)); + QVERIFY(rootModelNode.hasProperty("x")); + QVERIFY(rootModelNode.property("x").isVariantProperty()); + QCOMPARE(rootModelNode.variantProperty("x").value(), QVariant(70)); - rootModelNode.bindingProperty("test") = "parent.x"; - QVERIFY(!rootModelNode.property("test").isVariantProperty()); - QVERIFY(rootModelNode.property("test").isBindingProperty()); + rootModelNode.bindingProperty("x") = "parent.x"; + QVERIFY(!rootModelNode.property("x").isVariantProperty()); + QVERIFY(rootModelNode.property("x").isBindingProperty()); - QCOMPARE(rootModelNode.bindingProperty("test").expression(), QString("parent.x")); + QCOMPARE(rootModelNode.bindingProperty("x").expression(), QString("parent.x")); - ModelNode childNode(addNodeListChild(rootModelNode, "Qt/Rectangle", 4 ,6, "data")); - rootModelNode.nodeListProperty("test").reparentHere(childNode); - QCOMPARE(childNode.parentProperty(), rootModelNode.nodeAbstractProperty("test")); - QVERIFY(rootModelNode.property("test").isNodeAbstractProperty()); - QVERIFY(rootModelNode.property("test").isNodeListProperty()); - QVERIFY(!rootModelNode.property("test").isBindingProperty()); + ModelNode childNode(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1 ,0, "data")); + rootModelNode.nodeListProperty("data").reparentHere(childNode); + QCOMPARE(childNode.parentProperty(), rootModelNode.nodeAbstractProperty("data")); + QVERIFY(rootModelNode.property("data").isNodeAbstractProperty()); + QVERIFY(rootModelNode.property("data").isNodeListProperty()); + QVERIFY(!rootModelNode.property("data").isBindingProperty()); QVERIFY(childNode.parentProperty().isNodeListProperty()); QCOMPARE(childNode, childNode.parentProperty().toNodeListProperty().toModelNodeList().first()); QCOMPARE(rootModelNode, childNode.parentProperty().parentModelNode()); - QCOMPARE(childNode.parentProperty().name(), QString("test")); + QCOMPARE(childNode.parentProperty().name(), QString("data")); - QVERIFY(!rootModelNode.property("test").isVariantProperty()); - rootModelNode.variantProperty("test") = 90; - QVERIFY(rootModelNode.property("test").isVariantProperty()); - QCOMPARE(rootModelNode.variantProperty("test").value(), QVariant(90)); + QVERIFY(!rootModelNode.property("x").isVariantProperty()); + rootModelNode.variantProperty("x") = 90; + QVERIFY(rootModelNode.property("x").isVariantProperty()); + QCOMPARE(rootModelNode.variantProperty("x").value(), QVariant(90)); } void tst_TestCore::testBasicStates() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "id: root;\n" "Rectangle {\n" @@ -1165,7 +1204,7 @@ void tst_TestCore::testBasicStates() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1174,13 +1213,13 @@ void tst_TestCore::testBasicStates() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&textModifier); model->attachView(testRewriterView.data()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Rectangle")); QVERIFY(rootModelNode.hasProperty("data")); @@ -1213,6 +1252,7 @@ void tst_TestCore::testBasicStates() QCOMPARE(state1.propertyChanges().count(), 2); QCOMPARE(state2.propertyChanges().count(), 2); + QVERIFY(state1.propertyChanges().first().modelNode().metaInfo().isSubclassOf("<cpp>.QDeclarative1StateOperation", -1, -1)); QVERIFY(!state1.hasPropertyChanges(rootModelNode)); QVERIFY(state1.propertyChanges(rect1).isValid()); @@ -1275,10 +1315,117 @@ void tst_TestCore::testBasicStates() // QCOMPARE(rect2Instance.property("x").toInt(), 0); } +void tst_TestCore::testBasicStatesQtQuick20() +{ + char qmlString[] = "import QtQuick 2.0\n" + "Rectangle {\n" + "id: root;\n" + "Rectangle {\n" + "id: rect1;\n" + "}\n" + "Rectangle {\n" + "id: rect2;\n" + "}\n" + "states: [\n" + "State {\n" + "name: \"state1\"\n" + "PropertyChanges {\n" + "target: rect1\n" + "}\n" + "PropertyChanges {\n" + "target: rect2\n" + "}\n" + "}\n" + "," + "State {\n" + "name: \"state2\"\n" + "PropertyChanges {\n" + "target: rect1\n" + "}\n" + "PropertyChanges {\n" + "target: rect2;\n" + "x: 10;\n" + "}\n" + "}\n" + "]\n" + "}\n"; + + Exception::setShouldAssert(true); + + QPlainTextEdit textEdit; + textEdit.setPlainText(qmlString); + NotIndentingTextEditModifier textModifier(&textEdit); + + QScopedPointer<Model> model(Model::create("QtQuick.Item")); + QVERIFY(model.data()); + + QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); + testRewriterView->setTextModifier(&textModifier); + model->attachView(testRewriterView.data()); + + ModelNode rootModelNode(testRewriterView->rootModelNode()); + QVERIFY(rootModelNode.isValid()); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Rectangle")); + QCOMPARE(rootModelNode.majorVersion(), 2); + QCOMPARE(rootModelNode.majorQtQuickVersion(), 2); + + qDebug() << rootModelNode.nodeListProperty("states").toModelNodeList().first().metaInfo().majorVersion(); + qDebug() << rootModelNode.nodeListProperty("states").toModelNodeList().first().metaInfo().typeName(); + + QSKIP("No qml2puppet", SkipAll); + + QScopedPointer<TestView> view(new TestView(model.data())); + QVERIFY(view.data()); + model->attachView(view.data()); + + QVERIFY(rootModelNode.hasProperty("data")); + + QVERIFY(rootModelNode.property("data").isNodeListProperty()); + + QCOMPARE(rootModelNode.nodeListProperty("data").toModelNodeList().count(), 2); + + ModelNode rect1 = rootModelNode.nodeListProperty("data").toModelNodeList().first(); + ModelNode rect2 = rootModelNode.nodeListProperty("data").toModelNodeList().last(); + + QVERIFY(QmlItemNode(rect1).isValid()); + QVERIFY(QmlItemNode(rect2).isValid()); + + QVERIFY(QmlItemNode(rootModelNode).isValid()); + + QCOMPARE(QmlItemNode(rootModelNode).states().allStates().count(), 2); + QCOMPARE(QmlItemNode(rootModelNode).states().names().count(), 2); + QCOMPARE(QmlItemNode(rootModelNode).states().names().first(), QString("state1")); + QCOMPARE(QmlItemNode(rootModelNode).states().names().last(), QString("state2")); + + // + // QmlModelState API tests + // + QmlModelState state1 = QmlItemNode(rootModelNode).states().state("state1"); + QmlModelState state2 = QmlItemNode(rootModelNode).states().state("state2"); + + QVERIFY(state1.isValid()); + QVERIFY(state2.isValid()); + + QCOMPARE(state1.propertyChanges().count(), 2); + QCOMPARE(state2.propertyChanges().count(), 2); + + QVERIFY(!state1.hasPropertyChanges(rootModelNode)); + + QVERIFY(state1.propertyChanges(rect1).isValid()); + QVERIFY(state1.propertyChanges(rect2).isValid()); + + state1.propertyChanges(rect2).modelNode().hasProperty("x"); + + QCOMPARE(QmlItemNode(rect1).allAffectingStates().count(), 2); + QCOMPARE(QmlItemNode(rect2).allAffectingStates().count(), 2); + QCOMPARE(QmlItemNode(rootModelNode).allAffectingStates().count(), 0); + QCOMPARE(QmlItemNode(rect1).allAffectingStatesOperations().count(), 2); + QCOMPARE(QmlItemNode(rect2).allAffectingStatesOperations().count(), 2); +} + void tst_TestCore::testModelBasicOperations() { - QSKIP("Fix MetaInfo", SkipAll); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Flipable")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1299,8 +1446,8 @@ void tst_TestCore::testModelBasicOperations() QVERIFY(!rootModelNode.hasProperty("width")); QVERIFY(!rootModelNode.hasProperty("children")); - ModelNode childNode1(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "children")); - ModelNode childNode2(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data")); + ModelNode childNode1(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "children")); + ModelNode childNode2(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data")); QVERIFY(childNode1.isValid()); QVERIFY(childNode2.isValid()); @@ -1338,7 +1485,7 @@ void tst_TestCore::testModelBasicOperations() void tst_TestCore::testModelResolveIds() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1348,47 +1495,47 @@ void tst_TestCore::testModelResolveIds() ModelNode rootNode = view->rootModelNode(); rootNode.setId("rootNode"); - ModelNode childNode1(addNodeListChild(rootNode, "Qt/Rectangle", 4, 7, "children")); + ModelNode childNode1(addNodeListChild(rootNode, "QtQuick.Rectangle", 1, 0, "children")); - ModelNode childNode2(addNodeListChild(childNode1, "Qt/Rectangle", 4, 7, "children")); + ModelNode childNode2(addNodeListChild(childNode1, "QtQuick.Flipable", 1, 0, "children")); childNode2.setId("childNode2"); - childNode2.bindingProperty("test").setExpression("parent.parent"); + childNode2.bindingProperty("anchors.fill").setExpression("parent.parent"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), rootNode); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), rootNode); childNode1.setId("childNode1"); - childNode2.bindingProperty("test").setExpression("childNode1.parent"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), rootNode); - childNode2.bindingProperty("test").setExpression("rootNode"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), rootNode); + childNode2.bindingProperty("anchors.fill").setExpression("childNode1.parent"); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), rootNode); + childNode2.bindingProperty("anchors.fill").setExpression("rootNode"); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), rootNode); - ModelNode childNode3(addNodeListChild(childNode2, "Qt/Rectangle", 4, 7, "children")); + ModelNode childNode3(addNodeListChild(childNode2, "QtQuick.Rectangle", 1, 0, "children")); childNode3.setId("childNode3"); childNode2.nodeProperty("front").setModelNode(childNode3); - childNode2.bindingProperty("test").setExpression("childNode3.parent"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), childNode2); - childNode2.bindingProperty("test").setExpression("childNode3.parent.parent"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), childNode1); - childNode2.bindingProperty("test").setExpression("childNode3.parent.parent.parent"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), rootNode); - childNode2.bindingProperty("test").setExpression("childNode3"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), childNode3); - childNode2.bindingProperty("test").setExpression("front"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), childNode3); - childNode2.bindingProperty("test").setExpression("back"); - QVERIFY(!childNode2.bindingProperty("test").resolveToModelNode().isValid()); - childNode2.bindingProperty("test").setExpression("childNode3.parent.front"); - QCOMPARE(childNode2.bindingProperty("test").resolveToModelNode(), childNode3); + childNode2.bindingProperty("anchors.fill").setExpression("childNode3.parent"); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), childNode2); + childNode2.bindingProperty("anchors.fill").setExpression("childNode3.parent.parent"); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), childNode1); + childNode2.bindingProperty("anchors.fill").setExpression("childNode3.parent.parent.parent"); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), rootNode); + childNode2.bindingProperty("anchors.fill").setExpression("childNode3"); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), childNode3); + childNode2.bindingProperty("anchors.fill").setExpression("front"); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), childNode3); + childNode2.bindingProperty("anchors.fill").setExpression("back"); + QVERIFY(!childNode2.bindingProperty("anchors.fill").resolveToModelNode().isValid()); + childNode2.bindingProperty("anchors.fill").setExpression("childNode3.parent.front"); + QCOMPARE(childNode2.bindingProperty("anchors.fill").resolveToModelNode(), childNode3); childNode2.variantProperty("x") = 10; QCOMPARE(childNode2.variantProperty("x").value().toInt(), 10); - childNode2.bindingProperty("test").setExpression("childNode3.parent.x"); - QVERIFY(childNode2.bindingProperty("test").resolveToProperty().isVariantProperty()); - QCOMPARE(childNode2.bindingProperty("test").resolveToProperty().toVariantProperty().value().toInt(), 10); + childNode2.bindingProperty("width").setExpression("childNode3.parent.x"); + QVERIFY(childNode2.bindingProperty("width").resolveToProperty().isVariantProperty()); + QCOMPARE(childNode2.bindingProperty("width").resolveToProperty().toVariantProperty().value().toInt(), 10); - childNode2.bindingProperty("test").setExpression("childNode3.parent.test"); - QVERIFY(childNode2.bindingProperty("test").resolveToProperty().isBindingProperty()); - QCOMPARE(childNode2.bindingProperty("test").resolveToProperty().toBindingProperty().expression(), QString("childNode3.parent.test")); + childNode2.bindingProperty("width").setExpression("childNode3.parent.width"); + QVERIFY(childNode2.bindingProperty("width").resolveToProperty().isBindingProperty()); + QCOMPARE(childNode2.bindingProperty("width").resolveToProperty().toBindingProperty().expression(), QString("childNode3.parent.width")); } void tst_TestCore::testModelNodeListProperty() @@ -1396,7 +1543,7 @@ void tst_TestCore::testModelNodeListProperty() // // Test NodeListProperty API // - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1414,7 +1561,7 @@ void tst_TestCore::testModelNodeListProperty() QVERIFY(!rootChildren.isNodeListProperty()); QVERIFY(rootChildren.isEmpty()); - ModelNode rectNode = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode rectNode = view->createModelNode("QtQuick.Rectangle", 1, 0); rootChildren.reparentHere(rectNode); // @@ -1425,7 +1572,7 @@ void tst_TestCore::testModelNodeListProperty() QVERIFY(rootChildren.isNodeListProperty()); QVERIFY(!rootChildren.isEmpty()); - ModelNode mouseAreaNode = view->createModelNode("Qt/Item", 4, 7); + ModelNode mouseAreaNode = view->createModelNode("QtQuick.Item", 1, 1); NodeListProperty rectChildren = rectNode.nodeListProperty("children"); rectChildren.reparentHere(mouseAreaNode); @@ -1453,7 +1600,7 @@ void tst_TestCore::testModelNodeListProperty() void tst_TestCore::testBasicOperationsWithView() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1467,10 +1614,6 @@ void tst_TestCore::testBasicOperationsWithView() QCOMPARE(rootModelNode.allDirectSubModelNodes().count(), 0); NodeInstance rootInstance = nodeInstanceView->instanceForNode(rootModelNode); - // no width, height specified implicitly is set to 100x100 - QCOMPARE(rootInstance.size().width(), 100.0); - QCOMPARE(rootInstance.size().height(), 100.0); - QVERIFY(rootInstance.isValid()); QVERIFY(rootModelNode.isValid()); @@ -1484,8 +1627,8 @@ void tst_TestCore::testBasicOperationsWithView() QCOMPARE(rootInstance.size().width(), 10.0); QCOMPARE(rootInstance.size().height(), 10.0); - ModelNode childNode(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data")); - ModelNode childNode2(addNodeListChild(childNode, "Qt/Rectangle", 4, 7, "data")); + ModelNode childNode(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data")); + ModelNode childNode2(addNodeListChild(childNode, "QtQuick.Rectangle", 1, 0, "data")); QVERIFY(childNode2.parentProperty().parentModelNode() == childNode); QVERIFY(childNode.isValid()); @@ -1519,10 +1662,10 @@ void tst_TestCore::testBasicOperationsWithView() QVERIFY(!childInstance2.isValid()); } - childNode = addNodeListChild(rootModelNode, "Qt/Image", 4, 7, "data"); + childNode = addNodeListChild(rootModelNode, "QtQuick.Image", 1, 0, "data"); QVERIFY(childNode.isValid()); - QCOMPARE(childNode.type(), QString("Qt/Image")); - childNode2 = addNodeListChild(childNode, "Qt/Rectangle", 4, 7, "data"); + QCOMPARE(childNode.type(), QString("QtQuick.Image")); + childNode2 = addNodeListChild(childNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(childNode2.isValid()); childNode2.setParentProperty(rootModelNode, "data"); QVERIFY(childNode2.isValid()); @@ -1560,7 +1703,7 @@ void tst_TestCore::testBasicOperationsWithView() void tst_TestCore::testQmlModelView() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QmlModelView *view = new TestView(model.data()); @@ -1578,7 +1721,7 @@ void tst_TestCore::testQmlModelView() propertyList.append(qMakePair(QString("width"), QVariant(20))); propertyList.append(qMakePair(QString("height"), QVariant(20))); - QmlObjectNode node1 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); + QmlObjectNode node1 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); QVERIFY(node1.isValid()); QVERIFY(!node1.hasNodeParent()); @@ -1594,7 +1737,7 @@ void tst_TestCore::testQmlModelView() QVERIFY(node1.instanceParent() == view->rootQmlObjectNode()); - QmlObjectNode node2 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); + QmlObjectNode node2 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); QVERIFY(node2.isValid()); QVERIFY(!node2.hasNodeParent()); @@ -1622,12 +1765,12 @@ void tst_TestCore::testQmlModelView() QCOMPARE(node1.instanceValue("x").toInt(), 2); - QmlObjectNode node3 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); - QmlObjectNode node4 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); - QmlObjectNode node5 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); - QmlObjectNode node6 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); - QmlObjectNode node7 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); - QmlObjectNode node8 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); + QmlObjectNode node3 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); + QmlObjectNode node4 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); + QmlObjectNode node5 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); + QmlObjectNode node6 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); + QmlObjectNode node7 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); + QmlObjectNode node8 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); node3.setParentProperty(node2.nodeAbstractProperty("children")); node4.setParentProperty(node3.nodeAbstractProperty("children")); @@ -1655,21 +1798,20 @@ void tst_TestCore::testQmlModelView() QCOMPARE(node2.instanceValue("x").toInt(), 10); // is this right? or should it be a invalid qvariant? - node1 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); + node1 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); node1.setId("node1"); QCOMPARE(node2.instanceValue("x").toInt(), 20); - node3 = view->createQmlObjectNode("Qt/Rectangle", 4, 7, propertyList); + node3 = view->createQmlObjectNode("QtQuick.Rectangle", 1, 0, propertyList); node3.setParentProperty(node2.nodeAbstractProperty("children")); QCOMPARE(node3.instanceValue("width").toInt(), 20); node3.setVariantProperty("width", 0); QCOMPARE(node3.instanceValue("width").toInt(), 0); QCOMPARE(node3.instanceValue("x").toInt(), 20); - QVERIFY(!QDeclarativeMetaType::toQObject(node3.instanceValue("anchors.fill"))); + //QVERIFY(!QDeclarativeMetaType::toQObject(node3.instanceValue("anchors.fill"))); node3.setBindingProperty("anchors.fill", "parent"); - QVERIFY(QDeclarativeMetaType::toQObject(node3.instanceValue("anchors.fill"))); QCOMPARE(node3.instanceValue("x").toInt(), 0); QCOMPARE(node3.instanceValue("width").toInt(), 20); @@ -1682,7 +1824,7 @@ void tst_TestCore::testQmlModelView() void tst_TestCore::testModelRemoveNode() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1695,7 +1837,7 @@ void tst_TestCore::testModelRemoveNode() QCOMPARE(view->rootModelNode().allDirectSubModelNodes().count(), 0); - ModelNode childNode = addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(childNode.isValid()); QCOMPARE(view->rootModelNode().allDirectSubModelNodes().count(), 1); QVERIFY(view->rootModelNode().allDirectSubModelNodes().contains(childNode)); @@ -1707,7 +1849,7 @@ void tst_TestCore::testModelRemoveNode() QVERIFY(childInstance.parentId() == view->rootModelNode().internalId()); } - ModelNode subChildNode = addNodeListChild(childNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode subChildNode = addNodeListChild(childNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(subChildNode.isValid()); QCOMPARE(childNode.allDirectSubModelNodes().count(), 1); QVERIFY(childNode.allDirectSubModelNodes().contains(subChildNode)); @@ -1738,7 +1880,7 @@ void tst_TestCore::testModelRemoveNode() QVERIFY(view->rootModelNode().isValid()); // delete node not in hierarchy - childNode = view->createModelNode("Qt/Item", 4, 7); + childNode = view->createModelNode("QtQuick.Item", 1, 1); childNode.destroy(); model->detachView(nodeInstanceView); @@ -1746,7 +1888,7 @@ void tst_TestCore::testModelRemoveNode() void tst_TestCore::reparentingNode() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); @@ -1763,7 +1905,7 @@ void tst_TestCore::reparentingNode() NodeInstanceView *nodeInstanceView = new NodeInstanceView(model.data(), NodeInstanceServerInterface::TestModus); model->attachView(nodeInstanceView); - ModelNode childNode = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); QCOMPARE(childNode.parentProperty().parentModelNode(), rootModelNode); QVERIFY(rootModelNode.allDirectSubModelNodes().contains(childNode)); @@ -1773,7 +1915,7 @@ void tst_TestCore::reparentingNode() QVERIFY(childInstance.parentId() == view->rootModelNode().internalId()); } - ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/Item", 4, 7, "data"); + ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.Item", 1, 1, "data"); QCOMPARE(childNode2.parentProperty().parentModelNode(), rootModelNode); QVERIFY(rootModelNode.allDirectSubModelNodes().contains(childNode2)); @@ -1808,16 +1950,17 @@ void tst_TestCore::reparentingNode() QCOMPARE(childNode.parentProperty().parentModelNode(), childNode2); + QApplication::processEvents(); model->detachView(nodeInstanceView); } void tst_TestCore::reparentingNodeLikeDragAndDrop() { QPlainTextEdit textEdit; - textEdit.setPlainText("import Qt 4.7;\n\nItem {\n}\n"); + textEdit.setPlainText("import QtQuick 1.1;\n\nItem {\n}\n"); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -1833,7 +1976,7 @@ void tst_TestCore::reparentingNodeLikeDragAndDrop() view->rootModelNode().setId("rootModelNode"); QCOMPARE(view->rootModelNode().id(), QString("rootModelNode")); - ModelNode rectNode = addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data"); + ModelNode rectNode = addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data"); rectNode.setId("rect_1"); rectNode.variantProperty("x").setValue(20); rectNode.variantProperty("y").setValue(30); @@ -1842,7 +1985,7 @@ void tst_TestCore::reparentingNodeLikeDragAndDrop() RewriterTransaction transaction(view->beginRewriterTransaction()); - ModelNode textNode = addNodeListChild(view->rootModelNode(), "Qt/Text", 4, 7, "data"); + ModelNode textNode = addNodeListChild(view->rootModelNode(), "QtQuick.Text", 1, 1, "data"); QCOMPARE(textNode.parentProperty().parentModelNode(), view->rootModelNode()); QVERIFY(view->rootModelNode().allDirectSubModelNodes().contains(textNode)); @@ -1925,12 +2068,14 @@ void tst_TestCore::reparentingNodeLikeDragAndDrop() QCOMPARE(textNode.parentProperty().parentModelNode(), rectNode); QVERIFY(rectNode.allDirectSubModelNodes().contains(textNode)); + QApplication::processEvents(); + model->detachView(nodeInstanceView); } void tst_TestCore::testModelReorderSiblings() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1943,11 +2088,11 @@ void tst_TestCore::testModelReorderSiblings() ModelNode rootModelNode = view->rootModelNode(); QVERIFY(rootModelNode.isValid()); - ModelNode a = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode a = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(a.isValid()); - ModelNode b = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode b = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(b.isValid()); - ModelNode c = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode c = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(c.isValid()); { @@ -1976,12 +2121,14 @@ void tst_TestCore::testModelReorderSiblings() QVERIFY(nodeInstanceView->instanceForNode(c).parentId() == rootModelNode.internalId()); } + QApplication::processEvents(); + model->detachView(nodeInstanceView); } void tst_TestCore::testModelRootNode() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -1992,10 +2139,10 @@ void tst_TestCore::testModelRootNode() ModelNode rootModelNode = view->rootModelNode(); QVERIFY(rootModelNode.isValid()); QVERIFY(rootModelNode.isRootNode()); - ModelNode topChildNode = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode topChildNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(topChildNode.isValid()); QVERIFY(rootModelNode.isRootNode()); - ModelNode childNode = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(childNode.isValid()); QVERIFY(rootModelNode.isValid()); QVERIFY(rootModelNode.isRootNode()); @@ -2008,19 +2155,20 @@ void tst_TestCore::testModelRootNode() QString errorMsg = tr("Exception: %1 %2 %3:%4").arg(exception.type(), exception.function(), exception.file()).arg(exception.line()); QFAIL(errorMsg.toLatin1().constData()); } + QApplication::processEvents(); } void tst_TestCore::reparentingNodeInModificationGroup() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - ModelNode childNode = addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode2 = addNodeListChild(view->rootModelNode(), "Qt/Item", 4, 7, "data"); + ModelNode childNode = addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode2 = addNodeListChild(view->rootModelNode(), "QtQuick.Item", 1, 1, "data"); childNode.variantProperty("x").setValue(10); childNode.variantProperty("y").setValue(10); @@ -2058,11 +2206,13 @@ void tst_TestCore::reparentingNodeInModificationGroup() QCOMPARE(childNode2.parentProperty().parentModelNode(), view->rootModelNode()); QVERIFY(childNode2.isValid()); QVERIFY(view->rootModelNode().allDirectSubModelNodes().contains(childNode2)); + + QApplication::processEvents(); } void tst_TestCore::testModelAddAndRemoveProperty() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2098,12 +2248,14 @@ void tst_TestCore::testModelAddAndRemoveProperty() QVERIFY(node.hasProperty("foo")); QCOMPARE(node.variantProperty("foo").value().toString(), QString("bar")); + QApplication::processEvents(); + model->detachView(nodeInstanceView); } void tst_TestCore::testModelViewNotification() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view1(new TestView(model.data())); @@ -2125,7 +2277,7 @@ void tst_TestCore::testModelViewNotification() QCOMPARE(view1->methodCalls(), expectedCalls); QCOMPARE(view2->methodCalls(), expectedCalls); - ModelNode childNode = addNodeListChild(view2->rootModelNode(), "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(view2->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data"); expectedCalls << TestView::MethodCall("nodeCreated", QStringList() << ""); expectedCalls << TestView::MethodCall("nodeReparented", QStringList() << "" << "data" << "" << "PropertiesAdded"); QCOMPARE(view1->methodCalls(), expectedCalls); @@ -2155,7 +2307,7 @@ void tst_TestCore::testModelViewNotification() QCOMPARE(view1->methodCalls(), expectedCalls); QCOMPARE(view2->methodCalls(), expectedCalls); - childNode.bindingProperty("visible").setExpression("false"); + childNode.bindingProperty("visible").setExpression("false && true"); expectedCalls << TestView::MethodCall("propertiesAboutToBeRemoved", QStringList() << "visible"); expectedCalls << TestView::MethodCall("bindingPropertiesChanged", QStringList() << "visible" << "PropertiesAdded"); QCOMPARE(view1->methodCalls(), expectedCalls); @@ -2170,12 +2322,14 @@ void tst_TestCore::testModelViewNotification() model->detachView(view1.data()); expectedCalls << TestView::MethodCall("modelAboutToBeDetached", QStringList() << QString::number(reinterpret_cast<long>(model.data()))); QCOMPARE(view1->methodCalls(), expectedCalls); + + QApplication::processEvents(); } void tst_TestCore::testRewriterTransaction() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2185,7 +2339,7 @@ void tst_TestCore::testRewriterTransaction() RewriterTransaction transaction = view->beginRewriterTransaction(); QVERIFY(transaction.isValid()); - ModelNode childNode = addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(childNode.isValid()); childNode.destroy(); @@ -2195,7 +2349,7 @@ void tst_TestCore::testRewriterTransaction() RewriterTransaction transaction2 = view->beginRewriterTransaction(); QVERIFY(transaction2.isValid()); - ModelNode childNode = addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(childNode.isValid()); childNode.destroy(); @@ -2222,7 +2376,7 @@ void tst_TestCore::testRewriterTransaction() void tst_TestCore::testRewriterId() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "}\n"; @@ -2230,7 +2384,7 @@ void tst_TestCore::testRewriterId() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2245,16 +2399,16 @@ void tst_TestCore::testRewriterId() model->attachView(testRewriterView.data()); - QCOMPARE(rootModelNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Rectangle")); QVERIFY(rootModelNode.isValid()); - ModelNode newNode(view->createModelNode("Qt/Rectangle", 4, 7)); + ModelNode newNode(view->createModelNode("QtQuick.Rectangle", 1, 0)); newNode.setId("testId"); rootModelNode.nodeListProperty("data").reparentHere(newNode); - const QLatin1String expected("import Qt 4.7\n" + const QLatin1String expected("import QtQuick 1.1\n" "Rectangle {\n" "Rectangle {\n" " id: testId\n" @@ -2266,7 +2420,7 @@ void tst_TestCore::testRewriterId() void tst_TestCore::testRewriterNodeReparentingTransaction1() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "}\n"; @@ -2274,7 +2428,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction1() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2283,7 +2437,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction1() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&textModifier); @@ -2291,12 +2445,12 @@ void tst_TestCore::testRewriterNodeReparentingTransaction1() QVERIFY(rootModelNode.isValid()); - ModelNode childNode1 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode3 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode4 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode1 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode3 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode4 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); - ModelNode reparentNode = addNodeListChild(childNode1, "Qt/Rectangle", 4, 7, "data"); + ModelNode reparentNode = addNodeListChild(childNode1, "QtQuick.Rectangle", 1, 0, "data"); RewriterTransaction rewriterTransaction = view->beginRewriterTransaction(); @@ -2311,7 +2465,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction1() void tst_TestCore::testRewriterNodeReparentingTransaction2() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "}\n"; @@ -2319,7 +2473,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction2() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2328,7 +2482,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction2() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&textModifier); @@ -2336,8 +2490,8 @@ void tst_TestCore::testRewriterNodeReparentingTransaction2() QVERIFY(rootModelNode.isValid()); - ModelNode childNode1 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode1 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); childNode2.variantProperty("x") = 200; childNode2.variantProperty("y") = 50; @@ -2377,7 +2531,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction2() void tst_TestCore::testRewriterNodeReparentingTransaction3() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "}\n"; @@ -2385,7 +2539,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction3() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2394,7 +2548,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction3() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&textModifier); @@ -2402,10 +2556,10 @@ void tst_TestCore::testRewriterNodeReparentingTransaction3() QVERIFY(rootModelNode.isValid()); - ModelNode childNode1 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode3 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode4 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode1 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode3 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode4 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); RewriterTransaction rewriterTransaction = view->beginRewriterTransaction(); @@ -2427,7 +2581,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction3() void tst_TestCore::testRewriterNodeReparentingTransaction4() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "}\n"; @@ -2435,7 +2589,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction4() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2444,7 +2598,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction4() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&textModifier); @@ -2452,11 +2606,11 @@ void tst_TestCore::testRewriterNodeReparentingTransaction4() QVERIFY(rootModelNode.isValid()); - ModelNode childNode1 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode3 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode4 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); - ModelNode childNode5 = addNodeListChild(childNode2, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode1 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode3 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode4 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); + ModelNode childNode5 = addNodeListChild(childNode2, "QtQuick.Rectangle", 1, 0, "data"); RewriterTransaction rewriterTransaction = view->beginRewriterTransaction(); @@ -2478,7 +2632,7 @@ void tst_TestCore::testRewriterNodeReparentingTransaction4() void tst_TestCore::testRewriterAddNodeTransaction() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "}\n"; @@ -2486,7 +2640,7 @@ void tst_TestCore::testRewriterAddNodeTransaction() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2495,7 +2649,7 @@ void tst_TestCore::testRewriterAddNodeTransaction() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&textModifier); @@ -2504,11 +2658,11 @@ void tst_TestCore::testRewriterAddNodeTransaction() QVERIFY(rootModelNode.isValid()); - ModelNode childNode = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); RewriterTransaction rewriterTransaction = view->beginRewriterTransaction(); - ModelNode newNode = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode newNode = view->createModelNode("QtQuick.Rectangle", 1, 0); newNode.variantProperty("x") = 100; newNode.variantProperty("y") = 100; @@ -2520,7 +2674,7 @@ void tst_TestCore::testRewriterAddNodeTransaction() void tst_TestCore::testRewriterComponentId() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" " Component {\n" " id: testComponent\n" @@ -2533,7 +2687,7 @@ void tst_TestCore::testRewriterComponentId() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2546,17 +2700,17 @@ void tst_TestCore::testRewriterComponentId() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Rectangle")); ModelNode component(rootModelNode.allDirectSubModelNodes().first()); QVERIFY(component.isValid()); - QCOMPARE(component.type(), QString("Qt/Component")); + QCOMPARE(component.type(), QString("QtQuick.Component")); QCOMPARE(component.id(), QString("testComponent")); } void tst_TestCore::testRewriterTransactionRewriter() { - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "}\n"; @@ -2564,7 +2718,7 @@ void tst_TestCore::testRewriterTransactionRewriter() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2573,7 +2727,7 @@ void tst_TestCore::testRewriterTransactionRewriter() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&textModifier); @@ -2586,7 +2740,7 @@ void tst_TestCore::testRewriterTransactionRewriter() { RewriterTransaction transaction = view->beginRewriterTransaction(); - childNode1 = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + childNode1 = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); childNode1.variantProperty("x") = 10; childNode1.variantProperty("y") = 10; } @@ -2598,7 +2752,7 @@ void tst_TestCore::testRewriterTransactionRewriter() { RewriterTransaction transaction = view->beginRewriterTransaction(); - childNode2 = addNodeListChild(childNode1, "Qt/Rectangle", 4, 7, "data"); + childNode2 = addNodeListChild(childNode1, "QtQuick.Rectangle", 1, 0, "data"); childNode2.destroy(); } @@ -2623,7 +2777,7 @@ void tst_TestCore::testRewriterPropertyDeclarations() // property variant myArray: [ Rectangle {} ] // property variant someGradient: Gradient {} - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Item {\n" " property int intProperty\n" " property bool boolProperty: true\n" @@ -2636,7 +2790,7 @@ void tst_TestCore::testRewriterPropertyDeclarations() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2654,7 +2808,7 @@ void tst_TestCore::testRewriterPropertyDeclarations() // ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QCOMPARE(rootModelNode.properties().size(), 4); @@ -2687,7 +2841,7 @@ void tst_TestCore::testRewriterPropertyAliases() // where type is (int | bool | double | real | string | url | color | date | variant) // - char qmlString[] = "import Qt 4.7\n" + char qmlString[] = "import QtQuick 1.1\n" "Item {\n" " property alias theText: t.text\n" " default alias property yPos: t.y\n" @@ -2698,7 +2852,7 @@ void tst_TestCore::testRewriterPropertyAliases() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2711,7 +2865,7 @@ void tst_TestCore::testRewriterPropertyAliases() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QList<AbstractProperty> properties = rootModelNode.properties(); QCOMPARE(properties.size(), 0); // TODO: How to represent alias properties? As Bindings? @@ -2720,7 +2874,7 @@ void tst_TestCore::testRewriterPropertyAliases() void tst_TestCore::testRewriterPositionAndOffset() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " id: root\n" @@ -2758,7 +2912,7 @@ void tst_TestCore::testRewriterPositionAndOffset() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2771,7 +2925,7 @@ void tst_TestCore::testRewriterPositionAndOffset() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); QString string = QString(qmlString).mid(testRewriterView->nodeOffset(rootNode), testRewriterView->nodeLength(rootNode)); const QString qmlExpected0("Rectangle {\n" @@ -2837,7 +2991,7 @@ void tst_TestCore::testRewriterPositionAndOffset() void tst_TestCore::testRewriterComponentTextModifier() { - const QString qmlString("import Qt 4.7\n" + const QString qmlString("import QtQuick 1.1\n" "Rectangle {\n" " id: root\n" " x: 10;\n" @@ -2860,7 +3014,7 @@ void tst_TestCore::testRewriterComponentTextModifier() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2873,7 +3027,7 @@ void tst_TestCore::testRewriterComponentTextModifier() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); ModelNode componentNode = rootNode.allDirectSubModelNodes().last(); @@ -2884,7 +3038,7 @@ void tst_TestCore::testRewriterComponentTextModifier() ComponentTextModifier componentTextModifier(&textModifier, componentStartOffset, componentEndOffset, rootStartOffset); - const QString qmlExpected("import Qt 4.7\n" + const QString qmlExpected("import QtQuick 1.1\n" " " " " " " @@ -2905,19 +3059,20 @@ void tst_TestCore::testRewriterComponentTextModifier() QCOMPARE(componentTextModifier.text(), qmlExpected); - QScopedPointer<Model> componentModel(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> componentModel(Model::create("QtQuick.Item", 1, 1)); QScopedPointer<TestRewriterView> testRewriterViewComponent(new TestRewriterView()); testRewriterViewComponent->setTextModifier(&componentTextModifier); componentModel->attachView(testRewriterViewComponent.data()); ModelNode componentrootNode = testRewriterViewComponent->rootModelNode(); QVERIFY(componentrootNode.isValid()); - QCOMPARE(componentrootNode.type(), QLatin1String("Qt/Component")); + //The <Component> node is skipped + QCOMPARE(componentrootNode.type(), QLatin1String("QtQuick.Rectangle")); } void tst_TestCore::testRewriterPreserveType() { - const QString qmlString("import Qt 4.7\n" + const QString qmlString("import QtQuick 1.1\n" "Rectangle {\n" " id: root\n" " Text {\n" @@ -2930,7 +3085,7 @@ void tst_TestCore::testRewriterPreserveType() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2943,7 +3098,7 @@ void tst_TestCore::testRewriterPreserveType() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); ModelNode textNode = rootNode.allDirectSubModelNodes().first(); QCOMPARE(QVariant::Bool, textNode.variantProperty("font.bold").value().type()); @@ -2952,7 +3107,7 @@ void tst_TestCore::testRewriterPreserveType() textNode.variantProperty("font.bold") = QVariant(true); textNode.variantProperty("font.pointSize") = QVariant(13.0); - ModelNode newTextNode = addNodeListChild(rootNode, "Qt/Text", 4, 7, "data"); + ModelNode newTextNode = addNodeListChild(rootNode, "QtQuick.Text", 1, 1, "data"); newTextNode.variantProperty("font.bold") = QVariant(true); newTextNode.variantProperty("font.pointSize") = QVariant(13.0); @@ -2964,7 +3119,7 @@ void tst_TestCore::testRewriterPreserveType() void tst_TestCore::testRewriterForArrayMagic() { try { - const QLatin1String qmlString("import Qt 4.7\n" + const QLatin1String qmlString("import QtQuick 1.1\n" "\n" "Rectangle {\n" " states: State {\n" @@ -2975,7 +3130,7 @@ void tst_TestCore::testRewriterForArrayMagic() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -2988,16 +3143,16 @@ void tst_TestCore::testRewriterForArrayMagic() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); QVERIFY(rootNode.property(QLatin1String("states")).isNodeListProperty()); QmlItemNode rootItem(rootNode); QVERIFY(rootItem.isValid()); QmlModelState state1(rootItem.states().addState("s2")); - QCOMPARE(state1.modelNode().type(), QString("Qt/State")); + QCOMPARE(state1.modelNode().type(), QString("QtQuick.State")); - const QLatin1String expected("import Qt 4.7\n" + const QLatin1String expected("import QtQuick 1.1\n" "\n" "Rectangle {\n" " states: [\n" @@ -3018,7 +3173,7 @@ void tst_TestCore::testRewriterForArrayMagic() void tst_TestCore::testRewriterWithSignals() { - const QLatin1String qmlString("import Qt 4.7\n" + const QLatin1String qmlString("import QtQuick 1.1\n" "\n" "TextEdit {\n" " onTextChanged: { print(\"foo\"); }\n" @@ -3027,7 +3182,7 @@ void tst_TestCore::testRewriterWithSignals() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -3040,7 +3195,7 @@ void tst_TestCore::testRewriterWithSignals() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/TextEdit")); + QCOMPARE(rootNode.type(), QString("QtQuick.TextEdit")); QmlItemNode rootItem(rootNode); QVERIFY(rootItem.isValid()); @@ -3050,7 +3205,7 @@ void tst_TestCore::testRewriterWithSignals() void tst_TestCore::testRewriterNodeSliding() { - const QLatin1String qmlString("import Qt 4.7\n" + const QLatin1String qmlString("import QtQuick 1.1\n" "Rectangle {\n" " id: root\n" " Rectangle {\n" @@ -3070,7 +3225,7 @@ void tst_TestCore::testRewriterNodeSliding() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -3083,7 +3238,7 @@ void tst_TestCore::testRewriterNodeSliding() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); QCOMPARE(rootNode.id(), QLatin1String("root")); QCOMPARE(rootNode.nodeListProperty(QLatin1String("data")).toModelNodeList().at(0).id(), QLatin1String("rectangle1")); @@ -3102,7 +3257,7 @@ void tst_TestCore::testRewriterNodeSliding() void tst_TestCore::testRewriterExceptionHandling() { - const QLatin1String qmlString("import Qt 4.7\n" + const QLatin1String qmlString("import QtQuick 1.1\n" "Text {\n" "}"); @@ -3110,7 +3265,7 @@ void tst_TestCore::testRewriterExceptionHandling() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Text", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Text", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -3123,7 +3278,7 @@ void tst_TestCore::testRewriterExceptionHandling() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Text")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Text")); try { @@ -3132,9 +3287,9 @@ void tst_TestCore::testRewriterExceptionHandling() rootNode.variantProperty("bla") = QVariant("blah"); transaction.commit(); QFAIL("RewritingException should be thrown"); - } catch (RewritingException &e) { + } catch (RewritingException &) { QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Text")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Text")); QVERIFY(!rootNode.hasProperty("bla")); QVERIFY(!rootNode.hasProperty("text")); } @@ -3142,7 +3297,7 @@ void tst_TestCore::testRewriterExceptionHandling() void tst_TestCore::testRewriterFirstDefinitionInside() { - const QString qmlString("import Qt 4.7\n" + const QString qmlString("import QtQuick 1.1\n" "Rectangle {\n" " id: root\n" " x: 10;\n" @@ -3166,7 +3321,7 @@ void tst_TestCore::testRewriterFirstDefinitionInside() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -3179,7 +3334,7 @@ void tst_TestCore::testRewriterFirstDefinitionInside() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); ModelNode componentNode = rootNode.allDirectSubModelNodes().last(); @@ -3198,7 +3353,7 @@ void tst_TestCore::testRewriterFirstDefinitionInside() void tst_TestCore::testCopyModelRewriter1() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " id: root\n" @@ -3236,7 +3391,7 @@ void tst_TestCore::testCopyModelRewriter1() textEdit1.setPlainText(qmlString); NotIndentingTextEditModifier textModifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model1(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model1.data()); QScopedPointer<TestView> view1(new TestView(model1.data())); @@ -3249,13 +3404,13 @@ void tst_TestCore::testCopyModelRewriter1() ModelNode rootNode1 = view1->rootModelNode(); QVERIFY(rootNode1.isValid()); - QCOMPARE(rootNode1.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode1.type(), QLatin1String("QtQuick.Rectangle")); QPlainTextEdit textEdit2; textEdit2.setPlainText(qmlString); NotIndentingTextEditModifier textModifier2(&textEdit2); - QScopedPointer<Model> model2(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model2(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model2.data()); QScopedPointer<TestView> view2(new TestView(model2.data())); @@ -3268,7 +3423,7 @@ void tst_TestCore::testCopyModelRewriter1() ModelNode rootNode2 = view2->rootModelNode(); QVERIFY(rootNode2.isValid()); - QCOMPARE(rootNode2.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode2.type(), QLatin1String("QtQuick.Rectangle")); // @@ -3293,7 +3448,7 @@ void tst_TestCore::testCopyModelRewriter1() const QLatin1String expected( "\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " id: root\n" @@ -3368,7 +3523,7 @@ void tst_TestCore::testCopyModelRewriter1() void tst_TestCore::testCopyModelRewriter2() { const QLatin1String qmlString1("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "id: root\n" @@ -3408,7 +3563,7 @@ void tst_TestCore::testCopyModelRewriter2() const QLatin1String qmlString2("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); @@ -3417,7 +3572,7 @@ void tst_TestCore::testCopyModelRewriter2() textEdit1.setPlainText(qmlString1); NotIndentingTextEditModifier textModifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model1(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model1.data()); QScopedPointer<TestView> view1(new TestView(model1.data())); @@ -3430,7 +3585,7 @@ void tst_TestCore::testCopyModelRewriter2() ModelNode rootNode1 = view1->rootModelNode(); QVERIFY(rootNode1.isValid()); - QCOMPARE(rootNode1.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode1.type(), QLatin1String("QtQuick.Rectangle")); // read in 2 @@ -3439,7 +3594,7 @@ void tst_TestCore::testCopyModelRewriter2() textEdit2.setPlainText(qmlString2); NotIndentingTextEditModifier textModifier2(&textEdit2); - QScopedPointer<Model> model2(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model2(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model2.data()); QScopedPointer<TestView> view2(new TestView(model2.data())); @@ -3451,7 +3606,7 @@ void tst_TestCore::testCopyModelRewriter2() ModelNode rootNode2 = view2->rootModelNode(); QVERIFY(rootNode2.isValid()); - QCOMPARE(rootNode2.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode2.type(), QLatin1String("QtQuick.Rectangle")); // @@ -3460,7 +3615,7 @@ void tst_TestCore::testCopyModelRewriter2() merger.replaceModel(rootNode1); QVERIFY(rootNode2.isValid()); - QCOMPARE(rootNode2.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode2.type(), QLatin1String("QtQuick.Rectangle")); QCOMPARE(textEdit2.toPlainText(), qmlString1); } @@ -3475,9 +3630,9 @@ void tst_TestCore::testSubComponentManager() textEdit.setPlainText(file.readAll()); NotIndentingTextEditModifier modifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); model->setFileUrl(QUrl::fromLocalFile(fileName)); - QScopedPointer<SubComponentManager> subComponentManager(new SubComponentManager(model->metaInfo(), 0)); + QScopedPointer<SubComponentManager> subComponentManager(new SubComponentManager(model.data())); subComponentManager->update(QUrl::fromLocalFile(fileName), model->imports()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -3489,9 +3644,9 @@ void tst_TestCore::testSubComponentManager() QVERIFY(testRewriterView->rootModelNode().isValid()); - QVERIFY(model->metaInfo("Qt/Rectangle").propertyNames().contains("border.width")); + QVERIFY(model->metaInfo("QtQuick.Rectangle").propertyNames().contains("border.width")); - QVERIFY(model->metaInfo("Qt/Pen").isValid()); + QVERIFY(model->metaInfo("<cpp>.QDeclarative1Pen").isValid()); NodeMetaInfo myButtonMetaInfo = model->metaInfo("MyButton"); QVERIFY(myButtonMetaInfo.isValid()); QVERIFY(myButtonMetaInfo.propertyNames().contains("border.width")); @@ -3500,7 +3655,7 @@ void tst_TestCore::testSubComponentManager() void tst_TestCore::testAnchorsAndRewriting() { - const QString qmlString("import Qt 4.7\n" + const QString qmlString("import QtQuick 1.1\n" "Rectangle {\n" " id: root\n" " x: 10;\n" @@ -3523,7 +3678,7 @@ void tst_TestCore::testAnchorsAndRewriting() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -3536,7 +3691,7 @@ void tst_TestCore::testAnchorsAndRewriting() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); QmlItemNode rootItemNode = view->rootQmlItemNode(); QVERIFY(rootItemNode.isValid()); @@ -3561,7 +3716,7 @@ void tst_TestCore::testAnchorsAndRewriting() void tst_TestCore::testAnchorsAndRewritingCenter() { - const QString qmlString("import Qt 4.7\n" + const QString qmlString("import QtQuick 1.1\n" "Rectangle {\n" " id: root\n" " x: 10;\n" @@ -3584,7 +3739,7 @@ void tst_TestCore::testAnchorsAndRewritingCenter() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -3597,7 +3752,7 @@ void tst_TestCore::testAnchorsAndRewritingCenter() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); QmlItemNode rootItemNode = view->rootQmlItemNode(); QVERIFY(rootItemNode.isValid()); @@ -3611,7 +3766,7 @@ void tst_TestCore::testAnchorsAndRewritingCenter() void tst_TestCore::loadQml() { -char qmlString[] = "import Qt 4.7\n" +char qmlString[] = "import QtQuick 1.1\n" "Rectangle {\n" "id: root;\n" "width: 200;\n" @@ -3652,7 +3807,7 @@ char qmlString[] = "import Qt 4.7\n" textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -3661,14 +3816,14 @@ char qmlString[] = "import Qt 4.7\n" ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Item")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); testRewriterView->setTextModifier(&textModifier); model->attachView(testRewriterView.data()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Rectangle")); QCOMPARE(rootModelNode.id(), QString("root")); QCOMPARE(rootModelNode.variantProperty("width").value().toInt(), 200); QCOMPARE(rootModelNode.variantProperty("height").value().toInt(), 200); @@ -3678,7 +3833,7 @@ char qmlString[] = "import Qt 4.7\n" QCOMPARE(rootModelNode.nodeListProperty("data").toModelNodeList().count(), 3); ModelNode textNode1 = rootModelNode.nodeListProperty("data").toModelNodeList().first(); QVERIFY(textNode1.isValid()); - QCOMPARE(textNode1.type(), QString("Qt/Text")); + QCOMPARE(textNode1.type(), QString("QtQuick.Text")); QCOMPARE(textNode1.id(), QString("text1")); QCOMPARE(textNode1.variantProperty("text").value().toString(), QString("Hello World")); QVERIFY(textNode1.hasProperty("anchors.centerIn")); @@ -3694,13 +3849,13 @@ char qmlString[] = "import Qt 4.7\n" ModelNode rectNode = rootModelNode.nodeListProperty("data").toModelNodeList().at(1); QVERIFY(rectNode.isValid()); - QCOMPARE(rectNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rectNode.type(), QString("QtQuick.Rectangle")); QCOMPARE(rectNode.id(), QString("rectangle")); QVERIFY(rectNode.hasProperty("gradient")); QVERIFY(rectNode.property("gradient").isNodeProperty()); ModelNode gradientNode = rectNode.nodeProperty("gradient").modelNode(); QVERIFY(gradientNode.isValid()); - QCOMPARE(gradientNode.type(), QString("Qt/Gradient")); + QCOMPARE(gradientNode.type(), QString("QtQuick.Gradient")); QVERIFY(gradientNode.hasProperty("stops")); QVERIFY(gradientNode.property("stops").isNodeListProperty()); QCOMPARE(gradientNode.nodeListProperty("stops").toModelNodeList().count(), 2); @@ -3711,15 +3866,15 @@ char qmlString[] = "import Qt 4.7\n" QVERIFY(stop1.isValid()); QVERIFY(stop2.isValid()); - QCOMPARE(stop1.type(), QString("Qt/GradientStop")); - QCOMPARE(stop2.type(), QString("Qt/GradientStop")); + QCOMPARE(stop1.type(), QString("QtQuick.GradientStop")); + QCOMPARE(stop2.type(), QString("QtQuick.GradientStop")); QCOMPARE(stop1.variantProperty("position").value().toInt(), 0); QCOMPARE(stop2.variantProperty("position").value().toInt(), 1); ModelNode textNode2 = rootModelNode.nodeListProperty("data").toModelNodeList().last(); QVERIFY(textNode2.isValid()); - QCOMPARE(textNode2.type(), QString("Qt/Text")); + QCOMPARE(textNode2.type(), QString("QtQuick.Text")); QCOMPARE(textNode2.id(), QString("text2")); QCOMPARE(textNode2.variantProperty("width").value().toInt(), 80); QCOMPARE(textNode2.variantProperty("height").value().toInt(), 20); @@ -3730,105 +3885,83 @@ char qmlString[] = "import Qt 4.7\n" void tst_TestCore::testMetaInfo() { - QSKIP("Fix metainfo", SkipAll); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); + model->changeImports(QList<Import>() << Import::createLibraryImport("QtWebKit", "1.0"), QList<Import>()); // test whether default type is registered - QVERIFY(model->metaInfo("Qt/Item", 4, 7).isValid()); + QVERIFY(model->metaInfo("QtQuick.Item", -1, -1).isValid()); // test whether types from plugins are registered - QVERIFY(model->hasNodeMetaInfo("QtWebKit/WebView", 1, 0)); + QVERIFY(model->hasNodeMetaInfo("QtWebKit.WebView", -1, -1)); // test whether non-qml type is registered - QVERIFY(model->hasNodeMetaInfo("QGraphicsObject", 4, 7)); // Qt 4.7 namespace - QVERIFY(model->hasNodeMetaInfo("QGraphicsObject", 1, 0)); // webkit 1.0 namespace + QVERIFY(model->hasNodeMetaInfo("<cpp>.QGraphicsObject", -1, -1)); // Qt 4.7 namespace } void tst_TestCore::testMetaInfoSimpleType() { - QSKIP("Fix metainfo", SkipAll); - // - // Test type registered with qmlRegisterType: - // - // qmlRegisterType<QDeclarativeItem>("Qt",4,7,"Item") - // - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); - QVERIFY(model->hasNodeMetaInfo("Qt/Item", 4, 7)); - QVERIFY(model->hasNodeMetaInfo("Qt/Item", 4, 7)); + QVERIFY(model->hasNodeMetaInfo("QtQuick.Item", 1, 1)); + QVERIFY(model->hasNodeMetaInfo("QtQuick.Item", 1, 1)); - NodeMetaInfo itemMetaInfo = model->metaInfo("Qt/Item", 4, 7); - NodeMetaInfo itemMetaInfo2 = model->metaInfo("Qt/Item", 4, 7); + NodeMetaInfo itemMetaInfo = model->metaInfo("QtQuick.Item", 1, 1); + NodeMetaInfo itemMetaInfo2 = model->metaInfo("QtQuick.Item", 1, 1); QVERIFY(itemMetaInfo.isValid()); - QCOMPARE(itemMetaInfo.typeName(), QLatin1String("Qt/Item")); - QCOMPARE(itemMetaInfo.majorVersion(), 4); - QCOMPARE(itemMetaInfo.minorVersion(), 7); + QCOMPARE(itemMetaInfo.typeName(), QLatin1String("QtQuick.Item")); + QCOMPARE(itemMetaInfo.majorVersion(), 1); + QCOMPARE(itemMetaInfo.minorVersion(), 1); // super classes NodeMetaInfo graphicsObjectInfo = itemMetaInfo.directSuperClass(); QVERIFY(graphicsObjectInfo.isValid()); - QCOMPARE(graphicsObjectInfo.typeName(), QLatin1String("QGraphicsObject")); + QCOMPARE(graphicsObjectInfo.typeName(), QLatin1String("QtQuick.QGraphicsObject")); QCOMPARE(graphicsObjectInfo.majorVersion(), -1); QCOMPARE(graphicsObjectInfo.minorVersion(), -1); - QCOMPARE(itemMetaInfo.superClasses().size(), 2); // QGraphicsObject, Qt/QtObject - QVERIFY(itemMetaInfo.isSubclassOf("QGraphicsObject", 4, 7)); - QVERIFY(itemMetaInfo.isSubclassOf("Qt/QtObject", 4, 7)); + QCOMPARE(itemMetaInfo.superClasses().size(), 3); // Item, QGraphicsObject, QtQuick.QtObject + QVERIFY(itemMetaInfo.isSubclassOf("QtQuick.QGraphicsObject", -1, -1)); + QVERIFY(itemMetaInfo.isSubclassOf("<cpp>.QObject", -1, -1)); // availableInVersion - QVERIFY(itemMetaInfo.availableInVersion(4, 7)); - QVERIFY(itemMetaInfo.availableInVersion(4, 8)); - QVERIFY(itemMetaInfo.availableInVersion(5, 0)); + QVERIFY(itemMetaInfo.availableInVersion(1, 1)); + QVERIFY(itemMetaInfo.availableInVersion(1, 0)); QVERIFY(itemMetaInfo.availableInVersion(-1, -1)); - QVERIFY(!itemMetaInfo.availableInVersion(4, 6)); - QVERIFY(!itemMetaInfo.availableInVersion(3, 7)); } void tst_TestCore::testMetaInfoUncreatableType() { - QSKIP("Fix metainfo", SkipAll); - // Test type registered with qmlRegisterUncreatableType or qmlRegisterTypeNotAvailable: - // - // qmlRegisterUncreatableType<QDeclarativeAbstractAnimation>("Qt",4,7,"Animation",QDeclarativeAbstractAnimation::tr("Animation is an abstract class")); - // - - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); - QVERIFY(model->hasNodeMetaInfo("Qt/Animation")); - NodeMetaInfo animationTypeInfo = model->metaInfo("Qt/Animation", 4, 7); + QVERIFY(model->hasNodeMetaInfo("QtQuick.Animation")); + NodeMetaInfo animationTypeInfo = model->metaInfo("QtQuick.Animation", 1, 1); QVERIFY(animationTypeInfo.isValid()); QVERIFY(animationTypeInfo.isValid()); - QCOMPARE(animationTypeInfo.typeName(), QLatin1String("Qt/Animation")); - QCOMPARE(animationTypeInfo.majorVersion(), 4); - QCOMPARE(animationTypeInfo.minorVersion(), 7); + QCOMPARE(animationTypeInfo.typeName(), QLatin1String("QtQuick.Animation")); + QCOMPARE(animationTypeInfo.majorVersion(), 1); + QCOMPARE(animationTypeInfo.minorVersion(), 1); NodeMetaInfo qObjectTypeInfo = animationTypeInfo.directSuperClass(); QVERIFY(qObjectTypeInfo.isValid()); - QCOMPARE(qObjectTypeInfo.typeName(), QLatin1String("Qt/QtObject")); - QCOMPARE(qObjectTypeInfo.majorVersion(), 4); - QCOMPARE(qObjectTypeInfo.minorVersion(), 7); - QCOMPARE(animationTypeInfo.superClasses().size(), 1); + QCOMPARE(qObjectTypeInfo.typeName(), QLatin1String("QtQuick.QtObject")); + QCOMPARE(qObjectTypeInfo.majorVersion(), 1); + QCOMPARE(qObjectTypeInfo.minorVersion(), 0); + QCOMPARE(animationTypeInfo.superClasses().size(), 2); } void tst_TestCore::testMetaInfoExtendedType() { - QSKIP("Fix metainfo", SkipAll); - // Test type registered with qmlRegisterExtendedType - // - // qmlRegisterExtendedType<QGraphicsWidget,QDeclarativeGraphicsWidget>("Qt",4,7,"QGraphicsWidget"); - // - - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); - QVERIFY(model->hasNodeMetaInfo("Qt/QGraphicsWidget")); - NodeMetaInfo graphicsWidgetTypeInfo = model->metaInfo("Qt/QGraphicsWidget", 4, 7); + QVERIFY(model->hasNodeMetaInfo("QtQuick.QGraphicsWidget")); + NodeMetaInfo graphicsWidgetTypeInfo = model->metaInfo("QtQuick.QGraphicsWidget", 1, 1); QVERIFY(graphicsWidgetTypeInfo.isValid()); QVERIFY(graphicsWidgetTypeInfo.hasProperty("layout")); // from QGraphicsWidgetDeclarativeUI QVERIFY(graphicsWidgetTypeInfo.hasProperty("font")); // from QGraphicsWidget @@ -3836,10 +3969,10 @@ void tst_TestCore::testMetaInfoExtendedType() NodeMetaInfo graphicsObjectTypeInfo = graphicsWidgetTypeInfo.directSuperClass(); QVERIFY(graphicsObjectTypeInfo.isValid()); - QCOMPARE(graphicsObjectTypeInfo.typeName(), QLatin1String("QGraphicsObject")); + QCOMPARE(graphicsObjectTypeInfo.typeName(), QLatin1String("<cpp>.QGraphicsObject")); QCOMPARE(graphicsObjectTypeInfo.majorVersion(), -1); QCOMPARE(graphicsObjectTypeInfo.minorVersion(), -1); - QCOMPARE(graphicsWidgetTypeInfo.superClasses().size(), 2); + QCOMPARE(graphicsWidgetTypeInfo.superClasses().size(), 3); } void tst_TestCore::testMetaInfoInterface() @@ -3852,17 +3985,11 @@ void tst_TestCore::testMetaInfoInterface() void tst_TestCore::testMetaInfoCustomType() { - QSKIP("Fix metainfo", SkipAll); - - // Test type registered with qmlRegisterCustomType: - // - // qmlRegisterCustomType<QDeclarativePropertyChanges>("Qt", 4, 7, "PropertyChanges", new QDeclarativePropertyChangesParser); - - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); - QVERIFY(model->hasNodeMetaInfo("Qt/PropertyChanges")); - NodeMetaInfo propertyChangesInfo = model->metaInfo("Qt/PropertyChanges", 4, 7); + QVERIFY(model->hasNodeMetaInfo("QtQuick.PropertyChanges")); + NodeMetaInfo propertyChangesInfo = model->metaInfo("QtQuick.PropertyChanges", 1, 1); QVERIFY(propertyChangesInfo.isValid()); QVERIFY(propertyChangesInfo.hasProperty("target")); // from QDeclarativePropertyChanges QVERIFY(propertyChangesInfo.hasProperty("restoreEntryValues")); // from QDeclarativePropertyChanges @@ -3870,27 +3997,27 @@ void tst_TestCore::testMetaInfoCustomType() NodeMetaInfo stateOperationInfo = propertyChangesInfo.directSuperClass(); QVERIFY(stateOperationInfo.isValid()); - QCOMPARE(stateOperationInfo.typeName(), QLatin1String("QDeclarativeStateOperation")); + QCOMPARE(stateOperationInfo.typeName(), QLatin1String("QtQuick.QDeclarative1StateOperation")); QCOMPARE(stateOperationInfo.majorVersion(), -1); QCOMPARE(stateOperationInfo.minorVersion(), -1); - QCOMPARE(propertyChangesInfo.superClasses().size(), 2); + QCOMPARE(propertyChangesInfo.superClasses().size(), 3); // DeclarativePropertyChanges just has 3 properties QCOMPARE(propertyChangesInfo.propertyNames().size() - stateOperationInfo.propertyNames().size(), 3); + + QApplication::processEvents(); } void tst_TestCore::testMetaInfoEnums() { - QSKIP("Fix metainfo", SkipAll); - - QScopedPointer<Model> model(Model::create("Qt/Text")); + QScopedPointer<Model> model(createModel("QtQuick.Text")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - QCOMPARE(view->rootModelNode().metaInfo().typeName(), QString("Qt/Text")); + QCOMPARE(view->rootModelNode().metaInfo().typeName(), QString("QtQuick.Text")); QVERIFY(view->rootModelNode().metaInfo().hasProperty("transformOrigin")); @@ -3903,42 +4030,107 @@ void tst_TestCore::testMetaInfoEnums() QCOMPARE(view->rootModelNode().metaInfo().propertyTypeName("horizontalAlignment"), QLatin1String("HAlignment")); QVERIFY(view->rootModelNode().metaInfo().propertyKeysForEnum("horizontalAlignment").contains(QLatin1String("AlignLeft"))); QVERIFY(view->rootModelNode().metaInfo().propertyKeysForEnum("horizontalAlignment").contains(QLatin1String("AlignRight"))); + + QApplication::processEvents(); } -void tst_TestCore::testMetaInfoProperties() +void tst_TestCore::testMetaInfoQtQuick1Vs2() { - QSKIP("Fix metainfo", SkipAll); + char qmlString[] = "import QtQuick 2.0\n" + "Rectangle {\n" + "id: root;\n" + "width: 200;\n" + "height: 200;\n" + "color: \"white\";\n" + "Text {\n" + "id: text1\n" + "text: \"Hello World\"\n" + "anchors.centerIn: parent\n" + "Item {\n" + "id: item\n" + "}\n" + "}\n" + "Rectangle {\n" + "id: rectangle;\n" + "gradient: Gradient {\n" + "GradientStop {\n" + "position: 0\n" + "color: \"white\"\n" + "}\n" + "GradientStop {\n" + "position: 1\n" + "color: \"black\"\n" + "}\n" + "}\n" + "}\n" + "Text {\n" + "text: \"text\"\n" + "x: 66\n" + "y: 43\n" + "width: 80\n" + "height: 20\n" + "id: text2\n" + "}\n" + "}\n"; + + QPlainTextEdit textEdit; + textEdit.setPlainText(qmlString); + NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Text")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); - NodeMetaInfo textNodeMetaInfo = model->metaInfo("Qt/TextEdit", 4, 7); + QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); + testRewriterView->setTextModifier(&textModifier); + + model->attachView(testRewriterView.data()); + + ModelNode rootModelNode = testRewriterView->rootModelNode(); + QVERIFY(rootModelNode.isValid()); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Rectangle")); + + QVERIFY(!model->metaInfo("Rectangle", 1, 0).isValid()); + QVERIFY(model->metaInfo("Rectangle", -1, -1).isValid()); + QVERIFY(model->metaInfo("Rectangle", 2, 0).isValid()); + + QVERIFY(!model->metaInfo("QtQuick.Rectangle", 1, 0).isValid()); + QVERIFY(model->metaInfo("QtQuick.Rectangle", -1, -1).isValid()); + QVERIFY(model->metaInfo("QtQuick.Rectangle", 2, 0).isValid()); +} + +void tst_TestCore::testMetaInfoProperties() +{ + QScopedPointer<Model> model(createModel("QtQuick.Text")); + QVERIFY(model.data()); + + NodeMetaInfo textNodeMetaInfo = model->metaInfo("QtQuick.TextEdit", 1, 1); QVERIFY(textNodeMetaInfo.hasProperty("text")); // QDeclarativeTextEdit QVERIFY(textNodeMetaInfo.hasProperty("parent")); // QDeclarativeItem QVERIFY(textNodeMetaInfo.hasProperty("x")); // QGraphicsObject - QVERIFY(textNodeMetaInfo.hasProperty("objectName")); // Qt/QObject + QVERIFY(textNodeMetaInfo.hasProperty("objectName")); // QtQuick.QObject QVERIFY(!textNodeMetaInfo.hasProperty("bla")); QVERIFY(textNodeMetaInfo.propertyIsWritable("text")); QVERIFY(textNodeMetaInfo.propertyIsWritable("x")); + + QApplication::processEvents(); } void tst_TestCore::testMetaInfoDotProperties() { - QSKIP("Fix metainfo", SkipAll); - - QScopedPointer<Model> model(Model::create("Qt/Text")); + QScopedPointer<Model> model(createModel("QtQuick.Text")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - QVERIFY(model->hasNodeMetaInfo("Qt/Text")); + QVERIFY(model->hasNodeMetaInfo("QtQuick.Text")); - QVERIFY(model->hasNodeMetaInfo("Qt/Pen")); + QVERIFY(model->metaInfo("QtQuick.Rectangle").hasProperty("border")); + QCOMPARE(model->metaInfo("QtQuick.Rectangle").propertyTypeName("border"), QString("<cpp>.QDeclarative1Pen")); - QCOMPARE(view->rootModelNode().metaInfo().typeName(), QString("Qt/Text")); + QCOMPARE(view->rootModelNode().metaInfo().typeName(), QString("QtQuick.Text")); QVERIFY(view->rootModelNode().metaInfo().hasProperty("font")); QVERIFY(view->rootModelNode().metaInfo().hasProperty("font.bold")); @@ -3946,32 +4138,30 @@ void tst_TestCore::testMetaInfoDotProperties() QVERIFY(view->rootModelNode().metaInfo().propertyNames().contains("font.pointSize")); QVERIFY(view->rootModelNode().metaInfo().hasProperty("font.pointSize")); - ModelNode rectNode(addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data")); + ModelNode rectNode(addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data")); - - QVERIFY(rectNode.metaInfo().propertyNames().contains("pos.x")); - QVERIFY(!rectNode.metaInfo().propertyNames().contains("pos.x")); + QVERIFY(rectNode.metaInfo().propertyNames().contains("pos")); QVERIFY(rectNode.metaInfo().propertyNames().contains("pos.y")); - QVERIFY(!rectNode.metaInfo().propertyNames().contains("pos.y")); - QVERIFY(!rectNode.metaInfo().propertyNames().contains("anchors.topMargin")); + QVERIFY(rectNode.metaInfo().propertyNames().contains("pos.x")); + QVERIFY(rectNode.metaInfo().propertyNames().contains("anchors.topMargin")); QVERIFY(rectNode.metaInfo().propertyNames().contains("border.width")); QVERIFY(rectNode.metaInfo().hasProperty("border")); QVERIFY(rectNode.metaInfo().hasProperty("border.width")); + + QApplication::processEvents(); } void tst_TestCore::testMetaInfoListProperties() { - QSKIP("Fix metainfo", SkipAll); - - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - QVERIFY(model->hasNodeMetaInfo("Qt/Item")); - QCOMPARE(view->rootModelNode().metaInfo().typeName(), QString("Qt/Item")); + QVERIFY(model->hasNodeMetaInfo("QtQuick.Item")); + QCOMPARE(view->rootModelNode().metaInfo().typeName(), QString("QtQuick.Item")); QVERIFY(view->rootModelNode().metaInfo().hasProperty("states")); QVERIFY(view->rootModelNode().metaInfo().propertyIsListProperty("states")); @@ -3990,15 +4180,65 @@ void tst_TestCore::testMetaInfoListProperties() QVERIFY(!view->rootModelNode().metaInfo().propertyIsListProperty("effect")); QVERIFY(view->rootModelNode().metaInfo().hasProperty("parent")); QVERIFY(!view->rootModelNode().metaInfo().propertyIsListProperty("parent")); + + QApplication::processEvents(); +} + +void tst_TestCore::testQtQuick20Basic() +{ + QPlainTextEdit textEdit; + textEdit.setPlainText("\nimport QtQuick 2.0\n\nItem {\n}\n"); + NotIndentingTextEditModifier modifier(&textEdit); + + QScopedPointer<Model> model(Model::create("QtQuick.Item")); + QVERIFY(model.data()); + + TestRewriterView *testRewriterView = new TestRewriterView(model.data()); + testRewriterView->setTextModifier(&modifier); + model->attachView(testRewriterView); + + QVERIFY(testRewriterView->errors().isEmpty()); + ModelNode rootModelNode(testRewriterView->rootModelNode()); + QVERIFY(rootModelNode.isValid()); + QCOMPARE(rootModelNode.metaInfo().majorVersion(), 2); + QCOMPARE(rootModelNode.metaInfo().minorVersion(), 0); + QCOMPARE(rootModelNode.majorQtQuickVersion(), 2); + QCOMPARE(rootModelNode.majorVersion(), 2); +} + +void tst_TestCore::testQtQuick20BasicRectangle() +{ + QPlainTextEdit textEdit; + textEdit.setPlainText("\nimport QtQuick 2.0\nRectangle {\n}\n"); + NotIndentingTextEditModifier modifier(&textEdit); + + QScopedPointer<Model> model(Model::create("QtQuick.Item")); + QVERIFY(model.data()); + + TestRewriterView *testRewriterView = new TestRewriterView(model.data()); + testRewriterView->setTextModifier(&modifier); + model->attachView(testRewriterView); + + QTest::qSleep(1000); + QApplication::processEvents(); + + QVERIFY(testRewriterView->errors().isEmpty()); + ModelNode rootModelNode(testRewriterView->rootModelNode()); + QVERIFY(rootModelNode.isValid()); + QCOMPARE(rootModelNode.type(), QString("QtQuick.Rectangle")); + QCOMPARE(rootModelNode.metaInfo().majorVersion(), 2); + QCOMPARE(rootModelNode.metaInfo().minorVersion(), 0); + QCOMPARE(rootModelNode.majorQtQuickVersion(), 2); + QCOMPARE(rootModelNode.majorVersion(), 2); } void tst_TestCore::testStatesRewriter() { QPlainTextEdit textEdit; - textEdit.setPlainText("import Qt 4.7; Item {}\n"); + textEdit.setPlainText("import QtQuick 1.1; Item {}\n"); NotIndentingTextEditModifier modifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); @@ -4042,10 +4282,10 @@ void tst_TestCore::testStatesRewriter() void tst_TestCore::testGradientsRewriter() { QPlainTextEdit textEdit; - textEdit.setPlainText("\nimport Qt 4.7\n\nItem {\n}\n"); + textEdit.setPlainText("\nimport QtQuick 1.1\n\nItem {\n}\n"); NotIndentingTextEditModifier modifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); @@ -4061,9 +4301,9 @@ void tst_TestCore::testGradientsRewriter() QVERIFY(rootModelNode.isValid()); - ModelNode rectNode(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data")); + ModelNode rectNode(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data")); - const QLatin1String expected1("\nimport Qt 4.7\n" + const QLatin1String expected1("\nimport QtQuick 1.1\n" "\n" "Item {\n" "Rectangle {\n" @@ -4071,11 +4311,11 @@ void tst_TestCore::testGradientsRewriter() "}\n"); QCOMPARE(textEdit.toPlainText(), expected1); - ModelNode gradientNode(addNodeChild(rectNode, "Qt/Gradient", 4, 7, "gradient")); + ModelNode gradientNode(addNodeChild(rectNode, "QtQuick.Gradient", 1, 0, "gradient")); QVERIFY(rectNode.hasNodeProperty("gradient")); - const QLatin1String expected2("\nimport Qt 4.7\n" + const QLatin1String expected2("\nimport QtQuick 1.1\n" "\n" "Item {\n" "Rectangle {\n" @@ -4092,11 +4332,11 @@ void tst_TestCore::testGradientsRewriter() propertyList.append(qMakePair(QString("position"), QVariant::fromValue(0))); propertyList.append(qMakePair(QString("color"), QVariant::fromValue(QColor(Qt::red)))); - ModelNode gradientStop1(gradientNode.view()->createModelNode("Qt/GradientStop", 4, 7, propertyList)); + ModelNode gradientStop1(gradientNode.view()->createModelNode("QtQuick.GradientStop", 1, 0, propertyList)); QVERIFY(gradientStop1.isValid()); stops.reparentHere(gradientStop1); - const QLatin1String expected3("\nimport Qt 4.7\n" + const QLatin1String expected3("\nimport QtQuick 1.1\n" "\n" "Item {\n" "Rectangle {\n" @@ -4115,11 +4355,11 @@ void tst_TestCore::testGradientsRewriter() propertyList.append(qMakePair(QString("position"), QVariant::fromValue(0.5))); propertyList.append(qMakePair(QString("color"), QVariant::fromValue(QColor(Qt::blue)))); - ModelNode gradientStop2(gradientNode.view()->createModelNode("Qt/GradientStop", 4, 7, propertyList)); + ModelNode gradientStop2(gradientNode.view()->createModelNode("QtQuick.GradientStop", 1, 0, propertyList)); QVERIFY(gradientStop2.isValid()); stops.reparentHere(gradientStop2); - const QLatin1String expected4("\nimport Qt 4.7\n" + const QLatin1String expected4("\nimport QtQuick 1.1\n" "\n" "Item {\n" "Rectangle {\n" @@ -4143,11 +4383,11 @@ void tst_TestCore::testGradientsRewriter() propertyList.append(qMakePair(QString("position"), QVariant::fromValue(0.8))); propertyList.append(qMakePair(QString("color"), QVariant::fromValue(QColor(Qt::yellow)))); - ModelNode gradientStop3(gradientNode.view()->createModelNode("Qt/GradientStop", 4, 7, propertyList)); + ModelNode gradientStop3(gradientNode.view()->createModelNode("QtQuick.GradientStop", 1, 0, propertyList)); QVERIFY(gradientStop3.isValid()); stops.reparentHere(gradientStop3); - const QLatin1String expected5("\nimport Qt 4.7\n" + const QLatin1String expected5("\nimport QtQuick 1.1\n" "\n" "Item {\n" "Rectangle {\n" @@ -4174,7 +4414,7 @@ void tst_TestCore::testGradientsRewriter() gradientNode.removeProperty("stops"); - const QLatin1String expected6("\nimport Qt 4.7\n" + const QLatin1String expected6("\nimport QtQuick 1.1\n" "\n" "Item {\n" "Rectangle {\n" @@ -4191,7 +4431,7 @@ void tst_TestCore::testGradientsRewriter() propertyList.append(qMakePair(QString("position"), QVariant::fromValue(0))); propertyList.append(qMakePair(QString("color"), QVariant::fromValue(QColor(Qt::blue)))); - gradientStop1 = gradientNode.view()->createModelNode("Qt/GradientStop", 4, 7, propertyList); + gradientStop1 = gradientNode.view()->createModelNode("QtQuick.GradientStop", 1, 0, propertyList); QVERIFY(gradientStop1.isValid()); stops.reparentHere(gradientStop1); @@ -4199,7 +4439,7 @@ void tst_TestCore::testGradientsRewriter() void tst_TestCore::testQmlModelStates() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); @@ -4232,7 +4472,7 @@ void tst_TestCore::testQmlModelStates() void tst_TestCore::testInstancesStates() { // -// import Qt 4.7 +// import QtQuick 1.1 // // Rectangle { // Text { @@ -4260,7 +4500,7 @@ void tst_TestCore::testInstancesStates() // } // -// QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); +// QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); // QVERIFY(model.data()); // QScopedPointer<TestView> view(new TestView(model.data())); // QVERIFY(view.data()); @@ -4271,28 +4511,28 @@ void tst_TestCore::testInstancesStates() // // // ModelNode rootNode = view->rootModelNode(); -// ModelNode textNode = view->createModelNode("Qt/Text", 4, 7); +// ModelNode textNode = view->createModelNode("QtQuick.Text", 1, 1); // textNode.setId("targetObject"); // textNode.variantProperty("text").setValue("base state"); // rootNode.nodeListProperty("data").reparentHere(textNode); -// ModelNode propertyChanges1Node = view->createModelNode("Qt/PropertyChanges", 4, 7); +// ModelNode propertyChanges1Node = view->createModelNode("QtQuick.PropertyChanges", 1, 1); // propertyChanges1Node.bindingProperty("target").setExpression("targetObject"); // propertyChanges1Node.variantProperty("x").setValue(10); // propertyChanges1Node.variantProperty("text").setValue("state1"); -// ModelNode state1Node = view->createModelNode("Qt/State", 4, 7); +// ModelNode state1Node = view->createModelNode("QtQuick.State", 1, 1); // state1Node.variantProperty("name").setValue("state1"); // state1Node.nodeListProperty("changes").reparentHere(propertyChanges1Node); // rootNode.nodeListProperty("states").reparentHere(state1Node); -// ModelNode propertyChanges2Node = view->createModelNode("Qt/PropertyChanges", 4, 7); +// ModelNode propertyChanges2Node = view->createModelNode("QtQuick.PropertyChanges", 1, 1); // propertyChanges2Node.bindingProperty("target").setExpression("targetObject"); // propertyChanges2Node.variantProperty("text").setValue("state2"); -// ModelNode state2Node = view->createModelNode("Qt/State", 4, 7); +// ModelNode state2Node = view->createModelNode("QtQuick.State", 1, 1); // state2Node.variantProperty("name").setValue("state2"); // state2Node.nodeListProperty("changes").reparentHere(propertyChanges2Node); @@ -4389,7 +4629,7 @@ void tst_TestCore::testInstancesStates() // // // // move property changes of current state out of state -// ModelNode state3Node = view->createModelNode("Qt/State", 4, 7); +// ModelNode state3Node = view->createModelNode("QtQuick.State", 1, 1); // QDeclarativeListReference changes(state1, "changes"); // QCOMPARE(changes.count(), 1); // state3Node.nodeListProperty("changes").reparentHere(propertyChanges1Node); @@ -4412,7 +4652,7 @@ void tst_TestCore::testInstancesStates() // textNode.variantProperty("text").setValue("base state"); // // expressions -// ModelNode textNode2 = view->createModelNode("Qt/Text", 4, 7); +// ModelNode textNode2 = view->createModelNode("QtQuick.Text", 1, 1); // textNode2.setId("targetObject2"); // textNode2.variantProperty("text").setValue("textNode2"); @@ -4472,7 +4712,7 @@ void tst_TestCore::testInstancesStates() void tst_TestCore::testStates() { // -// import Qt 4.7 +// import QtQuick 1.1 // // Rectangle { // Text { @@ -4491,7 +4731,7 @@ void tst_TestCore::testStates() // } // -// QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); +// QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); // QVERIFY(model.data()); // QScopedPointer<TestView> view(new TestView(model.data())); // QVERIFY(view.data()); @@ -4500,7 +4740,7 @@ void tst_TestCore::testStates() // // build up model // ModelNode rootNode = view->rootModelNode(); -// ModelNode textNode = view->createModelNode("Qt/Text", 4, 7); +// ModelNode textNode = view->createModelNode("QtQuick.Text", 1, 1); // textNode.setId("targetObject"); // textNode.variantProperty("text").setValue("base state"); @@ -4516,7 +4756,7 @@ void tst_TestCore::testStates() // QVERIFY(textItem.isValid()); // QmlModelState state1(rootItem.states().addState("state 1")); //add state "state 1" -// QCOMPARE(state1.modelNode().type(), QString("Qt/State")); +// QCOMPARE(state1.modelNode().type(), QString("QtQuick.State")); // QVERIFY(view->currentState().isBaseState()); @@ -4549,7 +4789,7 @@ void tst_TestCore::testStates() // QCOMPARE(changes.modelNode().variantProperty("text").value(), QVariant("state 1")); // QCOMPARE(changes.modelNode().bindingProperty("target").expression(), QString("targetObject")); // QCOMPARE(changes.target(), textNode); -// QCOMPARE(changes.modelNode().type(), QString("Qt/PropertyChanges")); +// QCOMPARE(changes.modelNode().type(), QString("QtQuick.PropertyChanges")); // QCOMPARE(changes.modelNode().parentProperty().name(), QString("changes")); // QCOMPARE(changes.modelNode().parentProperty().parentModelNode(), state1.modelNode()); @@ -4568,7 +4808,7 @@ void tst_TestCore::testStates() void tst_TestCore::testStatesBaseState() { // -// import Qt 4.7 +// import QtQuick 1.1 // // Rectangle { // Text { @@ -4587,7 +4827,7 @@ void tst_TestCore::testStatesBaseState() // } // - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); @@ -4596,7 +4836,7 @@ void tst_TestCore::testStatesBaseState() // build up model ModelNode rootNode = view->rootModelNode(); - ModelNode textNode = view->createModelNode("Qt/Text", 4, 7); + ModelNode textNode = view->createModelNode("QtQuick.Text", 1, 1); textNode.setId("targetObject"); textNode.variantProperty("text").setValue("base state"); @@ -4612,17 +4852,19 @@ void tst_TestCore::testStatesBaseState() QVERIFY(textItem.isValid()); QmlModelState state1(rootItem.states().addState("state 1")); //add state "state 1" - QCOMPARE(state1.modelNode().type(), QString("Qt/State")); + QCOMPARE(state1.modelNode().type(), QString("QtQuick.State")); QVERIFY(view->currentState().isBaseState()); view->setCurrentState(state1); //set currentState "state 1" QCOMPARE(view->currentState(), state1); + QApplication::processEvents(); textItem.setVariantProperty("text", QVariant("state 1")); //set text in state ! QVERIFY(textItem.propertyAffectedByCurrentState("text")); + QApplication::processEvents(); QCOMPARE(textItem.instanceValue("text"), QVariant("state 1")); - ModelNode newNode = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode newNode = view->createModelNode("QtQuick.Rectangle", 1, 0); QVERIFY(!QmlObjectNode(newNode).currentState().isBaseState()); view->setCurrentState(view->baseState()); //set currentState base state @@ -4644,13 +4886,13 @@ void tst_TestCore::testStatesBaseState() void tst_TestCore::testInstancesIdResolution() { - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - // import Qt 4.7 + // import QtQuick 1.1 // // Rectangle { // id: root @@ -4668,7 +4910,7 @@ void tst_TestCore::testInstancesIdResolution() rootNode.variantProperty("width").setValue(100); rootNode.variantProperty("height").setValue(100); - ModelNode item1Node = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode item1Node = view->createModelNode("QtQuick.Rectangle", 1, 0); item1Node.setId("item1"); item1Node.bindingProperty("width").setExpression("root.width"); item1Node.bindingProperty("height").setExpression("item2.height"); @@ -4688,7 +4930,7 @@ void tst_TestCore::testInstancesIdResolution() // height: root.height // } - ModelNode item2Node = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode item2Node = view->createModelNode("QtQuick.Rectangle", 1, 0); item2Node.setId("item2"); item2Node.bindingProperty("width").setExpression("root.width / 2"); item2Node.bindingProperty("height").setExpression("root.height"); @@ -4713,7 +4955,7 @@ void tst_TestCore::testInstancesIdResolution() // height: 80 // } - ModelNode item3Node = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode item3Node = view->createModelNode("QtQuick.Rectangle", 1, 0); item3Node.setId("item3"); item3Node.variantProperty("height").setValue(80); rootNode.nodeListProperty("data").reparentHere(item3Node); @@ -4731,16 +4973,16 @@ void tst_TestCore::testInstancesNotInScene() // test whether deleting an instance which is not in the scene crashes // - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - ModelNode node1 = view->createModelNode("Qt/Item", 4, 7); + ModelNode node1 = view->createModelNode("QtQuick.Item", 1, 1); node1.setId("node1"); - ModelNode node2 = view->createModelNode("Qt/Item", 4, 7); + ModelNode node2 = view->createModelNode("QtQuick.Item", 1, 1); node2.setId("node2"); node1.nodeListProperty("children").reparentHere(node2); @@ -4752,21 +4994,21 @@ void tst_TestCore::testInstancesBindingsInStatesStress() { //This is a stress test to provoke a crash for (int j=0;j<20;j++) { - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - ModelNode node1 = view->createModelNode("Qt/Item", 4, 7); + ModelNode node1 = view->createModelNode("QtQuick.Item", 1, 1); node1.setId("node1"); view->rootModelNode().nodeListProperty("children").reparentHere(node1); - ModelNode node2 = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode node2 = view->createModelNode("QtQuick.Rectangle", 1, 0); node2.setId("node2"); - ModelNode node3 = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode node3 = view->createModelNode("QtQuick.Rectangle", 1, 0); node3.setId("node3"); node1.nodeListProperty("children").reparentHere(node2); @@ -4857,21 +5099,21 @@ void tst_TestCore::testInstancesPropertyChangeTargets() //this tests checks if a change of the target of a CropertyChange //node is handled correctly - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - ModelNode node1 = view->createModelNode("Qt/Item", 4, 7); + ModelNode node1 = view->createModelNode("QtQuick.Item", 1, 1); node1.setId("node1"); view->rootModelNode().nodeListProperty("children").reparentHere(node1); - ModelNode node2 = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode node2 = view->createModelNode("QtQuick.Rectangle", 1, 0); node2.setId("node2"); - ModelNode node3 = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode node3 = view->createModelNode("QtQuick.Rectangle", 1, 0); node3.setId("node3"); node1.nodeListProperty("children").reparentHere(node2); @@ -4963,21 +5205,21 @@ void tst_TestCore::testInstancesPropertyChangeTargets() void tst_TestCore::testInstancesDeletePropertyChanges() { - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); model->attachView(view.data()); - ModelNode node1 = view->createModelNode("Qt/Item", 4, 7); + ModelNode node1 = view->createModelNode("QtQuick.Item", 1, 1); node1.setId("node1"); view->rootModelNode().nodeListProperty("children").reparentHere(node1); - ModelNode node2 = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode node2 = view->createModelNode("QtQuick.Rectangle", 1, 0); node2.setId("node2"); - ModelNode node3 = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode node3 = view->createModelNode("QtQuick.Rectangle", 1, 0); node3.setId("node3"); node1.nodeListProperty("children").reparentHere(node2); @@ -5052,7 +5294,7 @@ void tst_TestCore::testInstancesDeletePropertyChanges() void tst_TestCore::testInstancesChildrenLowLevel() { -// QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); +// QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); // QVERIFY(model.data()); // QScopedPointer<NodeInstanceView> view(new NodeInstanceView); @@ -5064,11 +5306,11 @@ void tst_TestCore::testInstancesChildrenLowLevel() // rootModelNode.setId("rootModelNode"); -// ModelNode childNode1 = addNodeListChild(rootModelNode, "Qt/Text", 4, 7, "data"); +// ModelNode childNode1 = addNodeListChild(rootModelNode, "QtQuick.Text", 1, 1, "data"); // QVERIFY(childNode1.isValid()); // childNode1.setId("childNode1"); -// ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/TextEdit", 4, 7, "data"); +// ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.TextEdit", 1, 1, "data"); // QVERIFY(childNode2.isValid()); // childNode2.setId("childNode2"); @@ -5142,7 +5384,7 @@ void tst_TestCore::testInstancesChildrenLowLevel() void tst_TestCore::testInstancesResourcesLowLevel() { -// QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); +// QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); // QVERIFY(model.data()); // QScopedPointer<NodeInstanceView> view(new NodeInstanceView); @@ -5154,15 +5396,15 @@ void tst_TestCore::testInstancesResourcesLowLevel() // rootModelNode.setId("rootModelNode"); -// ModelNode childNode1 = addNodeListChild(rootModelNode, "Qt/Text", 4, 7, "data"); +// ModelNode childNode1 = addNodeListChild(rootModelNode, "QtQuick.Text", 1, 1, "data"); // QVERIFY(childNode1.isValid()); // childNode1.setId("childNode1"); -// ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/TextEdit", 4, 7, "data"); +// ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.TextEdit", 1, 1, "data"); // QVERIFY(childNode2.isValid()); // childNode2.setId("childNode2"); -// ModelNode listModel = addNodeListChild(rootModelNode, "Qt/ListModel", 4, 7, "data"); +// ModelNode listModel = addNodeListChild(rootModelNode, "QtQuick.ListModel", 1, 1, "data"); // QVERIFY(listModel.isValid()); // listModel.setId("listModel"); @@ -5241,7 +5483,7 @@ void tst_TestCore::testInstancesResourcesLowLevel() // QCOMPARE(listReferenceData.at(1), child1Item); // QCOMPARE(listReferenceData.at(2), child2Item); -// ModelNode listModel2 = addNodeListChild(rootModelNode, "Qt/ListModel", 4, 7, "data"); +// ModelNode listModel2 = addNodeListChild(rootModelNode, "QtQuick.ListModel", 1, 1, "data"); // QVERIFY(listModel2.isValid()); // listModel2.setId("listModel2"); @@ -5289,7 +5531,7 @@ void tst_TestCore::testInstancesResourcesLowLevel() void tst_TestCore::testInstancesFlickableLowLevel() { -// QScopedPointer<Model> model(Model::create("Qt/Flickable", 4, 7)); +// QScopedPointer<Model> model(createModel("QtQuick.Flickable", 1, 1)); // QVERIFY(model.data()); // QScopedPointer<NodeInstanceView> view(new NodeInstanceView); @@ -5301,15 +5543,15 @@ void tst_TestCore::testInstancesFlickableLowLevel() // rootModelNode.setId("rootModelNode"); -// ModelNode childNode1 = addNodeListChild(rootModelNode, "Qt/Text", 4, 7, "flickableData"); +// ModelNode childNode1 = addNodeListChild(rootModelNode, "QtQuick.Text", 1, 1, "flickableData"); // QVERIFY(childNode1.isValid()); // childNode1.setId("childNode1"); -// ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/TextEdit", 4, 7, "flickableData"); +// ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.TextEdit", 1, 1, "flickableData"); // QVERIFY(childNode2.isValid()); // childNode2.setId("childNode2"); -// ModelNode listModel = addNodeListChild(rootModelNode, "Qt/ListModel", 4, 7, "flickableData"); +// ModelNode listModel = addNodeListChild(rootModelNode, "QtQuick.ListModel", 1, 1, "flickableData"); // QVERIFY(listModel.isValid()); // listModel.setId("listModel"); @@ -5377,7 +5619,7 @@ void tst_TestCore::testInstancesFlickableLowLevel() void tst_TestCore::testInstancesReorderChildrenLowLevel() { -// QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); +// QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); // QVERIFY(model.data()); // QScopedPointer<NodeInstanceView> view(new NodeInstanceView); @@ -5389,23 +5631,23 @@ void tst_TestCore::testInstancesReorderChildrenLowLevel() // rootModelNode.setId("rootModelNode"); -// ModelNode childNode1 = addNodeListChild(rootModelNode, "Qt/Text", 4, 7, "data"); +// ModelNode childNode1 = addNodeListChild(rootModelNode, "QtQuick.Text", 1, 1, "data"); // QVERIFY(childNode1.isValid()); // childNode1.setId("childNode1"); -// ModelNode childNode2 = addNodeListChild(rootModelNode, "Qt/TextEdit", 4, 7, "data"); +// ModelNode childNode2 = addNodeListChild(rootModelNode, "QtQuick.TextEdit", 1, 1, "data"); // QVERIFY(childNode2.isValid()); // childNode2.setId("childNode2"); -// ModelNode listModel = addNodeListChild(rootModelNode, "Qt/ListModel", 4, 7, "data"); +// ModelNode listModel = addNodeListChild(rootModelNode, "QtQuick.ListModel", 1, 1, "data"); // QVERIFY(listModel.isValid()); // listModel.setId("listModel"); -// ModelNode childNode3 = addNodeListChild(rootModelNode, "Qt/TextEdit", 4, 7, "data"); +// ModelNode childNode3 = addNodeListChild(rootModelNode, "QtQuick.TextEdit", 1, 1, "data"); // QVERIFY(childNode3.isValid()); // childNode3.setId("childNode3"); -// ModelNode childNode4 = addNodeListChild(rootModelNode, "Qt/TextEdit", 4, 7, "data"); +// ModelNode childNode4 = addNodeListChild(rootModelNode, "QtQuick.TextEdit", 1, 1, "data"); // QVERIFY(childNode4.isValid()); // childNode4.setId("childNode4"); @@ -5476,7 +5718,7 @@ void tst_TestCore::testInstancesReorderChildrenLowLevel() void tst_TestCore::testQmlModelStatesInvalidForRemovedNodes() { - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -5493,11 +5735,11 @@ void tst_TestCore::testQmlModelStatesInvalidForRemovedNodes() QVERIFY(state1.isValid()); QCOMPARE(state1.name(), QString("state1")); - ModelNode childNode = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(childNode.isValid()); childNode.setId("childNode"); - ModelNode subChildNode = addNodeListChild(childNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode subChildNode = addNodeListChild(childNode, "QtQuick.Rectangle", 1, 0, "data"); QVERIFY(subChildNode.isValid()); subChildNode.setId("subChildNode"); @@ -5517,7 +5759,7 @@ void tst_TestCore::testInstancesAttachToExistingModel() // Test attaching nodeinstanceview to an existing model // - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -5525,7 +5767,7 @@ void tst_TestCore::testInstancesAttachToExistingModel() model->attachView(view.data()); ModelNode rootNode = view->rootModelNode(); - ModelNode rectangleNode = addNodeListChild(rootNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode rectangleNode = addNodeListChild(rootNode, "QtQuick.Rectangle", 1, 0, "data"); rectangleNode.variantProperty("width").setValue(100); @@ -5534,7 +5776,7 @@ void tst_TestCore::testInstancesAttachToExistingModel() // Attach NodeInstanceView - QScopedPointer<NodeInstanceView> instanceView(new NodeInstanceView); + QScopedPointer<NodeInstanceView> instanceView(new NodeInstanceView(0, NodeInstanceServerInterface::TestModus)); QVERIFY(instanceView.data()); model->attachView(instanceView.data()); @@ -5549,7 +5791,7 @@ void tst_TestCore::testInstancesAttachToExistingModel() void tst_TestCore::testQmlModelAddMultipleStates() { - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -5580,7 +5822,7 @@ void tst_TestCore::testQmlModelAddMultipleStates() void tst_TestCore::testQmlModelRemoveStates() { - QScopedPointer<Model> model(Model::create("Qt/Rectangle", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 1, 1)); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); @@ -5610,10 +5852,10 @@ void tst_TestCore::testQmlModelRemoveStates() void tst_TestCore::testQmlModelStateWithName() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Rectangle { id: theRect; width: 100; states: [ State { name: \"a\"; PropertyChanges { target: theRect; width: 200; } } ] }\n"); + textEdit1.setPlainText("import QtQuick 1.1; Rectangle { id: theRect; width: 100; states: [ State { name: \"a\"; PropertyChanges { target: theRect; width: 200; } } ] }\n"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); TestRewriterView *testRewriterView1 = new TestRewriterView(model1.data()); testRewriterView1->setTextModifier(&modifier1); @@ -5635,7 +5877,7 @@ void tst_TestCore::testQmlModelStateWithName() view->setCurrentState(rootNode.states().allStates().at(0)); rootNode.setVariantProperty("width", 112); - const QLatin1String expected1("import Qt 4.7; Rectangle { id: theRect; width: 100; states: [ State { name: \"a\"; PropertyChanges { target: theRect; width: 112 } } ] }\n"); + const QLatin1String expected1("import QtQuick 1.1; Rectangle { id: theRect; width: 100; states: [ State { name: \"a\"; PropertyChanges { target: theRect; width: 112 } } ] }\n"); QCOMPARE(textEdit1.toPlainText(), expected1); QVERIFY(!rootNode.isInBaseState()); @@ -5655,10 +5897,10 @@ void tst_TestCore::testQmlModelStateWithName() void tst_TestCore::testRewriterAutomaticSemicolonAfterChangedProperty() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Rectangle {\n width: 640\n height: 480\n}\n"); + textEdit1.setPlainText("import QtQuick 1.1; Rectangle {\n width: 640\n height: 480\n}\n"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); TestRewriterView *testRewriterView1 = new TestRewriterView(model1.data()); testRewriterView1->setTextModifier(&modifier1); @@ -5675,7 +5917,7 @@ void tst_TestCore::testRewriterAutomaticSemicolonAfterChangedProperty() void tst_TestCore::defaultPropertyValues() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -5685,12 +5927,12 @@ void tst_TestCore::defaultPropertyValues() QCOMPARE(view->rootModelNode().variantProperty("x").value().toDouble(), 0.0); QCOMPARE(view->rootModelNode().variantProperty("width").value().toDouble(), 0.0); - ModelNode rectNode(addNodeListChild(view->rootModelNode(), "Qt/Rectangle", 4, 7, "data")); + ModelNode rectNode(addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 1, 0, "data")); QCOMPARE(rectNode.variantProperty("y").value().toDouble(), 0.0); QCOMPARE(rectNode.variantProperty("width").value().toDouble(), 0.0); - ModelNode imageNode(addNodeListChild(view->rootModelNode(), "Qt/Image", 4, 7, "data")); + ModelNode imageNode(addNodeListChild(view->rootModelNode(), "QtQuick.Image", 1, 0, "data")); QCOMPARE(imageNode.variantProperty("y").value().toDouble(), 0.0); QCOMPARE(imageNode.variantProperty("width").value().toDouble(), 0.0); @@ -5699,10 +5941,10 @@ void tst_TestCore::defaultPropertyValues() void tst_TestCore::testModelPropertyValueTypes() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Rectangle { width: 100; radius: 1.5; color: \"red\"; }"); + textEdit1.setPlainText("import QtQuick 1.1; Rectangle { width: 100; radius: 1.5; color: \"red\"; }"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model1(Model::create("Qt/Item")); + QScopedPointer<Model> model1(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -5720,7 +5962,7 @@ void tst_TestCore::testModelPropertyValueTypes() void tst_TestCore::testModelNodeInHierarchy() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -5728,9 +5970,9 @@ void tst_TestCore::testModelNodeInHierarchy() model->attachView(view.data()); QVERIFY(view->rootModelNode().isInHierarchy()); - ModelNode node1 = addNodeListChild(view->rootModelNode(), "Qt/Item", 4, 7, "data"); + ModelNode node1 = addNodeListChild(view->rootModelNode(), "QtQuick.Item", 1, 1, "data"); QVERIFY(node1.isInHierarchy()); - ModelNode node2 = view->createModelNode("Qt/Item", 4, 7); + ModelNode node2 = view->createModelNode("QtQuick.Item", 1, 1); QVERIFY(!node2.isInHierarchy()); node2.nodeListProperty("data").reparentHere(node1); QVERIFY(!node2.isInHierarchy()); @@ -5741,11 +5983,11 @@ void tst_TestCore::testModelNodeInHierarchy() void tst_TestCore::testModelNodeIsAncestorOf() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); // - // import Qt 4.7 + // import QtQuick 1.1 // Item { // Item { // id: item2 @@ -5763,11 +6005,11 @@ void tst_TestCore::testModelNodeIsAncestorOf() model->attachView(view.data()); view->rootModelNode().setId("item1"); - ModelNode item2 = addNodeListChild(view->rootModelNode(), "Qt/Item", 4, 7, "data"); + ModelNode item2 = addNodeListChild(view->rootModelNode(), "QtQuick.Item", 1, 1, "data"); item2.setId("item2"); - ModelNode item3 = addNodeListChild(view->rootModelNode(), "Qt/Item", 4, 7, "data"); + ModelNode item3 = addNodeListChild(view->rootModelNode(), "QtQuick.Item", 1, 1, "data"); item3.setId("item3"); - ModelNode item4 = addNodeListChild(item3, "Qt/Item", 4, 7, "data"); + ModelNode item4 = addNodeListChild(item3, "QtQuick.Item", 1, 1, "data"); item4.setId("item4"); QVERIFY(view->rootModelNode().isAncestorOf(item2)); @@ -5780,8 +6022,7 @@ void tst_TestCore::testModelNodeIsAncestorOf() void tst_TestCore::testModelDefaultProperties() { - QSKIP("Fix metainfo", SkipAll); - QScopedPointer<Model> model(Model::create("Qt/Rectangle")); + QScopedPointer<Model> model(createModel("QtQuick.Rectangle")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -5797,10 +6038,10 @@ void tst_TestCore::testModelDefaultProperties() void tst_TestCore::loadAnchors() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Item { width: 100; height: 100; Rectangle { anchors.left: parent.left; anchors.horizontalCenter: parent.horizontalCenter; anchors.rightMargin: 20; }}"); + textEdit1.setPlainText("import QtQuick 1.1; Item { width: 100; height: 100; Rectangle { anchors.left: parent.left; anchors.horizontalCenter: parent.horizontalCenter; anchors.rightMargin: 20; }}"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -5836,10 +6077,10 @@ void tst_TestCore::loadAnchors() void tst_TestCore::changeAnchors() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Item { width: 100; height: 100; Rectangle { anchors.left: parent.left; anchors.horizontalCenter: parent.horizontalCenter; anchors.rightMargin: 20; }}"); + textEdit1.setPlainText("import QtQuick 1.1; Item { width: 100; height: 100; Rectangle { anchors.left: parent.left; anchors.horizontalCenter: parent.horizontalCenter; anchors.rightMargin: 20; }}"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -5897,10 +6138,10 @@ void tst_TestCore::changeAnchors() void tst_TestCore::anchorToSibling() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Item { Rectangle {} Rectangle { id: secondChild } }"); + textEdit1.setPlainText("import QtQuick 1.1; Item { Rectangle {} Rectangle { id: secondChild } }"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -5941,10 +6182,10 @@ void tst_TestCore::anchorToSibling() void tst_TestCore::removeFillAnchorByDetaching() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Item { width: 100; height: 100; Rectangle { id: child; anchors.fill: parent } }"); + textEdit1.setPlainText("import QtQuick 1.1; Item { width: 100; height: 100; Rectangle { id: child; anchors.fill: parent } }"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -6021,10 +6262,10 @@ void tst_TestCore::removeFillAnchorByDetaching() void tst_TestCore::removeFillAnchorByChanging() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Item { width: 100; height: 100; Rectangle { id: child; anchors.fill: parent } }"); + textEdit1.setPlainText("import QtQuick 1.1; Item { width: 100; height: 100; Rectangle { id: child; anchors.fill: parent } }"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -6101,7 +6342,7 @@ void tst_TestCore::removeFillAnchorByChanging() void tst_TestCore::testModelBindings() { - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(createModel("QtQuick.Item", 1, 1)); QVERIFY(model.data()); NodeInstanceView *nodeInstanceView = new NodeInstanceView(model.data(), NodeInstanceServerInterface::TestModus); @@ -6111,9 +6352,9 @@ void tst_TestCore::testModelBindings() QCOMPARE(rootModelNode.allDirectSubModelNodes().count(), 0); NodeInstance rootInstance = nodeInstanceView->instanceForNode(rootModelNode); - // default width/height is forced to 100 - QCOMPARE(rootInstance.size().width(), 100.0); - QCOMPARE(rootInstance.size().height(), 100.0); + // default width/height is 0 + QCOMPARE(rootInstance.size().width(), 0.0); + QCOMPARE(rootInstance.size().height(), 0.0); rootModelNode.variantProperty("width") = 200; rootModelNode.variantProperty("height") = 100; @@ -6121,7 +6362,7 @@ void tst_TestCore::testModelBindings() QCOMPARE(rootInstance.size().width(), 200.0); QCOMPARE(rootInstance.size().height(), 100.0); - ModelNode childNode = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); childNode.variantProperty("width") = 100; childNode.variantProperty("height") = 100; @@ -6159,7 +6400,8 @@ void tst_TestCore::testModelBindings() void tst_TestCore::testModelDynamicProperties() { - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QSKIP("Fix rewriter dynamic properties writing", SkipAll); + QScopedPointer<Model> model(createModel("QtQuick.Item", 1, 1)); QVERIFY(model.data()); TestView *testView = new TestView(model.data()); @@ -6169,8 +6411,8 @@ void tst_TestCore::testModelDynamicProperties() ModelNode rootModelNode = rootQmlItemNode.modelNode(); rootModelNode.variantProperty("x") = 10; - rootModelNode.variantProperty("myDouble") = qMakePair(QString("real"), QVariant(10)); rootModelNode.variantProperty("myColor").setDynamicTypeNameAndValue("color", Qt::red); + rootModelNode.variantProperty("myDouble").setDynamicTypeNameAndValue("real", 10); QVERIFY(!rootModelNode.property("x").isDynamic()); QVERIFY(rootModelNode.property("myColor").isDynamic()); @@ -6203,7 +6445,7 @@ void tst_TestCore::testModelDynamicProperties() void tst_TestCore::testModelSliding() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6212,10 +6454,10 @@ void tst_TestCore::testModelSliding() ModelNode rootModelNode(view->rootModelNode()); - ModelNode rect00(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data")); - ModelNode rect01(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data")); - ModelNode rect02(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data")); - ModelNode rect03(addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data")); + ModelNode rect00(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data")); + ModelNode rect01(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data")); + ModelNode rect02(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data")); + ModelNode rect03(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data")); QVERIFY(rect00.isValid()); QVERIFY(rect01.isValid()); @@ -6271,13 +6513,13 @@ void tst_TestCore::testModelSliding() void tst_TestCore::testRewriterChangeId() { - const char* qmlString = "import Qt 4.7\nRectangle { }"; + const char* qmlString = "import QtQuick 1.1\nRectangle { }"; QPlainTextEdit textEdit; textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6296,25 +6538,25 @@ void tst_TestCore::testRewriterChangeId() QCOMPARE(rootModelNode.id(), QString("rectId")); - QString expected = "import Qt 4.7\n" + QString expected = "import QtQuick 1.1\n" "Rectangle { id: rectId }"; QCOMPARE(textEdit.toPlainText(), expected); // change id for node outside of hierarchy - ModelNode node = view->createModelNode("Qt/Item", 4, 7); + ModelNode node = view->createModelNode("QtQuick.Item", 1, 1); node.setId("myId"); } void tst_TestCore::testRewriterRemoveId() { - const char* qmlString = "import Qt 4.7\nRectangle { id: rect }"; + const char* qmlString = "import QtQuick 1.1\nRectangle { id: rect }"; QPlainTextEdit textEdit; textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6332,7 +6574,7 @@ void tst_TestCore::testRewriterRemoveId() // // remove id in text // - const char* qmlString2 = "import Qt 4.7\nRectangle { }"; + const char* qmlString2 = "import QtQuick 1.1\nRectangle { }"; textEdit.setPlainText(qmlString2); QCOMPARE(rootModelNode.id(), QString()); @@ -6340,13 +6582,13 @@ void tst_TestCore::testRewriterRemoveId() void tst_TestCore::testRewriterChangeValueProperty() { - const char* qmlString = "import Qt 4.7\nRectangle { x: 10; y: 10 }"; + const char* qmlString = "import QtQuick 1.1\nRectangle { x: 10; y: 10 }"; QPlainTextEdit textEdit; textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6369,14 +6611,14 @@ void tst_TestCore::testRewriterChangeValueProperty() // change property for node outside of hierarchy PropertyListType properties; properties.append(QPair<QString,QVariant>("x", 10)); - ModelNode node = view->createModelNode("Qt/Item", 4, 7, properties); + ModelNode node = view->createModelNode("QtQuick.Item", 1, 1, properties); node.variantProperty("x").setValue(20); } void tst_TestCore::testRewriterRemoveValueProperty() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "Rectangle {\n" " x: 10\n" " y: 10;\n" @@ -6386,7 +6628,7 @@ void tst_TestCore::testRewriterRemoveValueProperty() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6407,7 +6649,7 @@ void tst_TestCore::testRewriterRemoveValueProperty() rootModelNode.removeProperty("x"); const QLatin1String expected("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "Rectangle {\n" " y: 10;\n" "}\n"); @@ -6416,19 +6658,19 @@ void tst_TestCore::testRewriterRemoveValueProperty() // remove property for node outside of hierarchy PropertyListType properties; properties.append(QPair<QString,QVariant>("x", 10)); - ModelNode node = view->createModelNode("Qt/Item", 4, 7, properties); + ModelNode node = view->createModelNode("QtQuick.Item", 1, 1, properties); node.removeProperty("x"); } void tst_TestCore::testRewriterSignalProperty() { - const char* qmlString = "import Qt 4.7\nRectangle { onColorChanged: {} }"; + const char* qmlString = "import QtQuick 1.1\nRectangle { onColorChanged: {} }"; QPlainTextEdit textEdit; textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6448,13 +6690,13 @@ void tst_TestCore::testRewriterSignalProperty() void tst_TestCore::testRewriterObjectTypeProperty() { - const char* qmlString = "import Qt 4.7\nRectangle { x: 10; y: 10 }"; + const char* qmlString = "import QtQuick 1.1\nRectangle { x: 10; y: 10 }"; QPlainTextEdit textEdit; textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6468,11 +6710,11 @@ void tst_TestCore::testRewriterObjectTypeProperty() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootModelNode.type(), QLatin1String("QtQuick.Rectangle")); - view->changeRootNodeType(QLatin1String("Qt/Text"), 4, 7); + view->changeRootNodeType(QLatin1String("QtQuick.Text"), 1, 1); - QCOMPARE(rootModelNode.type(), QLatin1String("Qt/Text")); + QCOMPARE(rootModelNode.type(), QLatin1String("QtQuick.Text")); } void tst_TestCore::testRewriterPropertyChanges() @@ -6482,7 +6724,7 @@ void tst_TestCore::testRewriterPropertyChanges() // Use a slightly more complicated example so that target properties are not resolved in default scope const char* qmlString - = "import Qt 4.7\n" + = "import QtQuick 1.1\n" "Rectangle {\n" " Text {\n" " id: targetObj\n" @@ -6502,7 +6744,7 @@ void tst_TestCore::testRewriterPropertyChanges() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6515,7 +6757,7 @@ void tst_TestCore::testRewriterPropertyChanges() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); QVERIFY(rootNode.propertyNames().contains(QLatin1String("data"))); QVERIFY(rootNode.propertyNames().contains(QLatin1String("states"))); QCOMPARE(rootNode.propertyNames().count(), 2); @@ -6526,7 +6768,7 @@ void tst_TestCore::testRewriterPropertyChanges() ModelNode stateNode = statesProperty.toModelNodeList().first(); QVERIFY(stateNode.isValid()); - QCOMPARE(stateNode.type(), QString("Qt/State")); + QCOMPARE(stateNode.type(), QString("QtQuick.State")); QCOMPARE(stateNode.propertyNames(), QStringList("changes")); NodeListProperty stateChangesProperty = stateNode.property("changes").toNodeListProperty(); @@ -6553,13 +6795,13 @@ void tst_TestCore::testRewriterListModel() try { // ListModel uses a custom parser - const char* qmlString = "import Qt 4.7; ListModel {\n ListElement {\n age: 12\n} \n}"; + const char* qmlString = "import QtQuick 1.1; ListModel {\n ListElement {\n age: 12\n} \n}"; QPlainTextEdit textEdit; textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -6588,7 +6830,7 @@ void tst_TestCore::testRewriterListModel() void tst_TestCore::testRewriterAddProperty() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); @@ -6596,7 +6838,7 @@ void tst_TestCore::testRewriterAddProperty() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6609,7 +6851,7 @@ void tst_TestCore::testRewriterAddProperty() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); rootNode.variantProperty(QLatin1String("x")).setValue(123); @@ -6618,7 +6860,7 @@ void tst_TestCore::testRewriterAddProperty() QCOMPARE(rootNode.variantProperty(QLatin1String("x")).value(), QVariant(123)); const QLatin1String expected("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "x: 123\n" @@ -6629,7 +6871,7 @@ void tst_TestCore::testRewriterAddProperty() void tst_TestCore::testRewriterAddPropertyInNestedObject() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Rectangle {\n" @@ -6640,7 +6882,7 @@ void tst_TestCore::testRewriterAddPropertyInNestedObject() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6653,18 +6895,18 @@ void tst_TestCore::testRewriterAddPropertyInNestedObject() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); ModelNode childNode = rootNode.nodeListProperty(QLatin1String("data")).toModelNodeList().at(0); QVERIFY(childNode.isValid()); - QCOMPARE(childNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(childNode.type(), QLatin1String("QtQuick.Rectangle")); QCOMPARE(childNode.id(), QLatin1String("rectangle1")); childNode.variantProperty(QLatin1String("x")).setValue(10); childNode.variantProperty(QLatin1String("y")).setValue(10); const QLatin1String expected("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Rectangle {\n" @@ -6678,7 +6920,7 @@ void tst_TestCore::testRewriterAddPropertyInNestedObject() void tst_TestCore::testRewriterAddObjectDefinition() { - const QLatin1String qmlString("import Qt 4.7\n" + const QLatin1String qmlString("import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); @@ -6686,7 +6928,7 @@ void tst_TestCore::testRewriterAddObjectDefinition() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6699,20 +6941,20 @@ void tst_TestCore::testRewriterAddObjectDefinition() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); - ModelNode childNode = view->createModelNode("Qt/MouseArea", 4, 7); + ModelNode childNode = view->createModelNode("QtQuick.MouseArea", 1, 1); rootNode.nodeAbstractProperty(QLatin1String("data")).reparentHere(childNode); QCOMPARE(rootNode.nodeProperty(QLatin1String("data")).toNodeListProperty().toModelNodeList().size(), 1); childNode = rootNode.nodeProperty(QLatin1String("data")).toNodeListProperty().toModelNodeList().at(0); - QCOMPARE(childNode.type(), QString(QLatin1String("Qt/MouseArea"))); + QCOMPARE(childNode.type(), QString(QLatin1String("QtQuick.MouseArea"))); } void tst_TestCore::testRewriterAddStatesArray() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); @@ -6720,7 +6962,7 @@ void tst_TestCore::testRewriterAddStatesArray() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6732,13 +6974,13 @@ void tst_TestCore::testRewriterAddStatesArray() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); - ModelNode stateNode = view->createModelNode("Qt/State", 4, 7); + ModelNode stateNode = view->createModelNode("QtQuick.State", 1, 0); rootNode.nodeListProperty(QLatin1String("states")).reparentHere(stateNode); const QString expected1 = QLatin1String("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "states: [\n" @@ -6748,11 +6990,11 @@ void tst_TestCore::testRewriterAddStatesArray() "}"); QCOMPARE(textEdit.toPlainText(), expected1); - ModelNode stateNode2 = view->createModelNode("Qt/State", 4, 7); + ModelNode stateNode2 = view->createModelNode("QtQuick.State", 1, 0); rootNode.nodeListProperty(QLatin1String("states")).reparentHere(stateNode2); const QString expected2 = QLatin1String("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "states: [\n" @@ -6768,7 +7010,7 @@ void tst_TestCore::testRewriterAddStatesArray() void tst_TestCore::testRewriterRemoveStates() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " states: [\n" @@ -6782,7 +7024,7 @@ void tst_TestCore::testRewriterRemoveStates() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6794,7 +7036,7 @@ void tst_TestCore::testRewriterRemoveStates() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); NodeListProperty statesProperty = rootNode.nodeListProperty(QLatin1String("states")); QVERIFY(statesProperty.isValid()); @@ -6804,7 +7046,7 @@ void tst_TestCore::testRewriterRemoveStates() state.destroy(); const QLatin1String expected1("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " states: [\n" @@ -6818,7 +7060,7 @@ void tst_TestCore::testRewriterRemoveStates() state.destroy(); const QLatin1String expected2("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); @@ -6828,7 +7070,7 @@ void tst_TestCore::testRewriterRemoveStates() void tst_TestCore::testRewriterRemoveObjectDefinition() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " MouseArea {\n" @@ -6840,7 +7082,7 @@ void tst_TestCore::testRewriterRemoveObjectDefinition() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6853,24 +7095,24 @@ void tst_TestCore::testRewriterRemoveObjectDefinition() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); QCOMPARE(rootNode.nodeProperty(QLatin1String("data")).toNodeListProperty().toModelNodeList().size(), 2); ModelNode childNode = rootNode.nodeProperty(QLatin1String("data")).toNodeListProperty().toModelNodeList().at(1); - QCOMPARE(childNode.type(), QString(QLatin1String("Qt/MouseArea"))); + QCOMPARE(childNode.type(), QString(QLatin1String("QtQuick.MouseArea"))); childNode.destroy(); QCOMPARE(rootNode.nodeProperty(QLatin1String("data")).toNodeListProperty().toModelNodeList().size(), 1); childNode = rootNode.nodeProperty(QLatin1String("data")).toNodeListProperty().toModelNodeList().at(0); - QCOMPARE(childNode.type(), QString(QLatin1String("Qt/MouseArea"))); + QCOMPARE(childNode.type(), QString(QLatin1String("QtQuick.MouseArea"))); childNode.destroy(); QVERIFY(!rootNode.hasProperty(QLatin1String("data"))); const QString expected = QLatin1String("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " // some comment here\n" @@ -6878,9 +7120,9 @@ void tst_TestCore::testRewriterRemoveObjectDefinition() QCOMPARE(textEdit.toPlainText(), expected); // don't crash when deleting nodes not in any hierarchy - ModelNode node1 = view->createModelNode("Qt/Rectangle", 4, 7); - ModelNode node2 = addNodeListChild(node1, "Qt/Item", 4, 7, "data"); - ModelNode node3 = addNodeListChild(node2, "Qt/Item", 4, 7, "data"); + ModelNode node1 = view->createModelNode("QtQuick.Rectangle", 1, 0); + ModelNode node2 = addNodeListChild(node1, "QtQuick.Item", 1, 1, "data"); + ModelNode node3 = addNodeListChild(node2, "QtQuick.Item", 1, 1, "data"); node3.destroy(); node1.destroy(); @@ -6889,7 +7131,7 @@ void tst_TestCore::testRewriterRemoveObjectDefinition() void tst_TestCore::testRewriterRemoveScriptBinding() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " x: 10; // some comment\n" @@ -6899,7 +7141,7 @@ void tst_TestCore::testRewriterRemoveScriptBinding() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6912,7 +7154,7 @@ void tst_TestCore::testRewriterRemoveScriptBinding() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); QCOMPARE(rootNode.properties().size(), 2); QVERIFY(rootNode.hasProperty(QLatin1String("x"))); @@ -6929,7 +7171,7 @@ void tst_TestCore::testRewriterRemoveScriptBinding() QCOMPARE(rootNode.properties().size(), 0); const QString expected = QLatin1String("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " // some comment\n" @@ -6940,7 +7182,7 @@ void tst_TestCore::testRewriterRemoveScriptBinding() void tst_TestCore::testRewriterNodeReparenting() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" @@ -6952,7 +7194,7 @@ void tst_TestCore::testRewriterNodeReparenting() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -6965,15 +7207,15 @@ void tst_TestCore::testRewriterNodeReparenting() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); ModelNode itemNode = rootNode.nodeListProperty("data").toModelNodeList().at(0); QVERIFY(itemNode.isValid()); - QCOMPARE(itemNode.type(), QLatin1String("Qt/Item")); + QCOMPARE(itemNode.type(), QLatin1String("QtQuick.Item")); ModelNode mouseArea = itemNode.nodeListProperty("data").toModelNodeList().at(0); QVERIFY(mouseArea.isValid()); - QCOMPARE(mouseArea.type(), QLatin1String("Qt/MouseArea")); + QCOMPARE(mouseArea.type(), QLatin1String("QtQuick.MouseArea")); rootNode.nodeListProperty("data").reparentHere(mouseArea); @@ -6981,7 +7223,7 @@ void tst_TestCore::testRewriterNodeReparenting() QCOMPARE(rootNode.nodeListProperty("data").toModelNodeList().size(), 2); QString expected = "\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" @@ -6993,9 +7235,9 @@ void tst_TestCore::testRewriterNodeReparenting() QCOMPARE(textEdit.toPlainText(), expected); // reparenting outside of the hierarchy - ModelNode node1 = view->createModelNode("Qt/Rectangle", 4, 7); - ModelNode node2 = view->createModelNode("Qt/Item", 4, 7); - ModelNode node3 = view->createModelNode("Qt/Item", 4, 7); + ModelNode node1 = view->createModelNode("QtQuick.Rectangle", 1, 0); + ModelNode node2 = view->createModelNode("QtQuick.Item", 1, 1); + ModelNode node3 = view->createModelNode("QtQuick.Item", 1, 1); node2.nodeListProperty("data").reparentHere(node3); node1.nodeListProperty("data").reparentHere(node2); @@ -7003,7 +7245,7 @@ void tst_TestCore::testRewriterNodeReparenting() rootNode.nodeListProperty("data").reparentHere(node1); expected = "\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" @@ -7023,11 +7265,11 @@ void tst_TestCore::testRewriterNodeReparenting() QCOMPARE(textEdit.toPlainText(), expected); // reparent out of the hierarchy - ModelNode node4 = view->createModelNode("Qt/Rectangle", 4, 7); + ModelNode node4 = view->createModelNode("QtQuick.Rectangle", 1, 0); node4.nodeListProperty("data").reparentHere(node1); expected = "\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" @@ -7043,7 +7285,7 @@ void tst_TestCore::testRewriterNodeReparenting() void tst_TestCore::testRewriterNodeReparentingWithTransaction() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " id: rootItem\n" @@ -7060,7 +7302,7 @@ void tst_TestCore::testRewriterNodeReparentingWithTransaction() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -7073,17 +7315,17 @@ void tst_TestCore::testRewriterNodeReparentingWithTransaction() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QLatin1String("QtQuick.Rectangle")); QCOMPARE(rootNode.id(), QLatin1String("rootItem")); ModelNode item1Node = rootNode.nodeListProperty("data").toModelNodeList().at(0); QVERIFY(item1Node.isValid()); - QCOMPARE(item1Node.type(), QLatin1String("Qt/Item")); + QCOMPARE(item1Node.type(), QLatin1String("QtQuick.Item")); QCOMPARE(item1Node.id(), QLatin1String("firstItem")); ModelNode item2Node = rootNode.nodeListProperty("data").toModelNodeList().at(1); QVERIFY(item2Node.isValid()); - QCOMPARE(item2Node.type(), QLatin1String("Qt/Item")); + QCOMPARE(item2Node.type(), QLatin1String("QtQuick.Item")); QCOMPARE(item2Node.id(), QLatin1String("secondItem")); RewriterTransaction transaction = testRewriterView->beginRewriterTransaction(); @@ -7094,7 +7336,7 @@ void tst_TestCore::testRewriterNodeReparentingWithTransaction() transaction.commit(); const QLatin1String expected("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " id: rootItem\n" @@ -7113,7 +7355,7 @@ void tst_TestCore::testRewriterNodeReparentingWithTransaction() void tst_TestCore::testRewriterMovingInOut() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); @@ -7121,7 +7363,7 @@ void tst_TestCore::testRewriterMovingInOut() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -7134,13 +7376,13 @@ void tst_TestCore::testRewriterMovingInOut() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); - ModelNode newNode = view->createModelNode("Qt/MouseArea", 4, 7); + ModelNode newNode = view->createModelNode("QtQuick.MouseArea", 1, 1); rootNode.nodeListProperty(QLatin1String("data")).reparentHere(newNode); const QLatin1String expected1("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "MouseArea {\n" @@ -7159,17 +7401,19 @@ void tst_TestCore::testRewriterMovingInOut() newNode.destroy(); const QLatin1String expected2("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); QCOMPARE(textEdit.toPlainText(), expected2); + + QApplication::processEvents(); } void tst_TestCore::testRewriterMovingInOutWithTransaction() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); @@ -7177,7 +7421,7 @@ void tst_TestCore::testRewriterMovingInOutWithTransaction() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -7190,11 +7434,11 @@ void tst_TestCore::testRewriterMovingInOutWithTransaction() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); RewriterTransaction transaction = view->beginRewriterTransaction(); - ModelNode newNode = view->createModelNode("Qt/MouseArea", 4, 7); + ModelNode newNode = view->createModelNode("QtQuick.MouseArea", 1, 1); rootNode.nodeListProperty(QLatin1String("data")).reparentHere(newNode); #define move(node, x, y) {\ @@ -7210,17 +7454,18 @@ void tst_TestCore::testRewriterMovingInOutWithTransaction() transaction.commit(); const QLatin1String expected2("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" "}"); QCOMPARE(textEdit.toPlainText(), expected2); + QApplication::processEvents(); } void tst_TestCore::testRewriterComplexMovingInOut() { const QLatin1String qmlString("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" @@ -7230,7 +7475,7 @@ void tst_TestCore::testRewriterComplexMovingInOut() textEdit.setPlainText(qmlString); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -7243,14 +7488,14 @@ void tst_TestCore::testRewriterComplexMovingInOut() ModelNode rootNode = view->rootModelNode(); QVERIFY(rootNode.isValid()); - QCOMPARE(rootNode.type(), QString("Qt/Rectangle")); + QCOMPARE(rootNode.type(), QString("QtQuick.Rectangle")); ModelNode itemNode = rootNode.nodeListProperty(QLatin1String("data")).toModelNodeList().at(0); - ModelNode newNode = view->createModelNode("Qt/MouseArea", 4, 7); + ModelNode newNode = view->createModelNode("QtQuick.MouseArea", 1, 1); rootNode.nodeListProperty(QLatin1String("data")).reparentHere(newNode); const QLatin1String expected1("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" @@ -7270,7 +7515,7 @@ void tst_TestCore::testRewriterComplexMovingInOut() move(newNode, 3, 3); const QLatin1String expected2("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" @@ -7286,7 +7531,7 @@ void tst_TestCore::testRewriterComplexMovingInOut() itemNode.nodeListProperty(QLatin1String("data")).reparentHere(newNode); const QLatin1String expected3("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" @@ -7306,22 +7551,23 @@ void tst_TestCore::testRewriterComplexMovingInOut() newNode.destroy(); const QLatin1String expected4("\n" - "import Qt 4.7\n" + "import QtQuick 1.1\n" "\n" "Rectangle {\n" " Item {\n" " }\n" "}"); QCOMPARE(textEdit.toPlainText(), expected4); + QApplication::processEvents(); } void tst_TestCore::removeCenteredInAnchorByDetaching() { QPlainTextEdit textEdit1; - textEdit1.setPlainText("import Qt 4.7; Item { Rectangle { id: child; anchors.centerIn: parent } }"); + textEdit1.setPlainText("import QtQuick 1.1; Item { Rectangle { id: child; anchors.centerIn: parent } }"); NotIndentingTextEditModifier modifier1(&textEdit1); - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(Model::create("QtQuick.Item")); QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView()); testRewriterView1->setTextModifier(&modifier1); @@ -7372,7 +7618,7 @@ void tst_TestCore::removeCenteredInAnchorByDetaching() void tst_TestCore::changePropertyBinding() { - QScopedPointer<Model> model(Model::create("Qt/Item")); + QScopedPointer<Model> model(createModel("QtQuick.Item")); QVERIFY(model.data()); QScopedPointer<TestView> view(new TestView(model.data())); @@ -7381,7 +7627,7 @@ void tst_TestCore::changePropertyBinding() ModelNode rootModelNode(view->rootModelNode()); rootModelNode.variantProperty("width") = 20; - ModelNode firstChild = addNodeListChild(rootModelNode, "Qt/Rectangle", 4, 7, "data"); + ModelNode firstChild = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"); firstChild.bindingProperty("width").setExpression(QString("parent.width")); firstChild.variantProperty("height")= 10; QVERIFY(firstChild.isValid()); @@ -7421,7 +7667,7 @@ void tst_TestCore::loadTestFiles() textEdit.setPlainText(QString(file.readAll())); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -7432,7 +7678,7 @@ void tst_TestCore::loadTestFiles() QVERIFY(model.data()); ModelNode rootModelNode(testRewriterView->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QLatin1String("Qt/Item")); + QCOMPARE(rootModelNode.type(), QLatin1String("QtQuick.Item")); QVERIFY(rootModelNode.allDirectSubModelNodes().isEmpty()); } @@ -7444,7 +7690,7 @@ void tst_TestCore::loadTestFiles() textEdit.setPlainText(QString(file.readAll())); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -7455,14 +7701,14 @@ void tst_TestCore::loadTestFiles() QVERIFY(model.data()); ModelNode rootModelNode(testRewriterView->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootModelNode.type(), QLatin1String("QtQuick.Rectangle")); QCOMPARE(rootModelNode.allDirectSubModelNodes().count(), 1); QCOMPARE(rootModelNode.variantProperty("width").value().toInt(), 200); QCOMPARE(rootModelNode.variantProperty("height").value().toInt(), 200); ModelNode textNode(rootModelNode.allDirectSubModelNodes().first()); QVERIFY(textNode.isValid()); - QCOMPARE(textNode.type(), QLatin1String("Qt/Text")); + QCOMPARE(textNode.type(), QLatin1String("QtQuick.Text")); QCOMPARE(textNode.variantProperty("x").value().toInt(), 66); QCOMPARE(textNode.variantProperty("y").value().toInt(), 93); } @@ -7474,7 +7720,7 @@ void tst_TestCore::loadTestFiles() textEdit.setPlainText(QString(file.readAll())); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -7485,7 +7731,7 @@ void tst_TestCore::loadTestFiles() QVERIFY(model.data()); ModelNode rootModelNode(testRewriterView->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootModelNode.type(), QLatin1String("QtQuick.Rectangle")); QCOMPARE(rootModelNode.allDirectSubModelNodes().count(), 4); QCOMPARE(rootModelNode.variantProperty("width").value().toInt(), 200); QCOMPARE(rootModelNode.variantProperty("height").value().toInt(), 200); @@ -7496,14 +7742,14 @@ void tst_TestCore::loadTestFiles() ModelNode textNode(rootModelNode.nodeListProperty("data").toModelNodeList().first()); QVERIFY(textNode.isValid()); QCOMPARE(textNode.id(), QLatin1String("text")); - QCOMPARE(textNode.type(), QLatin1String("Qt/Text")); + QCOMPARE(textNode.type(), QLatin1String("QtQuick.Text")); QCOMPARE(textNode.variantProperty("x").value().toInt(), 66); QCOMPARE(textNode.variantProperty("y").value().toInt(), 93); ModelNode imageNode(rootModelNode.nodeListProperty("data").toModelNodeList().last()); QVERIFY(imageNode.isValid()); QCOMPARE(imageNode.id(), QLatin1String("image1")); - QCOMPARE(imageNode.type(), QLatin1String("Qt/Image")); + QCOMPARE(imageNode.type(), QLatin1String("QtQuick.Image")); QCOMPARE(imageNode.variantProperty("x").value().toInt(), 41); QCOMPARE(imageNode.variantProperty("y").value().toInt(), 46); QCOMPARE(imageNode.variantProperty("source").value().toUrl(), QUrl("images/qtcreator.png")); @@ -7523,7 +7769,7 @@ void tst_TestCore::loadTestFiles() textEdit.setPlainText(QString(file.readAll())); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -7535,12 +7781,12 @@ void tst_TestCore::loadTestFiles() QVERIFY(model.data()); ModelNode rootModelNode(testRewriterView->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.type(), QLatin1String("Qt/Rectangle")); + QCOMPARE(rootModelNode.type(), QLatin1String("QtQuick.Rectangle")); QVERIFY(!rootModelNode.allDirectSubModelNodes().isEmpty()); } } -static QString rectWithGradient = "import Qt 4.7\n" +static QString rectWithGradient = "import QtQuick 1.1\n" "Rectangle {\n" " gradient: Gradient {\n" " id: pGradient\n" @@ -7560,7 +7806,7 @@ void tst_TestCore::loadGradient() textEdit.setPlainText(rectWithGradient); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -7579,7 +7825,7 @@ void tst_TestCore::loadGradient() QVERIFY(gradientProperty.isNodeProperty()); ModelNode gradientPropertyModelNode = gradientProperty.toNodeProperty().modelNode(); QVERIFY(gradientPropertyModelNode.isValid()); - QCOMPARE(gradientPropertyModelNode.type(), QString("Qt/Gradient")); + QCOMPARE(gradientPropertyModelNode.type(), QString("QtQuick.Gradient")); QCOMPARE(gradientPropertyModelNode.allDirectSubModelNodes().size(), 2); AbstractProperty stopsProperty = gradientPropertyModelNode.property("stops"); @@ -7592,7 +7838,7 @@ void tst_TestCore::loadGradient() ModelNode pOne = stops.first(); ModelNode pTwo = stops.last(); - QCOMPARE(pOne.type(), QString("Qt/GradientStop")); + QCOMPARE(pOne.type(), QString("QtQuick.GradientStop")); QCOMPARE(pOne.id(), QString("pOne")); QCOMPARE(pOne.allDirectSubModelNodes().size(), 0); QCOMPARE(pOne.propertyNames().size(), 2); @@ -7601,7 +7847,7 @@ void tst_TestCore::loadGradient() QCOMPARE(pOne.variantProperty("color").value().type(), QVariant::Color); QCOMPARE(pOne.variantProperty("color").value().value<QColor>(), QColor("lightsteelblue")); - QCOMPARE(pTwo.type(), QString("Qt/GradientStop")); + QCOMPARE(pTwo.type(), QString("QtQuick.GradientStop")); QCOMPARE(pTwo.id(), QString("pTwo")); QCOMPARE(pTwo.allDirectSubModelNodes().size(), 0); QCOMPARE(pTwo.propertyNames().size(), 2); @@ -7614,8 +7860,8 @@ void tst_TestCore::loadGradient() { ModelNode gradientNode = rootModelNode.allDirectSubModelNodes().last(); QVERIFY(gradientNode.isValid()); - QVERIFY(!gradientNode.metaInfo().isSubclassOf("Qt/Item", -1, -1)); - QCOMPARE(gradientNode.type(), QString("Qt/Gradient")); + QVERIFY(!gradientNode.metaInfo().isSubclassOf("QtQuick.Item", -1, -1)); + QCOMPARE(gradientNode.type(), QString("QtQuick.Gradient")); QCOMPARE(gradientNode.id(), QString("secondGradient")); QCOMPARE(gradientNode.allDirectSubModelNodes().size(), 2); @@ -7629,7 +7875,7 @@ void tst_TestCore::loadGradient() ModelNode nOne = stops.first(); ModelNode nTwo = stops.last(); - QCOMPARE(nOne.type(), QString("Qt/GradientStop")); + QCOMPARE(nOne.type(), QString("QtQuick.GradientStop")); QCOMPARE(nOne.id(), QString("nOne")); QCOMPARE(nOne.allDirectSubModelNodes().size(), 0); QCOMPARE(nOne.propertyNames().size(), 2); @@ -7638,7 +7884,7 @@ void tst_TestCore::loadGradient() QCOMPARE(nOne.variantProperty("color").value().type(), QVariant::Color); QCOMPARE(nOne.variantProperty("color").value().value<QColor>(), QColor("blue")); - QCOMPARE(nTwo.type(), QString("Qt/GradientStop")); + QCOMPARE(nTwo.type(), QString("QtQuick.GradientStop")); QCOMPARE(nTwo.id(), QString("nTwo")); QCOMPARE(nTwo.allDirectSubModelNodes().size(), 0); QCOMPARE(nTwo.propertyNames().size(), 2); @@ -7656,7 +7902,7 @@ void tst_TestCore::changeGradientId() textEdit.setPlainText(rectWithGradient); NotIndentingTextEditModifier textModifier(&textEdit); - QScopedPointer<Model> model(Model::create("Qt/Item", 4, 7)); + QScopedPointer<Model> model(Model::create("QtQuick.Item", 1, 1)); QVERIFY(model.data()); QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView()); @@ -7689,7 +7935,7 @@ void tst_TestCore::changeGradientId() firstStop.destroy(); QVERIFY(!firstStop.isValid()); - ModelNode gradientStop = addNodeListChild(gradientNode, "Qt/GradientStop", 4, 7, "stops"); + ModelNode gradientStop = addNodeListChild(gradientNode, "QtQuick.GradientStop", 1, 0, "stops"); gradientStop.variantProperty("position") = 0.5; gradientStop.variantProperty("color") = QColor("yellow"); diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.h b/tests/auto/qml/qmldesigner/coretests/tst_testcore.h index b98389749f..159bd5744c 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.h +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.h @@ -44,6 +44,10 @@ public: private slots: void initTestCase(); void cleanupTestCase(); + void init(); + void cleanup(); + + // // unit tests MetaInfo, NodeMetaInfo, PropertyMetaInfo @@ -57,7 +61,10 @@ private slots: void testMetaInfoEnums(); void testMetaInfoProperties(); void testMetaInfoDotProperties(); + void testMetaInfoQtQuick1Vs2(); void testMetaInfoListProperties(); + void testQtQuick20Basic(); + void testQtQuick20BasicRectangle(); // // unit tests Model, ModelNode, NodeProperty, AbstractView @@ -161,6 +168,7 @@ private slots: // integration tests // void testBasicStates(); + void testBasicStatesQtQuick20(); void testStates(); void testStatesBaseState(); void testStatesRewriter(); diff --git a/tests/auto/qml/qmldesigner/testview.cpp b/tests/auto/qml/qmldesigner/testview.cpp index 4ba56a472e..ce6860b212 100644 --- a/tests/auto/qml/qmldesigner/testview.cpp +++ b/tests/auto/qml/qmldesigner/testview.cpp @@ -30,6 +30,7 @@ #include "testview.h" #include <QDebug> +#include <QUrl> #include <qtestcase.h> #include <abstractproperty.h> #include <bindingproperty.h> @@ -151,10 +152,10 @@ void TestView::nodeOrderChanged(const QmlDesigner::NodeListProperty &listPropert m_methodCalls += MethodCall("nodeOrderChanged", QStringList() << listProperty.name() << movedNode.id() << QString::number(oldIndex)); } -void TestView::stateChanged(const QmlDesigner::QmlModelState &newQmlModelState, const QmlDesigner::QmlModelState &oldQmlModelState) +void TestView::actualStateChanged(const QmlDesigner::ModelNode &node) { - QmlDesigner::QmlModelView::stateChanged(newQmlModelState, oldQmlModelState); - m_methodCalls += MethodCall("stateChanged", QStringList() << newQmlModelState.name() << oldQmlModelState.name()); + QmlDesigner::QmlModelView::actualStateChanged(node); + m_methodCalls += MethodCall("actualStateChanged", QStringList() << node.id()); } QList<TestView::MethodCall> &TestView::methodCalls() diff --git a/tests/auto/qml/qmldesigner/testview.h b/tests/auto/qml/qmldesigner/testview.h index 28a633db85..4a283abf6d 100644 --- a/tests/auto/qml/qmldesigner/testview.h +++ b/tests/auto/qml/qmldesigner/testview.h @@ -72,8 +72,7 @@ public: void nodeOrderChanged(const QmlDesigner::NodeListProperty &listProperty, const QmlDesigner::ModelNode &movedNode, int oldIndex); - void stateChanged(const QmlDesigner::QmlModelState &newQmlModelState, const QmlDesigner::QmlModelState &oldQmlModelState); - + void actualStateChanged(const QmlDesigner::ModelNode &node); QList<MethodCall> &methodCalls(); QString lastFunction() const; diff --git a/tests/auto/qml/qmljssimplereader/qmljssimplereader.pro b/tests/auto/qml/qmljssimplereader/qmljssimplereader.pro new file mode 100644 index 0000000000..20722acddf --- /dev/null +++ b/tests/auto/qml/qmljssimplereader/qmljssimplereader.pro @@ -0,0 +1,12 @@ +include(../../qttest.pri) + +DEFINES+=QTCREATORDIR=\\\"$$IDE_SOURCE_TREE\\\" +DEFINES+=TESTSRCDIR=\\\"$$PWD\\\" + +include($$IDE_SOURCE_TREE/src/libs/utils/utils.pri) +include($$IDE_SOURCE_TREE/src/libs/qmljs/qmljs.pri) + +TARGET = tst_qmljssimplereader + +SOURCES += \ + tst_qmljssimplereader.cpp diff --git a/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp b/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp new file mode 100644 index 0000000000..80972ca410 --- /dev/null +++ b/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp @@ -0,0 +1,257 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include <qmljs/qmljssimplereader.h> + +#include <QtTest> +#include <algorithm> + +using namespace QmlJS; + +class tst_SimpleReader : public QObject +{ + Q_OBJECT +public: + tst_SimpleReader(); + +private slots: + void testWellFormed(); + void testIllFormed01(); + void testIllFormed02(); + void testArrays(); + void testBug01(); +}; + +tst_SimpleReader::tst_SimpleReader() +{ +} + +void tst_SimpleReader::testWellFormed() +{ + char source[] = "RootNode {\n" + " ChildNode {\n" + " property01: 10\n" + " }\n" + " ChildNode {\n" + " propertyString: \"str\"\n" + " InnerChild {\n" + " test: \"test\"\n" + " }\n" + " }\n" + " propertyBlah: false\n" + "}\n"; + + QmlJS::SimpleReaderNode::WeakPtr weak01; + QmlJS::SimpleReaderNode::WeakPtr weak02; + { + QmlJS::SimpleReader reader; + QmlJS::SimpleReaderNode::Ptr rootNode = reader.readFromSource(source); + QVERIFY(reader.errors().isEmpty()); + QVERIFY(rootNode); + QVERIFY(rootNode->isValid()); + QCOMPARE(rootNode->name(), QLatin1String("RootNode")); + + QCOMPARE(rootNode->children().count(), 2); + QCOMPARE(rootNode->properties().count(), 1); + + QVERIFY(rootNode->properties().contains("propertyBlah")); + QCOMPARE(rootNode->property("property01").toBool(), false); + + QVERIFY(rootNode->children().first()->isValid()); + QVERIFY(!rootNode->children().first()->isRoot()); + + QVERIFY(rootNode->children().first()->properties().contains("property01")); + QCOMPARE(rootNode->children().first()->property("property01").toInt(), 10); + + QmlJS::SimpleReaderNode::Ptr secondChild = rootNode->children().at(1); + + QVERIFY(secondChild); + QVERIFY(secondChild->isValid()); + QVERIFY(!secondChild->isRoot()); + QCOMPARE(secondChild->name(), QLatin1String("ChildNode")); + + QVERIFY(secondChild->properties().contains("propertyString")); + QCOMPARE(secondChild->property("propertyString").toString(), QLatin1String("str")); + + QCOMPARE(secondChild->children().count(), 1); + + QmlJS::SimpleReaderNode::Ptr innerChild = secondChild->children().first(); + + QVERIFY(innerChild); + QVERIFY(innerChild->isValid()); + QVERIFY(!innerChild->isRoot()); + QCOMPARE(innerChild->name(), QLatin1String("InnerChild")); + + QVERIFY(innerChild->properties().contains("test")); + QCOMPARE(innerChild->property("test").toString(), QLatin1String("test")); + + weak01 = rootNode; + weak02 = secondChild; + } + + QVERIFY(!weak01); + QVERIFY(!weak02); +} + +void tst_SimpleReader::testIllFormed01() +{ + char source[] = "RootNode {\n" + " ChildNode {\n" + " property01: 10\n" + " }\n" + " ChildNode {\n" + " propertyString: \"str\"\n" + " InnerChild \n" //missing { + " test: \"test\"\n" + " }\n" + " }\n" + " propertyBlah: false\n" + "}\n"; + QmlJS::SimpleReader reader; + QmlJS::SimpleReaderNode::Ptr rootNode = reader.readFromSource(source); + + QVERIFY(!rootNode); + QVERIFY(!reader.errors().empty()); +} + +void tst_SimpleReader::testIllFormed02() +{ + char source[] = "RootNode {\n" + " ChildNode {\n" + " property01: 10\n" + " property01: 20\n" + " }\n" + " ChildNode {\n" + " propertyString: \"str\"\n" + " InnerChild {\n" + " test: \"test\"\n" + " test: \"test2\"\n" + " }\n" + " }\n" + "}\n"; + + QmlJS::SimpleReader reader; + QmlJS::SimpleReaderNode::Ptr rootNode = reader.readFromSource(source); + + QVERIFY(rootNode); + QVERIFY(rootNode->isValid()); + QVERIFY(rootNode->isRoot()); + + QVERIFY(!reader.errors().empty()); + QCOMPARE(reader.errors().count(), 2); + + QmlJS::SimpleReaderNode::Ptr firstChild = rootNode->children().at(0); + + QVERIFY(firstChild); + QVERIFY(firstChild->isValid()); + QVERIFY(!firstChild->isRoot()); + + QCOMPARE(firstChild->properties().count(), 1); + QVERIFY(firstChild->properties().contains("property01")); + QCOMPARE(firstChild->property("property01").toString(), QLatin1String("20")); +} + +void tst_SimpleReader::testArrays() +{ + char source[] = "RootNode {\n" + " propertyArray: [\"string01\", \"string02\" ]\n" + " ChildNode {\n" + " propertyArray: [\"string01\", \"string02\" ]\n" + " propertyArrayMixed: [\"string03\", [\"string01\", \"string02\"] ]\n" + " }\n" + "}\n"; + + QList<QVariant> variantList; + variantList << QVariant(QLatin1String("string01")) << QVariant(QLatin1String("string02")); + const QVariant variant = variantList; + + QmlJS::SimpleReader reader; + QmlJS::SimpleReaderNode::Ptr rootNode = reader.readFromSource(source); + + QVERIFY(rootNode); + QVERIFY(rootNode->isValid()); + QVERIFY(rootNode->isRoot()); + + QCOMPARE(rootNode->property("propertyArray"), variant); + + + QmlJS::SimpleReaderNode::Ptr firstChild = rootNode->children().at(0); + + QVERIFY(firstChild); + QVERIFY(firstChild->isValid()); + QVERIFY(!firstChild->isRoot()); + QCOMPARE(firstChild->property("propertyArray"), variant); + + QList<QVariant> variantList2; + variantList2 << QVariant(QLatin1String("string03")) << variant; + const QVariant variant2 = variantList2; + + QCOMPARE(firstChild->property("propertyArrayMixed"), variant2); +} + +void tst_SimpleReader::testBug01() +{ + char source[] = "\n" + "AutoTypes {\n" + " imports: [ \"import HelperWidgets 1.0\", \"import QtQuick 1.0\", \"import Bauhaus 1.0\" ]\n" + " Type {\n" + " typeNames: [\"int\"]\n" + " sourceFile: \"IntEditorTemplate.qml\"\n" + " }\n" + " Type {\n" + " typeNames: [\"real\", \"double\", \"qreal\"]\n" + " sourceFile: \"RealEditorTemplate.qml\"\n" + " }\n" + " Type {\n" + " typeNames: [\"string\", \"QString\", \"QUrl\", \"url\"]\n" + " sourceFile: \"StringEditorTemplate.qml\"\n" + " }\n" + " Type {\n" + " typeNames: [\"bool\", \"boolean\"]\n" + " sourceFile: \"BooleanEditorTemplate.qml\"\n" + " }\n" + " Type {\n" + " typeNames: [\"color\", \"QColor\"]\n" + " sourceFile: \"ColorEditorTemplate.qml\"\n" + " }\n" + "}\n"; + + QmlJS::SimpleReader reader; + QmlJS::SimpleReaderNode::Ptr rootNode = reader.readFromSource(source); + + QVERIFY(rootNode); + QVERIFY(rootNode->isValid()); + QVERIFY(rootNode->isRoot()); + + QCOMPARE(rootNode->propertyNames().count(), 1); +} + +QTEST_MAIN(tst_SimpleReader); + +#include "tst_qmljssimplereader.moc" diff --git a/tests/manual/appwizards/main.cpp b/tests/manual/appwizards/main.cpp index 661cd81304..ca5f030aa6 100644 --- a/tests/manual/appwizards/main.cpp +++ b/tests/manual/appwizards/main.cpp @@ -71,26 +71,6 @@ int main(int argc, char *argv[]) } { - const QString rootPath = QLatin1String("../appwizards/qmlimportscenario_02/"); - QtQuickApp sAppImport02; - sAppImport02.setProjectPath(projectPath); - sAppImport02.setProjectName(QLatin1String("qml_imported_scenario_02")); - sAppImport02.setMainQml(QtQuickApp::ModeImport, rootPath + QLatin1String("subfolder1/myqmlapp.qml")); - QStringList moduleNames; - moduleNames.append(QLatin1String("no.trolltech.QmlModule01")); - moduleNames.append(QLatin1String("com.nokia.QmlModule02")); - QStringList importPaths; - importPaths.append(rootPath + QLatin1String("subfolder2/")); - importPaths.append(rootPath + QLatin1String("subfolder3/")); - if (!sAppImport02.setExternalModules(moduleNames, importPaths)) { - qDebug() << sAppImport02.error(); - return 2; - } - if (!sAppImport02.generateFiles(&errorMessage)) - return 1; - } - - { Html5App sAppNew; sAppNew.setProjectPath(projectPath); sAppNew.setProjectName(QLatin1String("new_html5_app")); diff --git a/tests/manual/appwizards/qmlimportscenario_02/myqmlapp.qmlproject b/tests/manual/appwizards/qmlimportscenario_02/myqmlapp.qmlproject deleted file mode 100644 index 1040b01e31..0000000000 --- a/tests/manual/appwizards/qmlimportscenario_02/myqmlapp.qmlproject +++ /dev/null @@ -1,17 +0,0 @@ -import QmlProject 1.0 - -Project { - QmlFiles { - directory: "subfolder1" - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } - importPaths: [ - "subfolder2", - "subfolder3" - ] -} diff --git a/tests/manual/appwizards/qmlimportscenario_02/subfolder1/myqmlapp.qml b/tests/manual/appwizards/qmlimportscenario_02/subfolder1/myqmlapp.qml deleted file mode 100644 index bfb548023f..0000000000 --- a/tests/manual/appwizards/qmlimportscenario_02/subfolder1/myqmlapp.qml +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -import QtQuick 1.0 - -Rectangle { - width: 360 - height: 360 - Text { - text: "Hello World" - anchors.centerIn: parent - } - MouseArea { - anchors.fill: parent - onClicked: { - Qt.quit(); - } - } -} diff --git a/tests/manual/appwizards/qmlimportscenario_02/subfolder2/no/trolltech/QmlModule01/apple.svg b/tests/manual/appwizards/qmlimportscenario_02/subfolder2/no/trolltech/QmlModule01/apple.svg deleted file mode 100644 index 31288ecce4..0000000000 --- a/tests/manual/appwizards/qmlimportscenario_02/subfolder2/no/trolltech/QmlModule01/apple.svg +++ /dev/null @@ -1,16 +0,0 @@ -<svg height="100%" version="1.1" viewBox="0 0 50 50" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"> - <defs> - </defs> - <metadata> - <rdf:RDF> - <cc:Work rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> - <dc:title/> - </cc:Work> - </rdf:RDF> - </metadata> - <path d="m22.7,3.84c-1.06,3.24-1.17,7.42-0.191,12.7" fill="none" stroke="#830" stroke-width="2.5"/> - <path d="m36.8,12.9c6.24,3.02,11.1,9.74,10.3,16.9-0.548,5.22-3.35,10.1-7.3,13.5-3.99,2.83-7.36-0.79-11.9-0.037-4.75,0.587-8.68,3.8-13.3,1.88-8.57-3.18-12.1-6.91-12.2-16.4,0.0813-6.01,2.05-12,7.75-14.6,2.95-1.03,8.83-0.118,12,0.363,4.83-3.24,9.26-3.55,14.6-1.61z" fill="#3A0"/> - <path d="m14,16.1c0.683,1.19-1.08,1.56-2.56,3.1-1.48,1.53-2.28,4.13-3.78,3.92-1.5-0.21-0.485-4.18,1.47-5.74,1.95-1.56,4.19-2.47,4.87-1.28z" fill="#FFF" opacity="0.5"/> -</svg>
\ No newline at end of file diff --git a/tests/manual/appwizards/qmlimportscenario_02/subfolder2/no/trolltech/QmlModule01/qmldir b/tests/manual/appwizards/qmlimportscenario_02/subfolder2/no/trolltech/QmlModule01/qmldir deleted file mode 100644 index 3a36c14330..0000000000 --- a/tests/manual/appwizards/qmlimportscenario_02/subfolder2/no/trolltech/QmlModule01/qmldir +++ /dev/null @@ -1 +0,0 @@ -QmlComponent01 1.0 QmlComponent01.qml
\ No newline at end of file diff --git a/tests/manual/appwizards/qmlimportscenario_02/subfolder3/com/nokia/QmlModule02/qmldir b/tests/manual/appwizards/qmlimportscenario_02/subfolder3/com/nokia/QmlModule02/qmldir deleted file mode 100644 index 33f694a57e..0000000000 --- a/tests/manual/appwizards/qmlimportscenario_02/subfolder3/com/nokia/QmlModule02/qmldir +++ /dev/null @@ -1 +0,0 @@ -QmlComponent02 1.0 QmlComponent02.qml
\ No newline at end of file diff --git a/tests/manual/appwizards/qmlimportscenario_02/subfolder3/com/nokia/QmlModule02/tomato.svg b/tests/manual/appwizards/qmlimportscenario_02/subfolder3/com/nokia/QmlModule02/tomato.svg deleted file mode 100644 index c0df58c20b..0000000000 --- a/tests/manual/appwizards/qmlimportscenario_02/subfolder3/com/nokia/QmlModule02/tomato.svg +++ /dev/null @@ -1,16 +0,0 @@ -<svg height="100%" id="svg2" version="1.1" viewBox="0 0 50 50" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"> - <defs id="defs14"> - </defs> - <metadata id="metadata4"> - <rdf:RDF> - <cc:Work rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> - <dc:title/> - </cc:Work> - </rdf:RDF> - </metadata> - <path d="M24.7,5.65c-2.7,2.23-3.2,5.65-2.2,10.8" fill="none" stroke="#080" stroke-width="2.5"/> - <path d="m41.6,16.9c6.71,7.89,3.30,18.5-2.42,23.6-5.73,5.11-16.2,6.50-26.6,1.84-10.4-4.7-13.1-21.3-3.65-27,9.45-5.68,26-6.29,32.6,1.6z" fill="#F00"/> - <path d="m15.6,15.3c0.683,1.19-1.88,1.16-4.97,4.10-2.95,2.8-2.64,6.7-4.14,6.5-1.50-0.2,0.72-7,2.67-8.5,1.95-1.56,5.80-3.27,6.48-2.08z" fill="#FFF" opacity="0.5"/> -</svg>
\ No newline at end of file diff --git a/tests/manual/debugger/simple/deep/deep/simple_test_app.h b/tests/manual/debugger/simple/deep/deep/simple_test_app.h index 8b16a4d553..376bc4cb73 100644 --- a/tests/manual/debugger/simple/deep/deep/simple_test_app.h +++ b/tests/manual/debugger/simple/deep/deep/simple_test_app.h @@ -149,7 +149,7 @@ namespace breakpoints { // <=== Break here. Twice<int> cc = Twice<int>(1); Twice<float> dd = Twice<float>(1.0); - dummyStatement(&a, &b, &c, &d, &e, &f, &z, bb, aa, cc, dd); + dummyStatement(&a, &b, &c, &d, &e, &f, &z, &bb, &aa, &cc, &dd); } } // namespace breakpoints diff --git a/tests/manual/debugger/simple/simple_test_app.cpp b/tests/manual/debugger/simple/simple_test_app.cpp index 01271d8028..715c69fecd 100644 --- a/tests/manual/debugger/simple/simple_test_app.cpp +++ b/tests/manual/debugger/simple/simple_test_app.cpp @@ -3676,11 +3676,22 @@ namespace qstring { dummyStatement(&str, &string, pstring); } + void testQStringRef() + { + QString str = "Hello"; + QStringRef ref(&str, 1, 2); + BREAK_HERE; + // Check ref "el" QString. + // Continue. + dummyStatement(&str, &ref); + } + void testQString() { testQString1(); testQString2(); testQString3(); + testQStringRef(); testQStringQuotes(); } @@ -3823,6 +3834,24 @@ namespace text { } // namespace text +namespace qprocess { + + void testQProcess() + { + return; + const int N = 14; + QProcess proc[N]; + for (int i = 0; i != N; ++i) { + proc[i].start("sleep 10"); + proc[i].waitForStarted(); + } + BREAK_HERE; + dummyStatement(&proc); + } + +} // namespace qprocess + + namespace qthread { class Thread : public QThread @@ -4191,11 +4220,13 @@ namespace qvector { { // This tests the display of a big vector. QVector<int> vec(10000); + for (int i = 0; i != vec.size(); ++i) + vec[i] = i * i; BREAK_HERE; // Expand vec. // Check vec <10000 items> QVector<int>. // Check vec.0 0 int. - // Check vec.1999 0 int. + // Check vec.1999 3996001 int. // Continue. // step over @@ -4486,6 +4517,31 @@ namespace namespc { } // namespace namespc +namespace gccextensions { + + void testGccExtensions() + { +#ifdef __GNUC__ + char v[8] = { 1, 2 }; + char w __attribute__ ((vector_size (8))) = { 1, 2 }; + int y[2] = { 1, 2 }; + int z __attribute__ ((vector_size (8))) = { 1, 2 }; + BREAK_HERE; + // Expand v. + // Check v.0 1 char. + // Check v.1 2 char. + // Check w.0 1 char. + // Check w.1 2 char. + // Check y.0 1 int. + // Check y.1 2 int. + // Check z.0 1 int. + // Check z.1 2 int. + // Continue. + dummyStatement(&v, &w, &y, &z); +#endif + } + +} // namespace gccextension class Z : public QObject { @@ -4519,6 +4575,32 @@ namespace basic { // This tests display of basic types. + void testInt() + { + quint64 u64 = ULONG_LONG_MAX; + qint64 s64 = LONG_LONG_MAX; + quint32 u32 = ULONG_MAX; + qint32 s32 = LONG_MAX; + quint64 u64s = 0; + qint64 s64s = LONG_LONG_MIN; + quint32 u32s = 0; + qint32 s32s = LONG_MIN; + + BREAK_HERE; + // Check u64 18446744073709551615 quint64. + // Check s64 9223372036854775807 qint64. + // Check u32 4294967295 quint32. + // Check s32 2147483647 qint32. + // Check u64s 0 quint64. + // Check s64s -9223372036854775808 qint64. + // Check u32s 0 quint32. + // Check s32s -2147483648 qint32. + // Continue. + + dummyStatement(&u64, &s64, &u32, &s32, &u64s, &s64s, &u32s, &s32s); + } + + void testArray1() { double d[3][3]; @@ -5248,11 +5330,47 @@ namespace basic { dummyStatement(&i, &b, &s); } + #ifdef Q_COMPILER_RVALUE_REFS + struct X { X() : a(2), b(3) {} int a, b; }; + + X testRValueReferenceHelper1() + { + return X(); + } + + X testRValueReferenceHelper2(X &&x) + { + return x; + } + + void testRValueReference() + { + X &&x1 = testRValueReferenceHelper1(); + X &&x2 = testRValueReferenceHelper2(std::move(x1)); + X &&x3 = testRValueReferenceHelper2(testRValueReferenceHelper1()); + + X y1 = testRValueReferenceHelper1(); + X y2 = testRValueReferenceHelper2(std::move(y1)); + X y3 = testRValueReferenceHelper2(testRValueReferenceHelper1()); + + BREAK_HERE; + // Continue. + dummyStatement(&x1, &x2, &x3, &y1, &y2, &y3); + } + + #else + + void testRValueReference() {} + + #endif + void testBasic() { + testInt(); testReference1(); testReference2(); testReference3("hello"); + testRValueReference(); testDynamicReference(); testReturn(); testArray1(); @@ -6566,6 +6684,7 @@ int main(int argc, char *argv[]) // Check for normal dumpers. basic::testBasic(); + gccextensions::testGccExtensions(); qhostaddress::testQHostAddress(); varargs::testVaList(); @@ -6620,6 +6739,7 @@ int main(int argc, char *argv[]) qstringlist::testQStringList(); qstring::testQString(); qthread::testQThread(); + qprocess::testQProcess(); qurl::testQUrl(); qvariant::testQVariant(); qvector::testQVector(); diff --git a/tests/manual/debugger/simple/simple_test_app.pro b/tests/manual/debugger/simple/simple_test_app.pro index e7f85a4589..d7573c04f1 100644 --- a/tests/manual/debugger/simple/simple_test_app.pro +++ b/tests/manual/debugger/simple/simple_test_app.pro @@ -34,6 +34,11 @@ maemo5 { INSTALLS += target } +#*g++* { +# DEFINES += USE_CXX11 +# QMAKE_CXXFLAGS += -std=c++0x +#} + exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h):DEFINES += USE_PRIVATE exists(/usr/include/boost/optional.hpp): DEFINES += USE_BOOST exists(/usr/include/eigen2/Eigen/Core): DEFINES += USE_EIGEN diff --git a/tests/manual/proparser/main.cpp b/tests/manual/proparser/main.cpp index 8aea951902..8f7088504a 100644 --- a/tests/manual/proparser/main.cpp +++ b/tests/manual/proparser/main.cpp @@ -46,8 +46,10 @@ static void print(const QString &fileName, int lineNo, int type, const QString & { QString pfx = ((type & QMakeHandler::CategoryMask) == QMakeHandler::WarningMessage) ? QString::fromLatin1("WARNING: ") : QString(); - if (lineNo) + if (lineNo > 0) qWarning("%s%s:%d: %s", qPrintable(pfx), qPrintable(fileName), lineNo, qPrintable(msg)); + else if (lineNo) + qWarning("%s%s: %s", qPrintable(pfx), qPrintable(fileName), qPrintable(msg)); else qWarning("%s%s", qPrintable(pfx), qPrintable(msg)); } @@ -67,7 +69,7 @@ public: static EvalHandler evalHandler; static int evaluate(const QString &fileName, const QString &in_pwd, const QString &out_pwd, - bool cumulative, QMakeGlobals *option, QMakeParser *parser, int level) + bool cumulative, ProFileGlobals *option, QMakeParser *parser, int level) { static QSet<QString> visited; if (visited.contains(fileName)) @@ -140,30 +142,59 @@ int main(int argc, char **argv) { QCoreApplication app(argc, argv); - QStringList args = app.arguments(); - args.removeFirst(); - int level = -1; // verbose - if (args.count() && args.first() == QLatin1String("-v")) - level = 0, args.removeFirst(); - if (args.count() < 2) - qFatal("need at least two arguments: [-v] <cumulative?> <filenme> [<out_pwd> [<qmake options>]]"); - - QMakeGlobals option; + ProFileGlobals option; QString qmake = QString::fromLocal8Bit(qgetenv("TESTREADER_QMAKE")); if (qmake.isEmpty()) qmake = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmake"); option.qmake_abslocation = QDir::cleanPath(qmake); option.initProperties(); - if (args.count() >= 4) - option.setCommandLineArguments(args.mid(3)); - QMakeParser parser(0, &evalHandler); - bool cumulative = args[0] == QLatin1String("true"); - QFileInfo infi(args[1]); - QString file = infi.absoluteFilePath(); - QString in_pwd = infi.absolutePath(); - QString out_pwd = (args.count() > 2) ? QFileInfo(args[2]).absoluteFilePath() : in_pwd; + QStringList args = app.arguments(); + args.removeFirst(); + int level = -1; // verbose + bool cumulative = false; + QString file; + QString in_pwd; + QString out_pwd; + QMakeCmdLineParserState state(QDir::currentPath()); + for (int pos = 0; ; ) { + QMakeGlobals::ArgumentReturn cmdRet = option.addCommandLineArguments(state, args, &pos); + if (cmdRet == QMakeGlobals::ArgumentsOk) + break; + if (cmdRet == QMakeGlobals::ArgumentMalformed) { + qCritical("argument %s needs a parameter", qPrintable(args.at(pos - 1))); + return 3; + } + Q_ASSERT(cmdRet == QMakeGlobals::ArgumentUnknown); + QString arg = args.at(pos++); + if (arg == QLatin1String("-v")) { + level = 0; + } else if (arg == QLatin1String("-d")) { + option.debugLevel++; + } else if (arg == QLatin1String("-c")) { + cumulative = true; + } else if (arg.startsWith(QLatin1Char('-'))) { + qCritical("unrecognized option %s", qPrintable(arg)); + return 3; + } else if (file.isEmpty()) { + QFileInfo infi(arg); + file = QDir::cleanPath(infi.absoluteFilePath()); + in_pwd = QDir::cleanPath(infi.absolutePath()); + } else if (out_pwd.isEmpty()) { + out_pwd = QDir::cleanPath(QFileInfo(arg).absoluteFilePath()); + } else { + qCritical("excess argument '%s'", qPrintable(arg)); + return 3; + } + } + if (file.isEmpty()) { + qCritical("usage: testreader [-v] [-d [-d]] [-c] <filenme> [<out_pwd>] [<variable assignments>]"); + return 3; + } + if (out_pwd.isEmpty()) + out_pwd = in_pwd; option.setDirectories(in_pwd, out_pwd); + QMakeParser parser(0, &evalHandler); return evaluate(file, in_pwd, out_pwd, cumulative, &option, &parser, level); } diff --git a/tests/manual/ssh/remoteprocess/remoteprocesstest.h b/tests/manual/ssh/remoteprocess/remoteprocesstest.h index 2e923a893d..55abeebdae 100644 --- a/tests/manual/ssh/remoteprocess/remoteprocesstest.h +++ b/tests/manual/ssh/remoteprocess/remoteprocesstest.h @@ -70,10 +70,10 @@ private: const QSsh::SshConnectionParameters m_sshParams; QTimer * const m_timeoutTimer; QTextStream *m_textStream; - QSsh::SshConnection *m_sshConnection; - QSsh::SshRemoteProcessRunner * const m_remoteRunner; QSsh::SshRemoteProcess::Ptr m_catProcess; QSsh::SshRemoteProcess::Ptr m_echoProcess; + QSsh::SshConnection *m_sshConnection; + QSsh::SshRemoteProcessRunner * const m_remoteRunner; QByteArray m_remoteStdout; QByteArray m_remoteStderr; QByteArray m_remoteData; diff --git a/tests/manual/ssh/ssh.pro b/tests/manual/ssh/ssh.pro index 6284229802..fdfd768132 100644 --- a/tests/manual/ssh/ssh.pro +++ b/tests/manual/ssh/ssh.pro @@ -5,4 +5,4 @@ #------------------------------------------------- TEMPLATE = subdirs -SUBDIRS = errorhandling sftp remoteprocess shell sftpfsmodel +SUBDIRS = errorhandling sftp remoteprocess shell sftpfsmodel tunnel diff --git a/tests/manual/ssh/tunnel/argumentscollector.cpp b/tests/manual/ssh/tunnel/argumentscollector.cpp new file mode 100644 index 0000000000..a533ac966a --- /dev/null +++ b/tests/manual/ssh/tunnel/argumentscollector.cpp @@ -0,0 +1,174 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ +#include "argumentscollector.h" + +#include <QDir> +#include <QProcessEnvironment> + +#include <iostream> + +using namespace QSsh; + +using namespace std; + +ArgumentsCollector::ArgumentsCollector(const QStringList &args) + : m_arguments(args) +{ +} + +QSsh::SshConnectionParameters ArgumentsCollector::collect(bool &success) const +{ + SshConnectionParameters parameters; + parameters.host = QLatin1String("localhost"); + + try { + bool authTypeGiven = false; + bool portGiven = false; + bool timeoutGiven = false; + bool proxySettingGiven = false; + int pos; + int port; + + for (pos = 1; pos < m_arguments.count() - 1; ++pos) { + if (checkAndSetStringArg(pos, parameters.userName, "-u")) + continue; + if (checkAndSetIntArg(pos, port, portGiven, "-p") + || checkAndSetIntArg(pos, parameters.timeout, timeoutGiven, "-t")) + continue; + if (checkAndSetStringArg(pos, parameters.password, "-pwd")) { + if (!parameters.privateKeyFile.isEmpty()) + throw ArgumentErrorException(QLatin1String("-pwd and -k are mutually exclusive.")); + parameters.authenticationType + = SshConnectionParameters::AuthenticationByPassword; + authTypeGiven = true; + continue; + } + if (checkAndSetStringArg(pos, parameters.privateKeyFile, "-k")) { + if (!parameters.password.isEmpty()) + throw ArgumentErrorException(QLatin1String("-pwd and -k are mutually exclusive.")); + parameters.authenticationType + = SshConnectionParameters::AuthenticationByKey; + authTypeGiven = true; + continue; + } + if (!checkForNoProxy(pos, parameters.proxyType, proxySettingGiven)) + throw ArgumentErrorException(QLatin1String("unknown option ") + m_arguments.at(pos)); + } + + Q_ASSERT(pos <= m_arguments.count()); + if (pos == m_arguments.count() - 1) { + if (!checkForNoProxy(pos, parameters.proxyType, proxySettingGiven)) + throw ArgumentErrorException(QLatin1String("unknown option ") + m_arguments.at(pos)); + } + + if (!authTypeGiven) { + parameters.authenticationType = SshConnectionParameters::AuthenticationByKey; + parameters.privateKeyFile = QDir::homePath() + QLatin1String("/.ssh/id_rsa"); + } + + if (parameters.userName.isEmpty()) { + parameters.userName + = QProcessEnvironment::systemEnvironment().value(QLatin1String("USER")); + } + if (parameters.userName.isEmpty()) + throw ArgumentErrorException(QLatin1String("No user name given.")); + + if (parameters.host.isEmpty()) + throw ArgumentErrorException(QLatin1String("No host given.")); + + parameters.port = portGiven ? port : 22; + if (!timeoutGiven) + parameters.timeout = 30; + success = true; + } catch (ArgumentErrorException &ex) { + cerr << "Error: " << qPrintable(ex.error) << endl; + printUsage(); + success = false; + } + return parameters; +} + +void ArgumentsCollector::printUsage() const +{ + cerr << "Usage: " << qPrintable(m_arguments.first()) + << "[ -u <user> ] " + << "[ -pwd <password> | -k <private key file> ] [ -p <port> ] " + << "[ -t <timeout> ] [ -no-proxy ]" << endl; +} + +bool ArgumentsCollector::checkAndSetStringArg(int &pos, QString &arg, const char *opt) const +{ + if (m_arguments.at(pos) == QLatin1String(opt)) { + if (!arg.isEmpty()) { + throw ArgumentErrorException(QLatin1String("option ") + opt + + QLatin1String(" was given twice.")); + } + arg = m_arguments.at(++pos); + if (arg.isEmpty() && QLatin1String(opt) != QLatin1String("-pwd")) + throw ArgumentErrorException(QLatin1String("empty argument not allowed here.")); + return true; + } + return false; +} + +bool ArgumentsCollector::checkAndSetIntArg(int &pos, int &val, + bool &alreadyGiven, const char *opt) const +{ + if (m_arguments.at(pos) == QLatin1String(opt)) { + if (alreadyGiven) { + throw ArgumentErrorException(QLatin1String("option ") + opt + + QLatin1String(" was given twice.")); + } + bool isNumber; + val = m_arguments.at(++pos).toInt(&isNumber); + if (!isNumber) { + throw ArgumentErrorException(QLatin1String("option ") + opt + + QLatin1String(" needs integer argument")); + } + alreadyGiven = true; + return true; + } + return false; +} + +bool ArgumentsCollector::checkForNoProxy(int &pos, + SshConnectionParameters::ProxyType &type, bool &alreadyGiven) const +{ + if (m_arguments.at(pos) == QLatin1String("-no-proxy")) { + if (alreadyGiven) + throw ArgumentErrorException(QLatin1String("proxy setting given twice.")); + type = SshConnectionParameters::NoProxy; + alreadyGiven = true; + return true; + } + return false; +} diff --git a/tests/manual/ssh/tunnel/argumentscollector.h b/tests/manual/ssh/tunnel/argumentscollector.h new file mode 100644 index 0000000000..d7189597f1 --- /dev/null +++ b/tests/manual/ssh/tunnel/argumentscollector.h @@ -0,0 +1,63 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#ifndef ARGUMENTSCOLLECTOR_H +#define ARGUMENTSCOLLECTOR_H + +#include <ssh/sshconnection.h> + +#include <QStringList> + +class ArgumentsCollector +{ +public: + ArgumentsCollector(const QStringList &args); + QSsh::SshConnectionParameters collect(bool &success) const; +private: + struct ArgumentErrorException + { + ArgumentErrorException(const QString &error) : error(error) {} + const QString error; + }; + + void printUsage() const; + bool checkAndSetStringArg(int &pos, QString &arg, const char *opt) const; + bool checkAndSetIntArg(int &pos, int &val, bool &alreadyGiven, + const char *opt) const; + bool checkForNoProxy(int &pos, + QSsh::SshConnectionParameters::ProxyType &type, + bool &alreadyGiven) const; + + const QStringList m_arguments; +}; + +#endif // ARGUMENTSCOLLECTOR_H diff --git a/tests/manual/ssh/tunnel/main.cpp b/tests/manual/ssh/tunnel/main.cpp new file mode 100644 index 0000000000..b25beb46ff --- /dev/null +++ b/tests/manual/ssh/tunnel/main.cpp @@ -0,0 +1,55 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ +#include "../remoteprocess/argumentscollector.h" +#include "tunnel.h" + +#include <ssh/sshconnection.h> + +#include <QCoreApplication> +#include <QObject> +#include <QStringList> + +#include <cstdlib> +#include <iostream> + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + bool parseSuccess; + const QSsh::SshConnectionParameters ¶meters + = ArgumentsCollector(app.arguments()).collect(parseSuccess); + if (!parseSuccess) + return EXIT_FAILURE; + Tunnel tunnel(parameters); + tunnel.run(); + return app.exec(); +} diff --git a/tests/manual/ssh/tunnel/tunnel.cpp b/tests/manual/ssh/tunnel/tunnel.cpp new file mode 100644 index 0000000000..342102a881 --- /dev/null +++ b/tests/manual/ssh/tunnel/tunnel.cpp @@ -0,0 +1,165 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ +#include "tunnel.h" + +#include <ssh/sshconnection.h> +#include <ssh/sshdirecttcpiptunnel.h> + +#include <QCoreApplication> +#include <QTcpServer> +#include <QTcpSocket> +#include <QTimer> + +#include <cstdlib> +#include <iostream> + +const QByteArray ServerDataPrefix("Received the following data: "); +const QByteArray TestData("Urgsblubb?"); + +using namespace QSsh; + +Tunnel::Tunnel(const QSsh::SshConnectionParameters ¶meters, QObject *parent) + : QObject(parent), + m_connection(new SshConnection(parameters, this)), + m_tunnelServer(new QTcpServer(this)), + m_expectingChannelClose(false) +{ + connect(m_connection, SIGNAL(connected()), SLOT(handleConnected())); + connect(m_connection, SIGNAL(error(QSsh::SshError)), SLOT(handleConnectionError())); +} + +Tunnel::~Tunnel() +{ +} + +void Tunnel::run() +{ + std::cout << "Connecting to SSH server..." << std::endl; + m_connection->connectToHost(); +} + +void Tunnel::handleConnectionError() +{ + std::cerr << "SSH connection error: " << qPrintable(m_connection->errorString()) << std::endl; + qApp->exit(EXIT_FAILURE); +} + +void Tunnel::handleConnected() +{ + std::cout << "Opening server side..." << std::endl; + if (!m_tunnelServer->listen(QHostAddress::LocalHost)) { + std::cerr << "Error opening port: " + << m_tunnelServer->errorString().toLocal8Bit().constData() << std::endl; + qApp->exit(EXIT_FAILURE); + return; + } + m_forwardedPort = m_tunnelServer->serverPort(); + connect(m_tunnelServer, SIGNAL(newConnection()), SLOT(handleNewConnection())); + + m_tunnel = m_connection->createTunnel(m_forwardedPort); + connect(m_tunnel.data(), SIGNAL(initialized()), SLOT(handleInitialized())); + connect(m_tunnel.data(), SIGNAL(error(QString)), SLOT(handleTunnelError(QString))); + connect(m_tunnel.data(), SIGNAL(readyRead()), SLOT(handleServerData())); + connect(m_tunnel.data(), SIGNAL(tunnelClosed()), SLOT(handleTunnelClosed())); + + std::cout << "Initializing tunnel..." << std::endl; + m_tunnel->initialize(); +} + +void Tunnel::handleInitialized() +{ + std::cout << "Writing data into the tunnel..." << std::endl; + m_tunnel->write(TestData); + QTimer * const timeoutTimer = new QTimer(this); + connect(timeoutTimer, SIGNAL(timeout()), SLOT(handleTimeout())); + timeoutTimer->start(10000); +} + +void Tunnel::handleServerData() +{ + m_dataReceivedFromServer += m_tunnel->readAll(); + if (m_dataReceivedFromServer == ServerDataPrefix + TestData) { + std::cout << "Data exchange successful. Closing server socket..." << std::endl; + m_expectingChannelClose = true; + m_tunnelSocket->close(); + } +} + +void Tunnel::handleTunnelError(const QString &reason) +{ + std::cerr << "Tunnel error: " << reason.toLocal8Bit().constData() << std::endl; + qApp->exit(EXIT_FAILURE); +} + +void Tunnel::handleTunnelClosed() +{ + if (m_expectingChannelClose) { + std::cout << "Successfully detected channel close." << std::endl; + std::cout << "Test finished successfully." << std::endl; + qApp->quit(); + } else { + std::cerr << "Error: Remote host closed channel." << std::endl; + qApp->exit(EXIT_FAILURE); + } +} + +void Tunnel::handleNewConnection() +{ + m_tunnelSocket = m_tunnelServer->nextPendingConnection(); + m_tunnelServer->close(); + connect(m_tunnelSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(handleSocketError())); + connect(m_tunnelSocket, SIGNAL(readyRead()), SLOT(handleClientData())); + handleClientData(); +} + +void Tunnel::handleSocketError() +{ + std::cerr << "Socket error: " << m_tunnelSocket->errorString().toLocal8Bit().constData() + << std::endl; + qApp->exit(EXIT_FAILURE); +} + +void Tunnel::handleClientData() +{ + m_dataReceivedFromClient += m_tunnelSocket->readAll(); + if (m_dataReceivedFromClient == TestData) { + std::cout << "Client data successfully received by server, now sending data to client..." + << std::endl; + m_tunnelSocket->write(ServerDataPrefix + m_dataReceivedFromClient); + } +} + +void Tunnel::handleTimeout() +{ + std::cerr << "Error: Timeout waiting for test completion." << std::endl; + qApp->exit(EXIT_FAILURE); +} diff --git a/src/plugins/debugger/qtmessagelogwindow.h b/tests/manual/ssh/tunnel/tunnel.h index 1fb38aaf0c..79a3de6823 100644 --- a/src/plugins/debugger/qtmessagelogwindow.h +++ b/tests/manual/ssh/tunnel/tunnel.h @@ -26,56 +26,53 @@ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ +#ifndef TUNNEL_H +#define TUNNEL_H -#ifndef QTMESSAGELOGWINDOW_H -#define QTMESSAGELOGWINDOW_H - -#include <QWidget> +#include <QObject> +#include <QSharedPointer> QT_BEGIN_NAMESPACE -class QAbstractItemModel; -class QAction; +class QTcpServer; +class QTcpSocket; QT_END_NAMESPACE -namespace Utils { -class StatusLabel; -class SavedAction; +namespace QSsh { +class SshConnection; +class SshConnectionParameters; +class SshDirectTcpIpTunnel; } -namespace Debugger { -namespace Internal { - -class QtMessageLogView; -class QtMessageLogItemDelegate; -class QtMessageLogProxyModel; -class QtMessageLogWindow : public QWidget +class Tunnel : public QObject { Q_OBJECT - public: - QtMessageLogWindow(QWidget *parent = 0); - ~QtMessageLogWindow(); + Tunnel(const QSsh::SshConnectionParameters ¶meters, QObject *parent = 0); + ~Tunnel(); - void setModel(QAbstractItemModel *model); - void readSettings(); - void showStatus(const QString &context, int timeout); + void run(); -public slots: - void writeSettings() const; +private slots: + void handleConnected(); + void handleConnectionError(); + void handleServerData(); + void handleInitialized(); + void handleTunnelError(const QString &reason); + void handleTunnelClosed(); + void handleNewConnection(); + void handleSocketError(); + void handleClientData(); + void handleTimeout(); private: - Utils::StatusLabel *m_statusLabel; - Utils::SavedAction *m_showLogAction; - Utils::SavedAction *m_showWarningAction; - Utils::SavedAction *m_showErrorAction; - QAction *m_clearAction; - QtMessageLogView *m_treeView; - QtMessageLogItemDelegate *m_itemDelegate; - QtMessageLogProxyModel *m_proxyModel; + QSsh::SshConnection * const m_connection; + QSharedPointer<QSsh::SshDirectTcpIpTunnel> m_tunnel; + QTcpServer * const m_tunnelServer; + QTcpSocket *m_tunnelSocket; + quint16 m_forwardedPort; + QByteArray m_dataReceivedFromServer; + QByteArray m_dataReceivedFromClient; + bool m_expectingChannelClose; }; -} // namespace Internal -} // namespace Debugger - -#endif // QTMESSAGELOGWINDOW_H - +#endif // TUNNEL_H diff --git a/tests/manual/ssh/tunnel/tunnel.pro b/tests/manual/ssh/tunnel/tunnel.pro new file mode 100644 index 0000000000..f2f960b98a --- /dev/null +++ b/tests/manual/ssh/tunnel/tunnel.pro @@ -0,0 +1,5 @@ +include(../ssh.pri) + +TARGET=tunnel +SOURCES=main.cpp tunnel.cpp argumentscollector.cpp +HEADERS=tunnel.h argumentscollector.h diff --git a/tests/system/suite_CSUP/tst_CSUP02/test.py b/tests/system/suite_CSUP/tst_CSUP02/test.py index 9e5a5b9c7a..ec8313a9fe 100644 --- a/tests/system/suite_CSUP/tst_CSUP02/test.py +++ b/tests/system/suite_CSUP/tst_CSUP02/test.py @@ -26,7 +26,6 @@ def main(): else: type(editorWidget, "<Ctrl+Space>") type(waitForObject(":popupFrame_Proposal_QListView"), "<Down>") - type(waitForObject(":popupFrame_Proposal_QListView"), "<Down>") listView = waitForObject(":popupFrame_Proposal_QListView") test.compare("class derived from QObject", str(listView.model().data(listView.currentIndex())), "Verifying selecting the correct entry.") diff --git a/tests/system/suite_debugger/tst_simple_debug/test.py b/tests/system/suite_debugger/tst_simple_debug/test.py index 5d0a12490e..5a1aab9c0b 100644 --- a/tests/system/suite_debugger/tst_simple_debug/test.py +++ b/tests/system/suite_debugger/tst_simple_debug/test.py @@ -31,7 +31,7 @@ def main(): test.log("Setting breakpoints") result = setBreakpointsForCurrentProject(filesAndLines) if result: - expectedBreakpointsOrder = [{"main.cpp":9}, {"main.qml":13}] + expectedBreakpointsOrder = [{"main.cpp":10}, {"main.qml":13}] # Only use 4.7.4 to work around QTBUG-25187 availableConfigs = iterateBuildConfigs(1, "Debug") if not availableConfigs: diff --git a/tests/tools/cplusplus-ast2png/cplusplus-ast2png.cpp b/tests/tools/cplusplus-ast2png/cplusplus-ast2png.cpp index 8af2b289e5..10a4e15ec7 100644 --- a/tests/tools/cplusplus-ast2png/cplusplus-ast2png.cpp +++ b/tests/tools/cplusplus-ast2png/cplusplus-ast2png.cpp @@ -203,9 +203,9 @@ public: SymbolDump(TranslationUnit *unit) : translationUnit(unit) { - o.setShowArgumentNames(true); - o.setShowFunctionSignatures(true); - o.setShowReturnTypes(true); + o.showArgumentNames = true; + o.showFunctionSignatures = true; + o.showReturnTypes = true; } void operator()(Symbol *s) { diff --git a/tests/tools/cplusplus-ast2png/dumpers.inc b/tests/tools/cplusplus-ast2png/dumpers.inc index 0d1d8e4620..a08981a8f7 100644 --- a/tests/tools/cplusplus-ast2png/dumpers.inc +++ b/tests/tools/cplusplus-ast2png/dumpers.inc @@ -359,6 +359,8 @@ virtual bool visit(ClassSpecifierAST *ast) for (SpecifierListAST *iter = ast->attribute_list; iter; iter = iter->next) nonterminal(iter->value); nonterminal(ast->name); + if (ast->final_token) + terminal(ast->final_token, ast); if (ast->colon_token) terminal(ast->colon_token, ast); for (BaseSpecifierListAST *iter = ast->base_clause_list; iter; iter = iter->next) @@ -477,6 +479,8 @@ virtual bool visit(FunctionDeclaratorAST *ast) terminal(ast->rparen_token, ast); for (SpecifierListAST *iter = ast->cv_qualifier_list; iter; iter = iter->next) nonterminal(iter->value); + if (ast->ref_qualifier_token) + terminal(ast->ref_qualifier_token, ast); nonterminal(ast->exception_specification); nonterminal(ast->trailing_return_type); nonterminal(ast->as_cpp_initializer); @@ -544,7 +548,13 @@ virtual bool visit(EnumSpecifierAST *ast) { if (ast->enum_token) terminal(ast->enum_token, ast); + if (ast->key_token) + terminal(ast->key_token, ast); nonterminal(ast->name); + if (ast->colon_token) + terminal(ast->colon_token, ast); + for (SpecifierListAST *iter = ast->type_specifier_list; iter; iter = iter->next) + nonterminal(iter->value); if (ast->lbrace_token) terminal(ast->lbrace_token, ast); for (EnumeratorListAST *iter = ast->enumerator_list; iter; iter = iter->next) @@ -649,6 +659,24 @@ virtual bool visit(ForeachStatementAST *ast) return false; } +virtual bool visit(RangeBasedForStatementAST *ast) +{ + if (ast->for_token) + terminal(ast->for_token, ast); + if (ast->lparen_token) + terminal(ast->lparen_token, ast); + for (SpecifierListAST *iter = ast->type_specifier_list; iter; iter = iter->next) + nonterminal(iter->value); + nonterminal(ast->declarator); + if (ast->colon_token) + terminal(ast->colon_token, ast); + nonterminal(ast->expression); + if (ast->rparen_token) + terminal(ast->rparen_token, ast); + nonterminal(ast->statement); + return false; +} + virtual bool visit(ForStatementAST *ast) { if (ast->for_token) @@ -727,12 +755,7 @@ virtual bool visit(LinkageSpecificationAST *ast) virtual bool visit(MemInitializerAST *ast) { nonterminal(ast->name); - if (ast->lparen_token) - terminal(ast->lparen_token, ast); - for (ExpressionListAST *iter = ast->expression_list; iter; iter = iter->next) - nonterminal(iter->value); - if (ast->rparen_token) - terminal(ast->rparen_token, ast); + nonterminal(ast->expression); return false; } @@ -831,7 +854,21 @@ virtual bool visit(NamespaceAliasDefinitionAST *ast) return false; } -virtual bool visit(NewPlacementAST *ast) +virtual bool visit(AliasDeclarationAST *ast) +{ + if (ast->using_token) + terminal(ast->using_token, ast); + if (ast->identifier_token) + terminal(ast->identifier_token, ast); + if (ast->equal_token) + terminal(ast->equal_token, ast); + nonterminal(ast->typeId); + if (ast->semicolon_token) + terminal(ast->semicolon_token, ast); + return false; +} + +virtual bool visit(ExpressionListParenAST *ast) { if (ast->lparen_token) terminal(ast->lparen_token, ast); @@ -869,16 +906,6 @@ virtual bool visit(NewExpressionAST *ast) return false; } -virtual bool visit(NewInitializerAST *ast) -{ - if (ast->lparen_token) - terminal(ast->lparen_token, ast); - nonterminal(ast->expression); - if (ast->rparen_token) - terminal(ast->rparen_token, ast); - return false; -} - virtual bool visit(NewTypeIdAST *ast) { for (SpecifierListAST *iter = ast->type_specifier_list; iter; iter = iter->next) @@ -980,12 +1007,7 @@ virtual bool visit(TypenameCallExpressionAST *ast) if (ast->typename_token) terminal(ast->typename_token, ast); nonterminal(ast->name); - if (ast->lparen_token) - terminal(ast->lparen_token, ast); - for (ExpressionListAST *iter = ast->expression_list; iter; iter = iter->next) - nonterminal(iter->value); - if (ast->rparen_token) - terminal(ast->rparen_token, ast); + nonterminal(ast->expression); return false; } @@ -993,12 +1015,7 @@ virtual bool visit(TypeConstructorCallAST *ast) { for (SpecifierListAST *iter = ast->type_specifier_list; iter; iter = iter->next) nonterminal(iter->value); - if (ast->lparen_token) - terminal(ast->lparen_token, ast); - for (ExpressionListAST *iter = ast->expression_list; iter; iter = iter->next) - nonterminal(iter->value); - if (ast->rparen_token) - terminal(ast->rparen_token, ast); + nonterminal(ast->expression); return false; } @@ -1012,6 +1029,8 @@ virtual bool visit(PointerToMemberAST *ast) terminal(ast->star_token, ast); for (SpecifierListAST *iter = ast->cv_qualifier_list; iter; iter = iter->next) nonterminal(iter->value); + if (ast->ref_qualifier_token) + terminal(ast->ref_qualifier_token, ast); return false; } @@ -1084,6 +1103,18 @@ virtual bool visit(SizeofExpressionAST *ast) return false; } +virtual bool visit(AlignofExpressionAST *ast) +{ + if (ast->alignof_token) + terminal(ast->alignof_token, ast); + if (ast->lparen_token) + terminal(ast->lparen_token, ast); + nonterminal(ast->typeId); + if (ast->rparen_token) + terminal(ast->rparen_token, ast); + return false; +} + virtual bool visit(PointerLiteralAST *ast) { if (ast->literal_token) @@ -1614,6 +1645,9 @@ virtual bool visit(LambdaCaptureAST *ast) virtual bool visit(CaptureAST *ast) { + if (ast->amper_token) + terminal(ast->amper_token, ast); + nonterminal(ast->identifier); return false; } |