diff --git a/dist/changes-3.2.0 b/dist/changes-3.2.0 index 5840173233e..3a67b9aab71 100644 --- a/dist/changes-3.2.0 +++ b/dist/changes-3.2.0 @@ -15,17 +15,20 @@ General * Enabled resizing of the locator field * Improved look and feel on HiDPI by adding more hi-resolution icons * Made keyboard and mouse activation of navigation panes and other trees more consistent + * Added display of current variable values in variable chooser dialog + * Removed unhelpful Generic Highlighter loading progress bar Editing + * Fixed support for mixed languages in the generic highlighter Managing and Building Projects QMake Projects - * Added context menu item for copying resource path from entries in QRC files in project tree - (QTCREATORBUG-11776) + * Added context menu item for copying resource path from entries in QRC + files in project tree (QTCREATORBUG-11776) * Added deployment support to plain C and C++ application wizards - * Removed warning about build directory below source directory for kits with Qt 5.2 and later - where this is supported (QTCREATORBUG-10024) + * Removed warning about build directory below source directory for kits + with Qt 5.2 and later where this is supported (QTCREATORBUG-10024) * Fixed that adding files to .pri file was missing $$PWD Qbs Projects @@ -37,12 +40,49 @@ Qbs Projects Generic Projects Debugging - * Added option to disable automatic centering on currently debugged line in editor - * GDB and LLDB - * Added pretty printers for AVX512 registers + * Changed default of "Load system GDB pretty printer" option back to "off" + * Added option to disable automatic centering on currently debugged + line in editor + * Made environment variables accessible in startup command settings + using a %{Env:SOME_NAME} syntax + * Changed single click on column view headers to cycle through + a "small widget" and a "width according to contents" + * Removed the "Always adjust to content size options" and + made this the default behavior + * Added pretty printers for AVX512 registers + * Fixed display of fixed-size wchar_t arrays + * Added personaltypes.py as default location for user created dumpers + * Added file setting to point to user created file of dumpers + (QTCREATORBUG-12492) + * Added button to restart current debugging session + without quitting the debugger process + * Made our dumpers also accessible from command line GDB + * Made LLDB engine honor the max stack depth setting + (QTCREATORBUG-12416) + * Added dumpers for QStringData, QHashedString and QQmlRefCount + * Fixed CDB engine to reset Locals and Expressions when + switching frames + * Made LLDB engine recover more gracefully from unexpected + situations + * Improved handling of the tabbed extra views for displayed + items + * Fixed regression in process snapshot creation + * Fixed crash in CDB extension related to verbose logs + * Introduced option to limit retrieval of string-like values + * Introduced [a..b] and [a.(s).b] syntax for more flexibility + in "ranged" expressions in Locals and Expression view + * Added several convienience functions to Python dumper interface + * Fixed CDB detection for Windows SDK 8.1 + * Added raw opcode bytes to Disassembler view + * Changed Disassembler view to order lines by increasing address + * Made more dumpers work in release builds + * Fixed debugging applications that are run in a terminal on Linux (QTCREATORBUG-3509) QML Profiler +Analyzer + * Added support for Run in Terminal (QTCREATORBUG-7311) + C++ Support * Fixed finding usages of members of typedef'ed anonymous structs (QTCREATORBUG-11859, QTCREATORBUG-11860) @@ -57,12 +97,23 @@ Qt Quick Designer Diff Viewer Version Control Systems + * Git + * Fixed replies to prompts (QTCREATORBUG-12335) + * Fixed that original author was not preserved during Cherry-Pick + * Reintroduced the expanded branch list in Show (QTCREATORBUG-11293) + * Fixed that switching to the commit editor was unresponsive (QTCREATORBUG-12449) + * Fixed showing commits by clicking their hashes in the interactive rebase editor + * Improved display in the Gerrit dialog to visualize dependencies + * Added support for choosing reviewer in Push to Gerrit dialog + over HTTP FakeVim * Added support for unicode input with 'C-v' in insert mode * Fixed issues with long command output (QTCREATORBUG-11598) * Fixed 'gv' after yanking text in visual mode (QTCREATORBUG-12112) * Fixed 'v', 'V' and 'C-v' while in visual mode (QTCREATORBUG-12113) + * Improved sharing of navigation data between editors of the + same document Platform Specific @@ -75,9 +126,18 @@ OS X Android * Fixed that UI was unresponsive while creating AVD (QTCREATORBUG-10601) + Remote Linux * Added custom remote executable run configuration type (QTCREATORBUG-12168) * Fixed issue with environment variables that contain spaces +BareMetal: + * Added openocd pipelining support + * Added variable support for device specific GDB commands + +Valgrind: + * Fixed passing of multiple arguments to application + + Credits for these changes go to: diff --git a/doc/api/coding-style.qdoc b/doc/api/coding-style.qdoc index 8c97c672f9f..fedd9a06808 100644 --- a/doc/api/coding-style.qdoc +++ b/doc/api/coding-style.qdoc @@ -692,6 +692,139 @@ \note As an exception, imported third party code as well as code interfacing the native APIs (src/support/os_*) can use NULL. + \section2 C++11 Features + + Code should compile with Microsoft Visual Studio 2010, g++ 4.5, and Clang 3.1. + + \section3 Lambdas + + You can use lambdas with the following restrictions: + + \list + \li You have to explicitly specify the return type, if the lambda contains more than a + single expression. Otherwise it does not compile with VS2010. + \code + []() -> QString { + Foo *foo = activeFoo(); + return foo ? foo->displayName() : QString(); + }); + + -NOT- + + []() { + Foo *foo = activeFoo(); + return foo ? foo->displayName() : QString(); + }); + \endcode + + \li If you use static functions from the class that the lambda is located in, you have to + explicitly capture \c this. Otherwise it does not compile with g++ 4.7 and earlier. + \code + void Foo::something() + { + ... + [this]() { Foo::someStaticFunction(); } + ... + } + + -NOT- + + void Foo::something() + { + ... + []() { Foo::someStaticFunction(); } + ... + } + \endcode + \endlist + + Format the lambda according to the following rules: + + \list + \li Always write parentheses for the parameter list, even if the function does not take + parameters. + \code + []() { doSomething(); } + + -NOT + + [] { doSomething(); } + \endcode + + \li Place the capture-list, parameter list, return type, and opening brace on the first line, + the body indented on the following lines, and the closing brace on a new line. + \code + []() -> bool { + something(); + return isSomethingElse(); + } + + -NOT- + + []() -> bool { something(); + somethingElse(); } + \endcode + + \li Place a closing parenthesis and semicolon of an enclosing function call on the same line + as the closing brace of the lambda. + \code + foo([]() { + something(); + }); + \endcode + + \li If you are using a lambda in an 'if' statement, start the lambda on a new line, to + avoid confusion between the opening brace for the lambda and the opening brace for the + 'if' statement. + \code + if (anyOf(fooList, + [](Foo foo) { + return foo.isGreat(); + }) { + return; + } + + -NOT- + + if (anyOf(fooList, [](Foo foo) { + return foo.isGreat(); + }) { + return; + } + \endcode + + \li Optionally, place the lambda completely on one line if it fits. + \code + foo([]() { return true; }); + + if (foo([]() { return true; })) { + ... + } + \endcode + + \endlist + + \section3 \c auto Keyword + + Optionally, you can use the \c auto keyword in the following cases. If in doubt, + for example if using \c auto could make the code less readable, do not use \c auto. + Keep in mind that code is read much more often than written. + + \list + \li When it avoids repetition of a type in the same statement. + \code + auto something = new MyCustomType; + auto keyEvent = static_cast(event); + auto myList = QStringList() << QLatin1String(“FooThing”) << QLatin1String(“BarThing”); + \endcode + + \li When assigning iterator types. + \code + auto it = myList.const_iterator(); + \endcode + + \endlist + \section2 Using QObject \list diff --git a/doc/api/plugin-specifications.qdoc b/doc/api/plugin-specifications.qdoc index 0eefadbc7c5..0183a8c02d4 100644 --- a/doc/api/plugin-specifications.qdoc +++ b/doc/api/plugin-specifications.qdoc @@ -31,8 +31,8 @@ \section2 Main Tag The root tag is \c plugin. It has the mandatory attributes \c name - and \c version, and the optional attributes \c compatVersion, \c experimental - and \c disabledByDefault. + and \c version, and the optional attributes \c compatVersion, \c experimental, + \c disabledByDefault and \c required. \table \header \li Tag @@ -79,6 +79,12 @@ If set, the respective plugin is not loaded by default but must be explicitly enabled by the user. This should be done for plugins which are not expected to be used by so many people as to justify the additional resource consumption. + + \row + \li required + \li Optional. Can be \c true or \c false, defaults to \c false. + Is used as a hint for the \gui{About Plugins...} dialog, that the user may not + manually disable this plugin. Only used for the Core plugin. \endtable \section2 Plugin-describing Tags diff --git a/doc/config/macros.qdocconf b/doc/config/macros.qdocconf index 00dd6a59533..38971f6e67b 100644 --- a/doc/config/macros.qdocconf +++ b/doc/config/macros.qdocconf @@ -17,6 +17,7 @@ macro.oslash.HTML = "ø" macro.ouml.HTML = "ö" macro.QA = "Qt Assistant" macro.QC = "Qt Creator" +macro.QCE = "Qt Creator Enterprise" macro.QD = "Qt Designer" macro.QL = "Qt Linguist" macro.QMLD = "Qt Quick Designer" diff --git a/doc/config/qtcreator-project.qdocconf b/doc/config/qtcreator-project.qdocconf index 424258f2f10..150768f062c 100644 --- a/doc/config/qtcreator-project.qdocconf +++ b/doc/config/qtcreator-project.qdocconf @@ -1,5 +1,6 @@ project = "QtCreator" description = "Qt Creator Manual" +url = http://qt-project.org/doc/qtcreator headerdirs = sourcedirs = $SRCDIR/src diff --git a/doc/src/analyze/qtquick-profiler.qdoc b/doc/src/analyze/qtquick-profiler.qdoc index f3c5a6b09fc..d9ccd2023e1 100644 --- a/doc/src/analyze/qtquick-profiler.qdoc +++ b/doc/src/analyze/qtquick-profiler.qdoc @@ -94,39 +94,10 @@ \section1 Analyzing Collected Data - The \gui Timeline view displays graphical representations of: + The \gui Timeline view displays graphical representations of QML and + JavaScript execution and a condensed view of all recorded events. - \list - \if defined(enterprise) - \li Pixmap loading times and cache sizes - - \li Scene graph events - \endif - - \li Painting operations - - \li Compiling the QML sources - - \li Creating items using QML types - - \li Binding evaluations - - \li Signal handling - - \li Executing JavaScript behind bindings and signal handlers - - \li Summary of the recorded period - - \endlist - - \if defined(enterprise) - Information about the pixmap cache and scene graph events are only available - from Qt 5.1 onwards. - - \image qtcreator-qml-performance-monitor-enterprise.png "QML Profiler" - \else \image qtcreator-qml-performance-monitor.png "QML Profiler" - \endif Each row in the timeline (6) describes a type of QML events that were recorded. Move the cursor on an event on a row to see how long it takes and @@ -162,28 +133,132 @@ To remove an event range, close the \gui Selection dialog. - \section2 Evaluating Bindings + \section2 Understanding the Data - On the \gui Binding row, you can see when a binding is evaluated and how - long the evaluation takes. Move the mouse over the binding for details - about the binding: location in the source code, duration, and source - code. + Generally, events in the timeline view indicate how long QML or JavaScript + execution took. Move the mouse over them to see details. For most events, + they include location in source code, duration and some relevant parts of + the source code itself. - Click the binding to move the cursor in the code editor to the part of the - code where the binding is called. + You can click on an event to move the cursor in the code editor to the part + of the code the event is associated with. - \section2 Evaluating JavaScript Events + The following types of events are displayed in the timeline view on one or + several rows. The availability of event types depends on the version of Qt + the application was compiled with, the version of Qt Quick it is using, and + whether \QC or \QCE is used to profile it. - On the \gui JavaScript row, you can see the time spent executing the actual - JavaScript behind bindings and signal handlers. It lists all the JavaScript - functions you may be using to evaluate bindings or handle signals. + \table - This information is displayed for applications that use the V4 engine and - are built with Qt 5.3, or later. + \header + \li Event Type + \li Description + \li Minimum Qt Version + \li Qt Quick Version + \li Enterprise Feature - For applications that use the V8 engine and are built with Qt 5.0 or 5.1, - you can view information about JavaScript events in the \gui JavaScript - view. + \row + \li \gui {Pixmap Cache} + \li Displays the general amount of pixmap data cached, in pixels. In + addition, displays a separate event for each picture being loaded, + with specifics about its file name and size. + \li Qt 5.1 + \li Qt Quick 2 + \li Yes + + \row + \li \gui {Scene Graph} + \li Displays the time when scene graph frames are rendered and some + additional timing information for the various stages executed to do + so. + \li Qt 5.1 + \li Qt Quick 2 + \li Yes + \row + \li \gui {Memory Usage} + \li Displays block allocations of the JavaScript memory manager. + Generally, the memory manager will reserve larger blocks of memory + in one piece and later hand them out to the application in smaller + bits. If the application requests single blocks of memory + surpassing a certain size, the memory manager will allocate those + separately. Those two modes of operation are shown as events of + different colors. + + The second row displays the actual usage of the allocated memory. + This is the amount of JavaScript heap the application has actually + requested. + \li Qt 5.4 + \li Qt Quick 2 + \li Yes + + \row + \li \gui Painting + \li Displays the time spent painting the scene for each frame. + \li Qt 4.7.4 + \li Qt Quick 1 + \li No + + \row + \li \gui Animations + \li Displays the amount of animations that are active and the frame + rate that they are running at. + + Information about render thread animations is displayed for + applications that are built with Qt 5.3 or later. Render thread + animations are shown in a separate row then. + \li Qt 5.0 (Qt 5.3) + \li Qt Quick 2 + \li No + + \row + \li \gui Compiling + \li Displays the time spent compiling the QML files. + \li Qt 4.7.4 + \li Qt Quick 1 or Qt Quick 2 + \li No + + \row + \li \gui Creating + \li Displays the time spent creating the elements in the scene. In Qt + Quick 2, creation of elements takes place in two stages. The first + stage is for the creation of the data structures, including child + elements. The second stage represents the completion callbacks. Not + all elements trigger completion callbacks, though. The stages are + shown as separate events in the timeline. + + For Qt Quick 2 applications compiled with versions of Qt before + 5.2.1 only the creation of top-level elements is shown, as single + events. + \li Qt 4.7.4 (Qt 5.2.1) + \li Qt Quick 1 or Qt Quick 2 + \li No + + \row + \li \gui Binding + \li Displays the time when a binding is evaluated and how long the + evaluation takes. + \li Qt 4.7.4 + \li Qt Quick 1 or Qt Quick 2 + \li No + + \row + \li \gui {Handling Signal} + \li Displays the time when a signal is handled and how long the + handling takes. + \li Qt 4.7.4 + \li Qt Quick 1 or Qt Quick 2 + \li No + + \row + \li \gui JavaScript + \li Displays the time spent executing the actual JavaScript behind + bindings and signal handlers. It lists all the JavaScript functions + you may be using to evaluate bindings or handle signals. + \li Qt 5.3 + \li Qt Quick 2 + \li No + + \endtable \section1 Viewing Events @@ -221,16 +296,21 @@ To copy the contents of one view or row to the clipboard, select \gui {Copy Table} or \gui {Copy Row} in the context menu. + JavaScript events are shown in the \gui Events view only for applications + that use Qt Quick 2 and are compiled with Qt 5.3 or later. For applications + that use Qt Quick 2 and are built with Qt 5.0 or 5.1, you can view + information about JavaScript events in the separate \gui JavaScript view. + \section2 Viewing More Data The QML JavaScript engine optimizes trivial bindings. The QML Profiler - does not receive information about optimized bindings, and - therefore, it displays the text \gui {} and the message + may not receive all information about optimized bindings, and therefore, + it may display the text \gui {} and the message \gui {Source code not available} in the \gui Callers and \gui {Callees} panes. - To inspect the optimized bindings, turn off the QML optimizer by setting the - environment variable QML_DISABLE_OPTIMIZER to 1. To set the environment + To inspect the optimized bindings, turn off the QML optimizer by setting + the environment variable QML_DISABLE_OPTIMIZER to 1. To set the environment variable for the current project in the project settings: \list 1 diff --git a/doc/src/howto/creator-vcs.qdoc b/doc/src/howto/creator-vcs.qdoc index 4574d53f7bd..5b35e2f0643 100644 --- a/doc/src/howto/creator-vcs.qdoc +++ b/doc/src/howto/creator-vcs.qdoc @@ -39,11 +39,11 @@ \row \li Bazaar \li \l{http://bazaar.canonical.com/} - \li \QC 2.2 and later + \li \row \li ClearCase \li \l{http://www-01.ibm.com/software/awdtools/clearcase/} - \li \QC 2.6 and later + \li \row \li CVS \li \l{http://www.cvshome.org} @@ -52,10 +52,12 @@ \li Git \li \l{http://git-scm.com/} \li Git version 1.7.2, or later + + Gerrit version 2.6, or later \row \li Mercurial \li \l{http://mercurial.selenic.com/} - \li \QC 2.0 and later + \li \row \li Perforce \li \l{http://www.perforce.com} @@ -399,8 +401,7 @@ for Windows, Linux and Mac. You can use the \l{http://code.google.com/p/gerrit/}{Gerrit} code review - tool for projects that use Git. You can apply and check out changes from - Gerrit in \QC 2.6 and later. + tool for projects that use Git. \section3 Working with the Current File diff --git a/doc/src/qtquick/qtquick-screens.qdoc b/doc/src/qtquick/qtquick-screens.qdoc index bdf655f7f87..283fcc9f4ff 100644 --- a/doc/src/qtquick/qtquick-screens.qdoc +++ b/doc/src/qtquick/qtquick-screens.qdoc @@ -107,7 +107,7 @@ \l{Positioning with Bindings} {Property binding} is a declarative way of specifying the value of a property. - Binding allows a property value to be expressed as an JavaScript expression + Binding allows a property value to be expressed as a JavaScript expression that defines the value relative to other property values or data accessible in the application. The property value is automatically kept up to date if the other properties or data values change. @@ -126,7 +126,6 @@ \QMLD cannot show bindings and using them might have a negative impact on performance, so consider setting anchors and margins for items, instead. - For example, instead of setting \c {parent.width} for an item, you could anchor the item to its sibling items on the left and the right. diff --git a/qtcreator.pri b/qtcreator.pri index f40eb12f2a1..1c893c11cea 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -1,8 +1,8 @@ !isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included") QTCREATOR_PRI_INCLUDED = 1 -QTCREATOR_VERSION = 3.1.81 -QTCREATOR_COMPAT_VERSION = 3.1.81 +QTCREATOR_VERSION = 3.1.82 +QTCREATOR_COMPAT_VERSION = 3.1.82 BINARY_ARTIFACTS_BRANCH = master # enable c++11 diff --git a/qtcreator.qbs b/qtcreator.qbs index 7cd9ca116b9..512c5671540 100644 --- a/qtcreator.qbs +++ b/qtcreator.qbs @@ -4,11 +4,11 @@ Project { property bool withAutotests: qbs.buildVariant === "debug" property string ide_version_major: '3' property string ide_version_minor: '1' - property string ide_version_release: '81' + property string ide_version_release: '82' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release property string ide_compat_version_major: '3' property string ide_compat_version_minor: '1' - property string ide_compat_version_release: '81' + property string ide_compat_version_release: '82' property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release property path ide_source_tree: path property string ide_app_path: qbs.targetOS.contains("osx") ? "" : "bin" diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp index 848fac14029..b3b96890085 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -1091,7 +1091,7 @@ static QObject *createDummyWindow(QQmlContext *context, const QUrl &sourceUrl) QQmlComponent component(context->engine()); QByteArray dummyWindow; dummyWindow.append("import QtQuick 2.0\n"); - dummyWindow.append("Item {\n"); + dummyWindow.append("Rectangle {\n"); dummyWindow.append("property string title\n"); dummyWindow.append("}\n"); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.cpp index ccfe49f56bf..c94c40b050a 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlpropertychangesnodeinstance.cpp @@ -71,8 +71,10 @@ void QmlPropertyChangesNodeInstance::setPropertyVariant(const PropertyName &name changesObject()->changeValue(name, value); QObject *targetObject = changesObject()->object(); if (targetObject && nodeInstanceServer()->activeStateInstance().isWrappingThisObject(changesObject()->state())) { - ServerNodeInstance targetInstance = nodeInstanceServer()->instanceForObject(targetObject); - targetInstance.setPropertyVariant(name, value); + if (nodeInstanceServer()->hasInstanceForObject(targetObject)) { + ServerNodeInstance targetInstance = nodeInstanceServer()->instanceForObject(targetObject); + targetInstance.setPropertyVariant(name, value); + } } } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp index 687149d4a7f..fc0c0d575c8 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp @@ -64,12 +64,13 @@ QmlStateNodeInstance::Pointer void QmlStateNodeInstance::activateState() { - if (stateGroup()) { - if (!isStateActive()) { - nodeInstanceServer()->setStateInstance(nodeInstanceServer()->instanceForObject(object())); - stateGroup()->setState(property("name").toString()); - } + if (stateGroup() + && !isStateActive() + && nodeInstanceServer()->hasInstanceForObject(object())) { + nodeInstanceServer()->setStateInstance(nodeInstanceServer()->instanceForObject(object())); + stateGroup()->setState(property("name").toString()); } + } void QmlStateNodeInstance::deactivateState() diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index a169305ce92..363c41e1156 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -199,9 +199,11 @@ void Qt5InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands() void Qt5InformationNodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command) { foreach (const ReparentContainer &container, command.reparentInstances()) { - ServerNodeInstance instance = instanceForId(container.instanceId()); - if (instance.isValid()) { - m_parentChangedSet.insert(instance); + if (hasInstanceForId(container.instanceId())) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isValid()) { + m_parentChangedSet.insert(instance); + } } } @@ -222,9 +224,11 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com QList instanceList; foreach (const InstanceContainer &container, command.instances()) { - ServerNodeInstance instance = instanceForId(container.instanceId()); - if (instance.isValid()) { - instanceList.append(instance); + if (hasInstanceForId(container.instanceId())) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isValid()) { + instanceList.append(instance); + } } } @@ -269,9 +273,11 @@ void Qt5InformationNodeInstanceServer::completeComponent(const CompleteComponent QList instanceList; foreach (qint32 instanceId, command.instances()) { - ServerNodeInstance instance = instanceForId(instanceId); - if (instance.isValid()) { - instanceList.append(instance); + if (hasInstanceForId(instanceId)) { + ServerNodeInstance instance = instanceForId(instanceId); + if (instance.isValid()) { + instanceList.append(instance); + } } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp index 003cee79958..28f87fde820 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp @@ -42,6 +42,8 @@ namespace QmlDesigner { Qt5PreviewNodeInstanceServer::Qt5PreviewNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : Qt5NodeInstanceServer(nodeInstanceClient) { + setSlowRenderTimerInterval(100000000); + setRenderTimerInterval(100); } void Qt5PreviewNodeInstanceServer::createScene(const CreateSceneCommand &command) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp index 558092e2777..91a2c4f25f6 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp @@ -132,9 +132,11 @@ void Qt5RenderNodeInstanceServer::createScene(const CreateSceneCommand &command) QList instanceList; foreach (const InstanceContainer &container, command.instances()) { - ServerNodeInstance instance = instanceForId(container.instanceId()); - if (instance.isValid()) { - instanceList.append(instance); + if (hasInstanceForId(container.instanceId())) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isValid()) { + instanceList.append(instance); + } } } @@ -154,10 +156,12 @@ void Qt5RenderNodeInstanceServer::completeComponent(const CompleteComponentComma QList instanceList; foreach (qint32 instanceId, command.instances()) { - ServerNodeInstance instance = instanceForId(instanceId); - if (instance.isValid()) { - instanceList.append(instance); - m_dirtyInstanceSet.insert(instance); + if (hasInstanceForId(instanceId)) { + ServerNodeInstance instance = instanceForId(instanceId); + if (instance.isValid()) { + instanceList.append(instance); + m_dirtyInstanceSet.insert(instance); + } } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp index 0fbf8c87a3f..bea6cdbde36 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp @@ -190,9 +190,11 @@ void Qt5TestNodeInstanceServer::removeProperties(const RemovePropertiesCommand & void Qt5TestNodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command) { foreach (const ReparentContainer &container, command.reparentInstances()) { - ServerNodeInstance instance = instanceForId(container.instanceId()); - if (instance.isValid()) { - instance.reparent(instanceForId(container.oldParentInstanceId()), container.oldParentProperty(), instanceForId(container.newParentInstanceId()), container.newParentProperty()); + if (hasInstanceForId(container.instanceId())) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isValid()) { + instance.reparent(instanceForId(container.oldParentInstanceId()), container.oldParentProperty(), instanceForId(container.newParentInstanceId()), container.newParentProperty()); + } } } diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/graphicsobjectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/graphicsobjectnodeinstance.cpp index 0f138f68827..4d28d61bec8 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/graphicsobjectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/graphicsobjectnodeinstance.cpp @@ -140,16 +140,18 @@ QTransform GraphicsObjectNodeInstance::transform() const if (!nodeInstanceServer()->hasInstanceForObject(object())) return sceneTransform(); - ServerNodeInstance nodeInstanceParent = nodeInstanceServer()->instanceForObject(object()).parent(); + if (nodeInstanceServer()->hasInstanceForObject(object())) { + ServerNodeInstance nodeInstanceParent = nodeInstanceServer()->instanceForObject(object()).parent(); - if (!nodeInstanceParent.isValid()) - return sceneTransform(); + if (!nodeInstanceParent.isValid()) + return sceneTransform(); - QGraphicsObject *graphicsObjectParent = qobject_cast(nodeInstanceParent.internalObject()); - if (graphicsObjectParent) - return graphicsObject()->itemTransform(graphicsObjectParent); - else - return sceneTransform(); + QGraphicsObject *graphicsObjectParent = qobject_cast(nodeInstanceParent.internalObject()); + if (graphicsObjectParent) + return graphicsObject()->itemTransform(graphicsObjectParent); + } + + return sceneTransform(); } QTransform GraphicsObjectNodeInstance::customTransform() const diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlpropertychangesnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlpropertychangesnodeinstance.cpp index 19e5a00264f..9c9d9f47a83 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlpropertychangesnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlpropertychangesnodeinstance.cpp @@ -71,8 +71,10 @@ void QmlPropertyChangesNodeInstance::setPropertyVariant(const PropertyName &name changesObject()->changeValue(name, value); QObject *targetObject = changesObject()->object(); if (targetObject && nodeInstanceServer()->activeStateInstance().isWrappingThisObject(changesObject()->state())) { - ServerNodeInstance targetInstance = nodeInstanceServer()->instanceForObject(targetObject); - targetInstance.setPropertyVariant(name, value); + if (nodeInstanceServer()->hasInstanceForObject(targetObject)) { + ServerNodeInstance targetInstance = nodeInstanceServer()->instanceForObject(targetObject); + targetInstance.setPropertyVariant(name, value); + } } } } diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlstatenodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlstatenodeinstance.cpp index 18c22b89339..7d67ff053f6 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlstatenodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qmlstatenodeinstance.cpp @@ -64,11 +64,11 @@ QmlStateNodeInstance::Pointer void QmlStateNodeInstance::activateState() { - if (stateGroup()) { - if (!isStateActive()) { - nodeInstanceServer()->setStateInstance(nodeInstanceServer()->instanceForObject(object())); - stateGroup()->setState(property("name").toString()); - } + if (stateGroup() + && !isStateActive() + && nodeInstanceServer()->hasInstanceForObject(object())) { + nodeInstanceServer()->setStateInstance(nodeInstanceServer()->instanceForObject(object())); + stateGroup()->setState(property("name").toString()); } } diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.cpp index fb18d638940..b08874ce2aa 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4informationnodeinstanceserver.cpp @@ -198,9 +198,11 @@ void Qt4InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands() void Qt4InformationNodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command) { foreach(const ReparentContainer &container, command.reparentInstances()) { - ServerNodeInstance instance = instanceForId(container.instanceId()); - if (instance.isValid()) { - m_parentChangedSet.insert(instance); + if (hasInstanceForId(container.instanceId())) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isValid()) { + m_parentChangedSet.insert(instance); + } } } @@ -221,9 +223,11 @@ void Qt4InformationNodeInstanceServer::createScene(const CreateSceneCommand &com QList instanceList; foreach(const InstanceContainer &container, command.instances()) { - ServerNodeInstance instance = instanceForId(container.instanceId()); - if (instance.isValid()) { - instanceList.append(instance); + if (hasInstanceForId(container.instanceId())) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isValid()) { + instanceList.append(instance); + } } } @@ -263,9 +267,11 @@ void Qt4InformationNodeInstanceServer::completeComponent(const CompleteComponent QList instanceList; foreach(qint32 instanceId, command.instances()) { - ServerNodeInstance instance = instanceForId(instanceId); - if (instance.isValid()) { - instanceList.append(instance); + if (hasInstanceForId(instanceId)) { + ServerNodeInstance instance = instanceForId(instanceId); + if (instance.isValid()) { + instanceList.append(instance); + } } } diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.cpp index 4755516a235..653ef22c511 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet/instances/qt4rendernodeinstanceserver.cpp @@ -154,9 +154,11 @@ void Qt4RenderNodeInstanceServer::createScene(const CreateSceneCommand &command) QList instanceList; foreach(const InstanceContainer &container, command.instances()) { - ServerNodeInstance instance = instanceForId(container.instanceId()); - if (instance.isValid()) { - instanceList.append(instance); + if (hasInstanceForId(container.instanceId())) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isValid()) { + instanceList.append(instance); + } } } @@ -176,9 +178,11 @@ void Qt4RenderNodeInstanceServer::completeComponent(const CompleteComponentComma QList instanceList; foreach(qint32 instanceId, command.instances()) { - ServerNodeInstance instance = instanceForId(instanceId); - if (instance.isValid()) { - instanceList.append(instance); + if (hasInstanceForId(instanceId)) { + ServerNodeInstance instance = instanceForId(instanceId); + if (instance.isValid()) { + instanceList.append(instance); + } } } diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml index d3afcf07c6b..25e3e6f390b 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml @@ -61,9 +61,11 @@ Rectangle { anchors.leftMargin: styleConstants.cellHorizontalMargin anchors.right: parent.right anchors.rightMargin: styleConstants.cellHorizontalMargin + anchors.bottom: parent.bottom + anchors.bottomMargin: styleConstants.cellHorizontalMargin - verticalAlignment: "AlignVCenter" - horizontalAlignment: "AlignHCenter" + verticalAlignment: Qt.AlignVCenter + horizontalAlignment: Qt.AlignHCenter text: itemName // to be set by model color: "#FFFFFF" renderType: Text.NativeRendering diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml index b0b8c97ee8e..0b5761dfe06 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml @@ -72,11 +72,11 @@ ScrollView { property color lighterBackgroundColor: "#5f5f5f" property int textWidth: 55 - property int textHeight: 30 + property int textHeight: 26 property int cellHorizontalMargin: 5 property int cellVerticalSpacing: 3 - property int cellVerticalMargin: 3 + property int cellVerticalMargin: 7 // the following depend on the actual shape of the item delegate property int cellWidth: textWidth + 2 * cellHorizontalMargin @@ -104,6 +104,9 @@ ScrollView { width: itemsView.viewport.width caption: sectionName // to be set by model visible: sectionVisible + topPadding: 2 + leftPadding: 2 + rightPadding: 1 Grid { id: itemGrid diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Section.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Section.qml index ce2a2622033..f794b377d47 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Section.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Section.qml @@ -35,6 +35,9 @@ Item { id: section property alias caption: label.text + property int leftPadding: 8 + property int topPadding: 4 + property int rightPadding: 0 clip: true @@ -93,16 +96,19 @@ Item { } } - default property alias __content: row.data + default property alias __content: row.children readonly property alias contentItem: row implicitHeight: Math.round(row.height + header.height + 8) Row { - width: parent.width - x: 8 - y: header.height + 4 + anchors.left: parent.left + anchors.leftMargin: leftPadding + anchors.right: parent.right + anchors.rightMargin: rightPadding + anchors.top: header.bottom + anchors.topMargin: topPadding id: row Behavior on opacity { NumberAnimation{easing.type: Easing.Linear ; duration: 80} } } diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml index f6dc75f62fa..81ff0cd0a44 100644 --- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml +++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml @@ -41,36 +41,19 @@ Rectangle { property int delegateStateImageSize gradient: Gradient { - GradientStop { position: 0.0; color: Qt.lighter(gradiantBaseColor, 1.1) } - GradientStop { position: 0.2; color: Qt.lighter(gradiantBaseColor, 1.2) } - GradientStop { position: 0.3; color: Qt.lighter(gradiantBaseColor, 1.1) } - GradientStop { position: 1.0; color: gradiantBaseColor } + GradientStop { position: 0.0; color: Qt.lighter(gradiantBaseColor, 1.5) } + GradientStop { position: 0.1; color: Qt.lighter(gradiantBaseColor, 1) } + GradientStop { position: 0.8; color: gradiantBaseColor } + GradientStop { position: 1.0; color: Qt.darker(gradiantBaseColor) } } MouseArea { anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - + acceptedButtons: Qt.LeftButton onClicked: { - if (mouse.button === Qt.LeftButton) { - focus = true - root.currentStateInternalId = internalNodeId - } else if (mouse.button === Qt.RightButton) { - contextMenu.popup() - } - } - - Menu { - id: contextMenu - - MenuItem { - text: root.expanded ? qsTr("Collapse") : qsTr("Expand") - onTriggered: { - root.expanded = ! root.expanded - } - - } + focus = true + root.currentStateInternalId = internalNodeId } } diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml index ad4d8c453b0..82130cb0c00 100644 --- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml +++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml @@ -35,7 +35,7 @@ import "../common" FocusScope { id: root - height: expanded ? 132 : 32 + height: expanded ? 136 : 32 signal createNewState signal deleteState(int internalNodeId) signal duplicateCurrentState @@ -44,7 +44,7 @@ FocusScope { property int delegateWidth: stateImageSize + 10 property int padding: 2 property int delegateHeight: root.height - padding * 2 - property int innerSpacing: 2 + property int innerSpacing: -1 property int currentStateInternalId : 0 property bool expanded: true @@ -63,31 +63,41 @@ FocusScope { anchors.fill: parent color: "#4f4f4f" } + MouseArea { anchors.fill: parent - onClicked: focus = true + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onClicked: { + if (mouse.button === Qt.LeftButton) + focus = true + else if (mouse.button === Qt.RightButton) + contextMenu.popup() + } + + Menu { + id: contextMenu + + MenuItem { + text: root.expanded ? qsTr("Collapse") : qsTr("Expand") + onTriggered: { + root.expanded = !root.expanded + } + + } + } } Item { id: addStateItem - property int buttonLeftSpacing: innerSpacing + property int buttonLeftSpacing: 0 anchors.right: parent.right width: delegateHeight / 2 + buttonLeftSpacing height: delegateHeight Button { - style: ButtonStyle { - background: Rectangle { - implicitWidth: 100 - implicitHeight: 25 - color: control.hovered ? "#6f6f6f" : "#4f4f4f" - - border.color: "black" - } - } - id: addStateButton visible: canAddNewStates @@ -130,16 +140,6 @@ FocusScope { delegateStateImageSource: stateImageSource delegateStateImageSize: stateImageSize } - Rectangle { - /* Rectangle at the bottom using the highlight color */ - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: 1 - anchors.rightMargin: 1 - height: 4 - color: Qt.darker(highlightColor, 1.2) - } } } } diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index d102db0fe0d..76213cc2c37 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -4455,6 +4455,9 @@ public: ExceptionSpecificationAST *exception_specification; TrailingReturnTypeAST *trailing_return_type; +public: // annotations + Function *symbol; + public: LambdaDeclaratorAST() : lparen_token(0) diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 67d9f2f8773..e6245eb0365 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -1087,11 +1087,10 @@ bool Bind::visit(LambdaDeclaratorAST *ast) return false; } -void Bind::lambdaDeclarator(LambdaDeclaratorAST *ast) +Function *Bind::lambdaDeclarator(LambdaDeclaratorAST *ast) { if (! ast) - return; - + return 0; Function *fun = control()->newFunction(0, 0); fun->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin()); @@ -1099,6 +1098,7 @@ void Bind::lambdaDeclarator(LambdaDeclaratorAST *ast) if (ast->trailing_return_type) _type = this->trailingReturnType(ast->trailing_return_type, _type); fun->setReturnType(_type); + ast->symbol = fun; // unsigned lparen_token = ast->lparen_token; FullySpecifiedType type; @@ -1108,7 +1108,8 @@ void Bind::lambdaDeclarator(LambdaDeclaratorAST *ast) type = this->specifier(it->value, type); } // unsigned mutable_token = ast->mutable_token; - type = this->exceptionSpecification(ast->exception_specification, type); + _type = this->exceptionSpecification(ast->exception_specification, type); + return fun; } bool Bind::visit(TrailingReturnTypeAST *ast) @@ -1780,8 +1781,15 @@ bool Bind::visit(ObjCSelectorExpressionAST *ast) bool Bind::visit(LambdaExpressionAST *ast) { this->lambdaIntroducer(ast->lambda_introducer); - this->lambdaDeclarator(ast->lambda_declarator); - this->statement(ast->statement); + if (Function *function = this->lambdaDeclarator(ast->lambda_declarator)) { + _scope->addMember(function); + Scope *previousScope = switchScope(function); + this->statement(ast->statement); + (void) switchScope(previousScope); + } else { + this->statement(ast->statement); + } + return false; } diff --git a/src/libs/3rdparty/cplusplus/Bind.h b/src/libs/3rdparty/cplusplus/Bind.h index 9fdab3f9054..ded74a9da84 100644 --- a/src/libs/3rdparty/cplusplus/Bind.h +++ b/src/libs/3rdparty/cplusplus/Bind.h @@ -103,7 +103,7 @@ protected: void lambdaIntroducer(LambdaIntroducerAST *ast); void lambdaCapture(LambdaCaptureAST *ast); void capture(CaptureAST *ast); - void lambdaDeclarator(LambdaDeclaratorAST *ast); + Function *lambdaDeclarator(LambdaDeclaratorAST *ast); FullySpecifiedType trailingReturnType(TrailingReturnTypeAST *ast, const FullySpecifiedType &init); const StringLiteral *asStringLiteral(unsigned firstToken, unsigned lastToken); diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp index 9bc8edecfda..df9c2151a45 100644 --- a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp +++ b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp @@ -164,7 +164,7 @@ void TranslationUnit::tokenize() _Lrecognize: if (tk.is(T_POUND) && tk.newline()) { - unsigned offset = tk.byteOffset; + const unsigned utf16CharOffset = tk.utf16charOffset; lex(&tk); if (! tk.newline() && tk.is(T_IDENTIFIER) && tk.identifier == expansionId) { @@ -237,7 +237,7 @@ void TranslationUnit::tokenize() if (! tk.newline() && tk.is(T_STRING_LITERAL)) { const StringLiteral *fileName = control()->stringLiteral(tk.string->chars(), tk.string->size()); - pushPreprocessorLine(offset, line, fileName); + pushPreprocessorLine(utf16CharOffset, line, fileName); lex(&tk); } } @@ -343,10 +343,10 @@ bool TranslationUnit::parse(ParseMode mode) void TranslationUnit::pushLineOffset(unsigned offset) { _lineOffsets.push_back(offset); } -void TranslationUnit::pushPreprocessorLine(unsigned offset, +void TranslationUnit::pushPreprocessorLine(unsigned utf16charOffset, unsigned line, const StringLiteral *fileName) -{ _ppLines.push_back(PPLine(offset, line, fileName)); } +{ _ppLines.push_back(PPLine(utf16charOffset, line, fileName)); } unsigned TranslationUnit::findLineNumber(unsigned utf16charOffset) const { @@ -359,10 +359,10 @@ unsigned TranslationUnit::findLineNumber(unsigned utf16charOffset) const return it - _lineOffsets.begin(); } -TranslationUnit::PPLine TranslationUnit::findPreprocessorLine(unsigned offset) const +TranslationUnit::PPLine TranslationUnit::findPreprocessorLine(unsigned utf16charOffset) const { std::vector::const_iterator it = - std::lower_bound(_ppLines.begin(), _ppLines.end(), PPLine(offset)); + std::lower_bound(_ppLines.begin(), _ppLines.end(), PPLine(utf16charOffset)); if (it != _ppLines.begin()) --it; @@ -419,7 +419,7 @@ void TranslationUnit::getPosition(unsigned utf16charOffset, // Adjust the line in regards to the preprocessing markers. const PPLine ppLine = findPreprocessorLine(utf16charOffset); - lineNumber -= findLineNumber(ppLine.offset) + 1; + lineNumber -= findLineNumber(ppLine.utf16charOffset) + 1; lineNumber += ppLine.line; file = ppLine.fileName; diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.h b/src/libs/3rdparty/cplusplus/TranslationUnit.h index 83213703c59..c42e25f958e 100644 --- a/src/libs/3rdparty/cplusplus/TranslationUnit.h +++ b/src/libs/3rdparty/cplusplus/TranslationUnit.h @@ -138,7 +138,7 @@ public: const StringLiteral **fileName = 0) const; void pushLineOffset(unsigned offset); - void pushPreprocessorLine(unsigned offset, + void pushPreprocessorLine(unsigned utf16charOffset, unsigned line, const StringLiteral *fileName); @@ -151,30 +151,30 @@ public: private: struct PPLine { - unsigned offset; + unsigned utf16charOffset; unsigned line; const StringLiteral *fileName; - PPLine(unsigned offset = 0, + PPLine(unsigned utf16charOffset = 0, unsigned line = 0, const StringLiteral *fileName = 0) - : offset(offset), line(line), fileName(fileName) + : utf16charOffset(utf16charOffset), line(line), fileName(fileName) { } bool operator == (const PPLine &other) const - { return offset == other.offset; } + { return utf16charOffset == other.utf16charOffset; } bool operator != (const PPLine &other) const - { return offset != other.offset; } + { return utf16charOffset != other.utf16charOffset; } bool operator < (const PPLine &other) const - { return offset < other.offset; } + { return utf16charOffset < other.utf16charOffset; } }; void releaseTokensAndComments(); unsigned findLineNumber(unsigned utf16charOffset) const; unsigned findColumnNumber(unsigned utf16CharOffset, unsigned lineNumber) const; - PPLine findPreprocessorLine(unsigned offset) const; + PPLine findPreprocessorLine(unsigned utf16charOffset) const; void showErrorLine(unsigned index, unsigned column, FILE *out); static const Token nullToken; diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index f8cdf106a0d..aae1b25ff10 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -1082,9 +1082,9 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac const unsigned argumentCountOfSpecialization = templateSpecialization->templateParameterCount(); + Subst subst(_control.data()); if (_factory->expandTemplates()) { Clone cloner(_control.data()); - Subst subst(_control.data()); for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) { const TypenameArgument *tParam = templateSpecialization->templateParameterAt(i)->asTypenameArgument(); @@ -1149,6 +1149,13 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac } } } + if (!baseBinding && subst.contains(baseName)) { + const FullySpecifiedType &fullType = subst[baseName]; + if (fullType.isValid()) { + if (NamedType *namedType = fullType.type()->asNamedType()) + baseBinding = lookupType(namedType->name()); + } + } } else { SubstitutionMap map; for (unsigned i = 0; diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index 3d259dea773..fd6f7c0549c 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -265,6 +265,16 @@ QRegExp PluginSpec::platformSpecification() const return d->platformSpecification; } +bool PluginSpec::isAvailableForHostPlatform() const +{ + return d->platformSpecification.isEmpty() || d->platformSpecification.exactMatch(PluginManager::platformName()); +} + +bool PluginSpec::isRequired() const +{ + return d->required; +} + /*! Returns whether the plugin has its experimental flag set. */ @@ -307,7 +317,7 @@ bool PluginSpec::isEffectivelyEnabled() const || d->forceDisabled) { return false; } - return d->platformSpecification.isEmpty() || d->platformSpecification.exactMatch(PluginManager::platformName()); + return isAvailableForHostPlatform(); } /*! @@ -460,6 +470,7 @@ namespace { const char PLUGIN_NAME[] = "name"; const char PLUGIN_VERSION[] = "version"; const char PLUGIN_COMPATVERSION[] = "compatVersion"; + const char PLUGIN_REQUIRED[] = "required"; const char PLUGIN_EXPERIMENTAL[] = "experimental"; const char PLUGIN_DISABLED_BY_DEFAULT[] = "disabledByDefault"; const char VENDOR[] = "vendor"; @@ -485,17 +496,17 @@ namespace { \internal */ PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec) - : - experimental(false), - disabledByDefault(false), - enabledInSettings(true), - disabledIndirectly(false), - forceEnabled(false), - forceDisabled(false), - plugin(0), - state(PluginSpec::Invalid), - hasError(false), - q(spec) + : required(false), + experimental(false), + disabledByDefault(false), + enabledInSettings(true), + disabledIndirectly(false), + forceEnabled(false), + forceDisabled(false), + plugin(0), + state(PluginSpec::Invalid), + hasError(false), + q(spec) { } @@ -642,8 +653,9 @@ void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader) } else if (compatVersion.isEmpty()) { compatVersion = version; } - disabledByDefault = readBooleanValue(reader, PLUGIN_DISABLED_BY_DEFAULT); + required = readBooleanValue(reader, PLUGIN_REQUIRED); experimental = readBooleanValue(reader, PLUGIN_EXPERIMENTAL); + disabledByDefault = readBooleanValue(reader, PLUGIN_DISABLED_BY_DEFAULT); if (reader.hasError()) return; if (experimental) diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index 15e561742d8..7ebb65f09ef 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -92,6 +92,8 @@ public: QString url() const; QString category() const; QRegExp platformSpecification() const; + bool isAvailableForHostPlatform() const; + bool isRequired() const; bool isExperimental() const; bool isDisabledByDefault() const; bool isEnabledInSettings() const; diff --git a/src/libs/extensionsystem/pluginspec_p.h b/src/libs/extensionsystem/pluginspec_p.h index f6944cf1371..6dfac9dbd31 100644 --- a/src/libs/extensionsystem/pluginspec_p.h +++ b/src/libs/extensionsystem/pluginspec_p.h @@ -65,6 +65,7 @@ public: QString name; QString version; QString compatVersion; + bool required; bool experimental; bool disabledByDefault; QString vendor; diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index 883633dd5ef..f2ef4744a42 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -108,10 +108,6 @@ PluginView::PluginView(QWidget *parent) m_errorIcon = QIcon(QLatin1String(":/extensionsystem/images/error.png")); m_notLoadedIcon = QIcon(QLatin1String(":/extensionsystem/images/notloaded.png")); - // cannot disable these - m_whitelist << QString::fromLatin1("Core") << QString::fromLatin1("Locator") - << QString::fromLatin1("Find") << QString::fromLatin1("TextEditor"); - connect(PluginManager::instance(), SIGNAL(pluginsChanged()), this, SLOT(updateList())); connect(m_categoryWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectPlugin(QTreeWidgetItem*))); @@ -234,15 +230,19 @@ int PluginView::parsePluginSpecs(QTreeWidgetItem *parentItem, Qt::CheckState &gr ++checkedCount; } - if (!m_whitelist.contains(spec->name())) { - pluginItem->setData(C_LOAD, Qt::CheckStateRole, state); - } else { + if (!spec->isAvailableForHostPlatform()) { + pluginItem->setData(C_LOAD, Qt::CheckStateRole, Qt::Unchecked); + pluginItem->setFlags(Qt::ItemIsSelectable); + pluginItem->setToolTip(C_LOAD, tr("Plugin is not available on this platform.")); + } else if (spec->isRequired()){ pluginItem->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked); pluginItem->setFlags(Qt::ItemIsSelectable); + pluginItem->setToolTip(C_LOAD, tr("Plugin is required.")); + } else { + pluginItem->setData(C_LOAD, Qt::CheckStateRole, state); + pluginItem->setToolTip(C_LOAD, tr("Load on startup")); } - pluginItem->setToolTip(C_LOAD, tr("Load on Startup")); - m_specToItem.insert(spec, pluginItem); if (parentItem) @@ -336,13 +336,10 @@ void PluginView::updatePluginSettings(QTreeWidgetItem *item, int column) PluginSpec *spec = collection->plugins().at(i); QTreeWidgetItem *child = m_specToItem.value(spec); - if (!m_whitelist.contains(spec->name())) { + if (spec->isAvailableForHostPlatform() && !spec->isRequired()) { spec->setEnabled(loadOnStartup); Qt::CheckState state = (loadOnStartup ? Qt::Checked : Qt::Unchecked); child->setData(C_LOAD, Qt::CheckStateRole, state); - } else { - child->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked); - child->setFlags(Qt::ItemIsSelectable); } } updatePluginDependencies(); @@ -357,7 +354,7 @@ void PluginView::updatePluginDependencies() { foreach (PluginSpec *spec, PluginManager::loadQueue()) { bool disableIndirectly = false; - if (m_whitelist.contains(spec->name())) + if (spec->isRequired()) continue; QHashIterator it(spec->dependencySpecs()); @@ -372,7 +369,7 @@ void PluginView::updatePluginDependencies() } } QTreeWidgetItem *childItem = m_specToItem.value(spec); - childItem->setDisabled(disableIndirectly); + childItem->setDisabled(disableIndirectly || !spec->isAvailableForHostPlatform()); if (disableIndirectly == spec->isDisabledIndirectly()) continue; diff --git a/src/libs/extensionsystem/pluginview.h b/src/libs/extensionsystem/pluginview.h index bf7e5992118..2709014b181 100644 --- a/src/libs/extensionsystem/pluginview.h +++ b/src/libs/extensionsystem/pluginview.h @@ -79,7 +79,6 @@ private: QList m_items; QHash m_specToItem; - QStringList m_whitelist; QIcon m_okIcon; QIcon m_errorIcon; QIcon m_notLoadedIcon; diff --git a/src/libs/qmljs/qmljscodeformatter.cpp b/src/libs/qmljs/qmljscodeformatter.cpp index caeb40da6f8..89e7544e1ee 100644 --- a/src/libs/qmljs/qmljscodeformatter.cpp +++ b/src/libs/qmljs/qmljscodeformatter.cpp @@ -35,9 +35,11 @@ #include #include -namespace QmlJS { - +namespace { Q_LOGGING_CATEGORY(formatterLog, "qtc.qmljs.formatter") +} + +namespace QmlJS { CodeFormatter::BlockData::BlockData() : m_indentDepth(0) diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp index 66da8d2932e..f3e0eb5fe53 100644 --- a/src/libs/qmljs/qmljsdocument.cpp +++ b/src/libs/qmljs/qmljsdocument.cpp @@ -38,6 +38,7 @@ #include #include +#include #include @@ -525,7 +526,7 @@ void Snapshot::insert(const Document::Ptr &document, bool allowInvalid) cImport.importId = document->importId(); cImport.language = document->language(); cImport.possibleExports << Export(ImportKey(ImportType::File, fileName), - QString(), true); + QString(), true, QFileInfo(fileName).baseName()); cImport.fingerprint = document->fingerprint(); _dependencies.addCoreImport(cImport); } @@ -554,15 +555,59 @@ void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info) } QStringList splitPath = path.split(QLatin1Char('/')); + QRegExp vNr(QLatin1String("^(.+)\\.([0-9]+)(?:\\.([0-9]+))?$")); + QRegExp safeName(QLatin1String("^[a-zA-Z_][[a-zA-Z0-9_]*$")); foreach (const ImportKey &importKey, packages) { - QString requiredPath = QStringList(splitPath.mid(0, splitPath.size() - importKey.splitPath.size())) - .join(QLatin1String("/")); - cImport.possibleExports << Export(importKey, requiredPath, true); + if (importKey.splitPath.size() == 1 && importKey.splitPath.at(0).isEmpty()) { + // relocatable + QStringList myPath = splitPath; + if (vNr.indexIn(myPath.last()) == 0) { + myPath.last() = vNr.cap(1); + } + for (int iPath = myPath.size(); iPath != 0; ) { + --iPath; + if (safeName.indexIn(myPath.at(iPath)) != 0) + break; + ImportKey iKey(ImportType::Library, QStringList(myPath.mid(iPath)).join(QLatin1String(".")), + importKey.majorVersion, importKey.minorVersion); + cImport.possibleExports.append(Export(iKey, QStringList(myPath.mid(0, iPath)) + .join(QLatin1String("/")), true)); + } + } else { + QString requiredPath = QStringList(splitPath.mid(0, splitPath.size() - importKey.splitPath.size())) + .join(QLatin1String("/")); + cImport.possibleExports << Export(importKey, requiredPath, true); + } + } + if (cImport.possibleExports.isEmpty()) { + QRegExp vNr(QLatin1String("^(.+)\\.([0-9]+)(?:\\.([0-9]+))?$")); + QRegExp safeName(QLatin1String("^[a-zA-Z_][[a-zA-Z0-9_]*$")); + int majorVersion = LanguageUtils::ComponentVersion::NoVersion; + int minorVersion = LanguageUtils::ComponentVersion::NoVersion; + if (vNr.indexIn(splitPath.last()) == 0) { + splitPath.last() = vNr.cap(1); + bool ok; + majorVersion = vNr.cap(2).toInt(&ok); + if (!ok) + majorVersion = LanguageUtils::ComponentVersion::NoVersion; + minorVersion = vNr.cap(3).toInt(&ok); + if (vNr.cap(3).isEmpty() || !ok) + minorVersion = LanguageUtils::ComponentVersion::NoVersion; + } + + for (int iPath = splitPath.size(); iPath != 0; ) { + --iPath; + if (safeName.indexIn(splitPath.at(iPath)) != 0) + break; + ImportKey iKey(ImportType::Library, QStringList(splitPath.mid(iPath)).join(QLatin1String(".")), + majorVersion, minorVersion); + cImport.possibleExports.append(Export(iKey, QStringList(splitPath.mid(0, iPath)) + .join(QLatin1String("/")), true)); + } } foreach (const QmlDirParser::Component &component, info.components()) { foreach (const Export &e, cImport.possibleExports) - // renaming of type name not really represented here... fix? - _dependencies.addExport(component.fileName, e.exportName, e.pathRequired); + _dependencies.addExport(component.fileName, e.exportName, e.pathRequired, e.typeName); } cImport.fingerprint = info.fingerprint(); _dependencies.addCoreImport(cImport); diff --git a/src/libs/qmljs/qmljsicons.cpp b/src/libs/qmljs/qmljsicons.cpp index 611e75d2f2b..3131583aa6f 100644 --- a/src/libs/qmljs/qmljsicons.cpp +++ b/src/libs/qmljs/qmljsicons.cpp @@ -43,9 +43,11 @@ enum { debug = false }; -namespace QmlJS { - +namespace { Q_LOGGING_CATEGORY(iconsLog, "qtc.qmljs.icons") +} + +namespace QmlJS { Icons *Icons::m_instance = 0; diff --git a/src/libs/qmljs/qmljsimportdependencies.cpp b/src/libs/qmljs/qmljsimportdependencies.cpp index e4fa8fba97e..60a79c51b06 100644 --- a/src/libs/qmljs/qmljsimportdependencies.cpp +++ b/src/libs/qmljs/qmljsimportdependencies.cpp @@ -38,9 +38,11 @@ #include -namespace QmlJS { - +namespace { Q_LOGGING_CATEGORY(importsLog, "qtc.qmljs.imports") +} + +namespace QmlJS { ImportKind::Enum toImportKind(ImportType::Enum type) { @@ -471,12 +473,14 @@ bool operator <(const ImportKey &i1, const ImportKey &i2) return i1.compare(i2) < 0; } +const QString Export::LibraryTypeName = QLatin1String("%Library%"); + Export::Export() : intrinsic(false) { } -Export::Export(ImportKey exportName, QString pathRequired, bool intrinsic) - : exportName(exportName), pathRequired(pathRequired), intrinsic(intrinsic) +Export::Export(ImportKey exportName, QString pathRequired, bool intrinsic, const QString &typeName) + : exportName(exportName), pathRequired(pathRequired), typeName(typeName), intrinsic(intrinsic) { } bool Export::visibleInVContext(const ViewerContext &vContext) const @@ -488,7 +492,8 @@ bool operator ==(const Export &i1, const Export &i2) { return i1.exportName == i2.exportName && i1.pathRequired == i2.pathRequired - && i1.intrinsic == i2.intrinsic; + && i1.intrinsic == i2.intrinsic + && i1.typeName == i2.typeName; } bool operator !=(const Export &i1, const Export &i2) @@ -770,32 +775,32 @@ void ImportDependencies::removeImportCacheEntry(const ImportKey &importKey, cons } void ImportDependencies::addExport(const QString &importId, const ImportKey &importKey, - const QString &requiredPath) + const QString &requiredPath, const QString &typeName) { if (!m_coreImports.contains(importId)) { CoreImport newImport(importId); newImport.language = Language::AnyLanguage; - newImport.possibleExports.append(Export(importKey, requiredPath, false)); + newImport.possibleExports.append(Export(importKey, requiredPath, false, typeName)); m_coreImports.insert(newImport.importId, newImport); m_importCache[importKey].append(importId); return; } CoreImport &importValue = m_coreImports[importId]; - importValue.possibleExports.append(Export(importKey, requiredPath, false)); + importValue.possibleExports.append(Export(importKey, requiredPath, false, typeName)); m_importCache[importKey].append(importId); qCDebug(importsLog) << "added export "<< importKey.toString() << " for id " < const &iterF) const; diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp index b31f04cd915..6a65e9a6fac 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp @@ -749,6 +749,8 @@ static bool findNewQmlLibraryInPath(const QString &path, const QString libraryPath = QFileInfo(qmldirFile).absolutePath(); newLibraries->insert(libraryPath); modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser)); + modelManager->loadPluginTypes(QFileInfo(libraryPath).canonicalFilePath(), libraryPath, + QString(), QString()); // scan the qml files in the library foreach (const QmlDirParser::Component &component, qmldirParser.components()) { @@ -1283,8 +1285,11 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx, { ViewerContext res = vCtx; - if (vCtx.language == Language::Qml && !doc.isNull() && - (doc->language() == Language::QmlQtQuick1 || doc->language() == Language::QmlQtQuick2)) + if (!doc.isNull() + && ((vCtx.language == Language::AnyLanguage && doc->language() != Language::NoLanguage) + || (vCtx.language == Language::Qml + && (doc->language() == Language::QmlQtQuick1 + || doc->language() == Language::QmlQtQuick2)))) res.language = doc->language(); ProjectInfo info; if (!doc.isNull()) @@ -1362,7 +1367,7 @@ ViewerContext ModelManagerInterface::defaultVContext(Language::Enum language, bool autoComplete) const { if (!doc.isNull()) { - if (language == Language::AnyLanguage) + if (language == Language::AnyLanguage && doc->language() != Language::NoLanguage) language = doc->language(); else if (language == Language::Qml && (doc->language() == Language::QmlQtQuick1 || doc->language() == Language::QmlQtQuick2)) @@ -1373,6 +1378,7 @@ ViewerContext ModelManagerInterface::defaultVContext(Language::Enum language, QMutexLocker locker(&m_mutex); defaultCtx = m_defaultVContexts.value(language); } + defaultCtx.language = language; if (autoComplete) return completeVContext(defaultCtx, doc); else diff --git a/src/libs/qmljs/qmljssimplereader.cpp b/src/libs/qmljs/qmljssimplereader.cpp index a47da70ce05..46505eb3c1a 100644 --- a/src/libs/qmljs/qmljssimplereader.cpp +++ b/src/libs/qmljs/qmljssimplereader.cpp @@ -39,8 +39,11 @@ #include -namespace QmlJS{ +namespace { Q_LOGGING_CATEGORY(simpleReaderLog, "qtc.qmljs.simpleReader") +} + +namespace QmlJS{ QVariant SimpleReaderNode::property(const QString &name) const { diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index 4c0573a38aa..e9c5642868e 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -427,7 +427,10 @@ void AutotoolsProject::updateCppCodeModel() foreach (const QString &file, m_files) part->files << CppTools::ProjectFile(file, CppTools::ProjectFile::CXXSource); - part->includePaths += m_makefileParserThread->includePaths(); + foreach (const QString &inc, m_makefileParserThread->includePaths()) { + part->headerPaths += CppTools::ProjectPart::HeaderPath( + inc, CppTools::ProjectPart::HeaderPath::IncludePath); + } part->projectDefines += m_makefileParserThread->defines(); pinfo.appendProjectPart(part); diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp index c92d34da220..42e213b3425 100644 --- a/src/plugins/bineditor/bineditor.cpp +++ b/src/plugins/bineditor/bineditor.cpp @@ -1571,6 +1571,7 @@ void BinEditorWidget::updateContents() m_oldData = m_data; m_data.clear(); setSizes(baseAddress() + cursorPosition(), m_size, m_blockSize); + viewport()->update(); } QPoint BinEditorWidget::offsetToPos(int offset) const diff --git a/src/plugins/bookmarks/bookmark.cpp b/src/plugins/bookmarks/bookmark.cpp index 8dce8795f2d..7c444a6e549 100644 --- a/src/plugins/bookmarks/bookmark.cpp +++ b/src/plugins/bookmarks/bookmark.cpp @@ -54,9 +54,10 @@ void Bookmark::removedFromEditor() void Bookmark::updateLineNumber(int line) { - if (line != lineNumber()) + if (line != lineNumber()) { + BaseTextMark::updateLineNumber(line); m_manager->updateBookmark(this); - BaseTextMark::updateLineNumber(line); + } } void Bookmark::updateBlock(const QTextBlock &block) diff --git a/src/plugins/clangcodemodel/clangcompletion.cpp b/src/plugins/clangcodemodel/clangcompletion.cpp index 3e49295749b..90ed1d77948 100644 --- a/src/plugins/clangcodemodel/clangcompletion.cpp +++ b/src/plugins/clangcodemodel/clangcompletion.cpp @@ -213,7 +213,8 @@ IAssistInterface *ClangCompletionAssistProvider::createAssistInterface( QList parts = modelManager->projectPart(fileName); if (parts.isEmpty()) parts += modelManager->fallbackProjectPart(); - QStringList includePaths, frameworkPaths, options; + ProjectPart::HeaderPaths headerPaths; + QStringList options; PchInfo::Ptr pchInfo; foreach (ProjectPart::Ptr part, parts) { if (part.isNull()) @@ -222,15 +223,14 @@ IAssistInterface *ClangCompletionAssistProvider::createAssistInterface( pchInfo = PchManager::instance()->pchInfo(part); if (!pchInfo.isNull()) options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName())); - includePaths = part->includePaths; - frameworkPaths = part->frameworkPaths; + headerPaths = part->headerPaths; break; } return new ClangCodeModel::ClangCompletionAssistInterface( m_clangCompletionWrapper, document, position, fileName, reason, - options, includePaths, frameworkPaths, pchInfo); + options, headerPaths, pchInfo); } // ------------------------ @@ -550,14 +550,12 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface(ClangCompleter::P const QString &fileName, AssistReason reason, const QStringList &options, - const QStringList &includePaths, - const QStringList &frameworkPaths, + const QList &headerPaths, const PchInfo::Ptr &pchInfo) : DefaultAssistInterface(document, position, fileName, reason) , m_clangWrapper(clangWrapper) , m_options(options) - , m_includePaths(includePaths) - , m_frameworkPaths(frameworkPaths) + , m_headerPaths(headerPaths) , m_savedPchPointer(pchInfo) { Q_ASSERT(!clangWrapper.isNull()); @@ -1138,29 +1136,22 @@ bool ClangCompletionAssistProcessor::completeInclude(const QTextCursor &cursor) } // Make completion for all relevant includes - QStringList includePaths = m_interface->includePaths(); - const QString ¤tFilePath = QFileInfo(m_interface->fileName()).path(); - if (!includePaths.contains(currentFilePath)) - includePaths.append(currentFilePath); + ProjectPart::HeaderPaths headerPaths = m_interface->headerPaths(); + const ProjectPart::HeaderPath currentFilePath(QFileInfo(m_interface->fileName()).path(), + ProjectPart::HeaderPath::IncludePath); + if (!headerPaths.contains(currentFilePath)) + headerPaths.append(currentFilePath); const Core::MimeType mimeType = Core::MimeDatabase::findByType(QLatin1String("text/x-c++hdr")); const QStringList suffixes = mimeType.suffixes(); - foreach (const QString &includePath, includePaths) { - QString realPath = includePath; + foreach (const ProjectPart::HeaderPath &headerPath, headerPaths) { + QString realPath = headerPath.path; if (!directoryPrefix.isEmpty()) { realPath += QLatin1Char('/'); realPath += directoryPrefix; - } - completeIncludePath(realPath, suffixes); - } - - foreach (const QString &frameworkPath, m_interface->frameworkPaths()) { - QString realPath = frameworkPath; - if (!directoryPrefix.isEmpty()) { - realPath += QLatin1Char('/'); - realPath += directoryPrefix; - realPath += QLatin1String(".framework/Headers"); + if (headerPath.isFrameworkPath()) + realPath += QLatin1String(".framework/Headers"); } completeIncludePath(realPath, suffixes); } diff --git a/src/plugins/clangcodemodel/clangcompletion.h b/src/plugins/clangcodemodel/clangcompletion.h index 2e07b034c31..180d7ec763e 100644 --- a/src/plugins/clangcodemodel/clangcompletion.h +++ b/src/plugins/clangcodemodel/clangcompletion.h @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -76,8 +77,7 @@ public: const QString &fileName, TextEditor::AssistReason reason, const QStringList &options, - const QStringList &includePaths, - const QStringList &frameworkPaths, + const QList &headerPaths, const Internal::PchInfo::Ptr &pchInfo); ClangCodeModel::ClangCompleter::Ptr clangWrapper() const @@ -91,16 +91,14 @@ public: const QStringList &options() const { return m_options; } - const QStringList &includePaths() const - { return m_includePaths; } - - const QStringList &frameworkPaths() const - { return m_frameworkPaths; } + const QList &headerPaths() const + { return m_headerPaths; } private: ClangCodeModel::ClangCompleter::Ptr m_clangWrapper; ClangCodeModel::Internal::UnsavedFiles m_unsavedFiles; - QStringList m_options, m_includePaths, m_frameworkPaths; + QStringList m_options; + QList m_headerPaths; Internal::PchInfo::Ptr m_savedPchPointer; }; diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 9a8dede302e..9dbb1eea65c 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -209,11 +209,25 @@ QStringList createClangOptions(const ProjectPart::Ptr &pPart, ProjectFile::Kind result << buildDefines(pPart->toolchainDefines, false); result << buildDefines(pPart->projectDefines, false); - foreach (const QString &frameworkPath, pPart->frameworkPaths) - result.append(QLatin1String("-F") + frameworkPath); - foreach (const QString &inc, pPart->includePaths) - if (!inc.isEmpty() && !isBlacklisted(inc)) - result << (QLatin1String("-I") + inc); + typedef ProjectPart::HeaderPath HeaderPath; + foreach (const HeaderPath &headerPath , pPart->headerPaths) { + if (headerPath.path.isEmpty() || isBlacklisted(headerPath.path)) + continue; + + QString prefix; + switch (headerPath.type) { + case HeaderPath::FrameworkPath: + prefix = QLatin1String("-F"); + break; + default: // This shouldn't happen, but let's be nice..: + // intentional fall-through: + case HeaderPath::IncludePath: + prefix = QLatin1String("-I"); + break; + } + + result.append(prefix + headerPath.path); + } #if 0 qDebug() << "--- m_args:"; diff --git a/src/plugins/clangcodemodel/pchmanager.cpp b/src/plugins/clangcodemodel/pchmanager.cpp index 6733cd83c24..55a23f6a402 100644 --- a/src/plugins/clangcodemodel/pchmanager.cpp +++ b/src/plugins/clangcodemodel/pchmanager.cpp @@ -249,7 +249,8 @@ void PchManager::doPchInfoUpdateNone(QFutureInterface &future, void PchManager::doPchInfoUpdateFuzzy(QFutureInterface &future, const PchManager::UpdateParams params) { - QHash > includes, frameworks; + typedef ProjectPart::HeaderPath HeaderPath; + QHash> headers; QHash > definesPerPCH; QHash objc; QHash cplusplus; @@ -266,8 +267,7 @@ void PchManager::doPchInfoUpdateFuzzy(QFutureInterface &future, continue; inputToParts[pch].append(projectPart); - includes[pch].unite(QSet::fromList(projectPart->includePaths)); - frameworks[pch].unite(QSet::fromList(projectPart->frameworkPaths)); + headers[pch].unite(QSet::fromList(projectPart->headerPaths)); cVersions[pch] = std::max(cVersions.value(pch, ProjectPart::C89), projectPart->cVersion); cxxVersions[pch] = std::max(cxxVersions.value(pch, ProjectPart::CXX98), projectPart->cxxVersion); cxxExtensionsMap[pch] = cxxExtensionsMap[pch] | projectPart->cxxExtensions; @@ -306,8 +306,7 @@ void PchManager::doPchInfoUpdateFuzzy(QFutureInterface &future, projectPart->cVersion = cVersions[pch]; projectPart->cxxVersion = cxxVersions[pch]; projectPart->cxxExtensions = cxxExtensionsMap[pch]; - projectPart->includePaths = includes[pch].toList(); - projectPart->frameworkPaths = frameworks[pch].toList(); + projectPart->headerPaths = headers[pch].toList(); QList defines = definesPerPCH[pch].toList(); if (!defines.isEmpty()) { @@ -378,22 +377,20 @@ void PchManager::doPchInfoUpdateCustom(QFutureInterface &future, future.setProgressRange(0, 1); future.setProgressValue(0); - QSet includes, frameworks; + ProjectPart::HeaderPaths headers; bool objc = false; bool cplusplus = false; ProjectPart::Ptr united(new ProjectPart()); united->cxxVersion = ProjectPart::CXX98; foreach (const ProjectPart::Ptr &projectPart, params.projectParts) { - includes.unite(QSet::fromList(projectPart->includePaths)); - frameworks.unite(QSet::fromList(projectPart->frameworkPaths)); + headers += projectPart->headerPaths; united->cVersion = std::max(united->cVersion, projectPart->cVersion); united->cxxVersion = std::max(united->cxxVersion, projectPart->cxxVersion); united->qtVersion = std::max(united->qtVersion, projectPart->qtVersion); objc |= hasObjCFiles(projectPart); cplusplus |= hasCppFiles(projectPart); } - united->frameworkPaths = frameworks.toList(); - united->includePaths = includes.toList(); + united->headerPaths = headers; QStringList opts = Utils::createClangOptions( united, getPrefixFileKind(objc, cplusplus)); united.clear(); diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 41c849734da..f6227b46591 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -338,27 +338,32 @@ bool CMakeProject::parseCMakeLists() CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this); pinfo.clearProjectParts(); - CppTools::ProjectPart::Ptr part(new CppTools::ProjectPart); + typedef CppTools::ProjectPart ProjectPart; + ProjectPart::Ptr part(new ProjectPart); part->project = this; part->displayName = displayName(); part->projectFile = projectFilePath().toString(); // This explicitly adds -I. to the include paths - part->includePaths += projectDirectory().toString(); + part->headerPaths += ProjectPart::HeaderPath(projectDirectory().toString(), + ProjectPart::HeaderPath::IncludePath); foreach (const QString &includeFile, cbpparser.includeFiles()) { + ProjectPart::HeaderPath hp(includeFile, ProjectPart::HeaderPath::IncludePath); + // CodeBlocks is utterly ignorant of frameworks on Mac, and won't report framework // paths. The work-around is to check if the include path ends in ".framework", and // if so, add the parent directory as framework path. if (includeFile.endsWith(QLatin1String(".framework"))) { const int slashIdx = includeFile.lastIndexOf(QLatin1Char('/')); if (slashIdx != -1) { - part->frameworkPaths += includeFile.left(slashIdx); + hp = ProjectPart::HeaderPath(includeFile.left(slashIdx), + ProjectPart::HeaderPath::FrameworkPath); continue; } } - part->includePaths += includeFile; + part->headerPaths += hp; } part->projectDefines += cbpparser.defines(); diff --git a/src/plugins/coreplugin/Core.pluginspec.in b/src/plugins/coreplugin/Core.pluginspec.in index a9103261546..cb4c7fa9e73 100644 --- a/src/plugins/coreplugin/Core.pluginspec.in +++ b/src/plugins/coreplugin/Core.pluginspec.in @@ -1,4 +1,4 @@ - + Digia Plc (C) 2014 Digia Plc diff --git a/src/plugins/coreplugin/coreplugin.qbs b/src/plugins/coreplugin/coreplugin.qbs index cc1e6fecb66..7ea4afa2f82 100644 --- a/src/plugins/coreplugin/coreplugin.qbs +++ b/src/plugins/coreplugin/coreplugin.qbs @@ -11,6 +11,12 @@ QtcPlugin { "widgets", "xml", "network", "script", "sql", "help", "printsupport" ] } + + Depends { + name: "Qt.gui-private" + condition: qbs.targetOS.contains("windows") && Qt.core.versionMajor >= 5 + } + Depends { name: "Utils" } Depends { name: "Aggregation" } diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 4a7a6e0f4b6..8fd1605f76f 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -1414,19 +1415,42 @@ void DocumentManager::executeOpenWithMenuAction(QAction *action) const QVariant data = action->data(); OpenWithEntry entry = qvariant_cast(data); if (entry.editorFactory) { - // close any open editors that have this file open, but have a different type. + // close any open editors that have this file open + // remember the views to open new editors in there + QList views; QList editorsOpenForFile = DocumentModel::editorsForFilePath(entry.fileName); - if (!editorsOpenForFile.isEmpty()) { - foreach (IEditor *openEditor, editorsOpenForFile) { - if (entry.editorFactory->id() == openEditor->document()->id()) - editorsOpenForFile.removeAll(openEditor); - } - if (!EditorManager::closeEditors(editorsOpenForFile)) // don't open if cancel was pressed - return; + foreach (IEditor *openEditor, editorsOpenForFile) { + Internal::EditorView *view = EditorManager::viewForEditor(openEditor); + if (view && view->currentEditor() == openEditor) // visible + views.append(view); } + if (!EditorManager::closeEditors(editorsOpenForFile)) // don't open if cancel was pressed + return; - EditorManager::openEditor(entry.fileName, entry.editorFactory->id()); + if (views.isEmpty()) { + EditorManager::openEditor(entry.fileName, entry.editorFactory->id()); + } else { + if (Internal::EditorView *currentView = EditorManager::currentEditorView()) { + if (views.removeOne(currentView)) + views.prepend(currentView); // open editor in current view first + } + EditorManager::OpenEditorFlags flags; + foreach (Internal::EditorView *view, views) { + IEditor *editor = + EditorManager::openEditor(view, entry.fileName, entry.editorFactory->id(), + flags); + // Do not change the current editor after opening the first one. That + // * prevents multiple updates of focus etc which are not necessary + // * lets us control which editor is made current by putting the current editor view + // to the front (if that was in the list in the first place + flags |= EditorManager::DoNotChangeCurrentEditor; + // do not try to open more editors if this one failed, or editor type does not + // support duplication anyhow + if (!editor || !editor->duplicateSupported()) + break; + } + } return; } if (entry.externalEditor) diff --git a/src/plugins/coreplugin/editormanager/documentmodel.cpp b/src/plugins/coreplugin/editormanager/documentmodel.cpp index c7894db8b9c..47b19883f23 100644 --- a/src/plugins/coreplugin/editormanager/documentmodel.cpp +++ b/src/plugins/coreplugin/editormanager/documentmodel.cpp @@ -213,7 +213,7 @@ void DocumentModelPrivate::addEntry(DocumentModel::Entry *entry) int index; QString displayName = entry->displayName(); for (index = 0; index < m_entries.count(); ++index) { - if (displayName < m_entries.at(index)->displayName()) + if (displayName.localeAwareCompare(m_entries.at(index)->displayName()) < 0) break; } int row = index + 1/**/; diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 441efa50327..1c3fe72bc72 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -820,7 +820,7 @@ void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentMod contextMenu->addAction(d->m_closeAllEditorsExceptVisibleContextAction); } -void EditorManager::addNativeDirActions(QMenu *contextMenu, DocumentModel::Entry *entry) +void EditorManager::addNativeDirAndOpenWithActions(QMenu *contextMenu, DocumentModel::Entry *entry) { QTC_ASSERT(contextMenu, return); bool enabled = entry && !entry->fileName().isEmpty(); @@ -830,6 +830,12 @@ void EditorManager::addNativeDirActions(QMenu *contextMenu, DocumentModel::Entry contextMenu->addAction(d->m_openGraphicalShellAction); contextMenu->addAction(d->m_openTerminalAction); contextMenu->addAction(d->m_findInDirectoryAction); + QMenu *openWith = contextMenu->addMenu(tr("Open with")); + connect(openWith, SIGNAL(triggered(QAction*)), + DocumentManager::instance(), SLOT(executeOpenWithMenuAction(QAction*))); + openWith->setEnabled(enabled); + if (enabled) + DocumentManager::populateOpenWithMenu(openWith, entry->fileName()); } static void setFocusToEditorViewAndUnmaximizePanes(EditorView *view) diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index 27a408068b0..d0c264023c0 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -117,6 +117,8 @@ public: static IEditor *openEditorWithContents(Id editorId, QString *titlePattern = 0, const QByteArray &contents = QByteArray(), OpenEditorFlags flags = NoFlags); + static IEditor *openEditor(Internal::EditorView *view, const QString &fileName, + Id id = Id(), OpenEditorFlags flags = NoFlags, bool *newEditor = 0); static bool openExternalEditor(const QString &fileName, Id editorId); @@ -125,6 +127,7 @@ public: static IDocument *currentDocument(); static IEditor *currentEditor(); + static Internal::EditorView *currentEditorView(); static QList visibleEditors(); static void activateEditor(IEditor *editor, OpenEditorFlags flags = 0); @@ -136,6 +139,8 @@ public: static void closeEditor(DocumentModel::Entry *entry); static void closeOtherEditors(IDocument *document); + static Internal::EditorView *viewForEditor(IEditor *editor); + static void addCurrentPositionToNavigationHistory(IEditor *editor = 0, const QByteArray &saveState = QByteArray()); static void cutForwardNavigationHistory(); @@ -186,7 +191,7 @@ public: static QString windowTitleVcsTopic(); static void addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentModel::Entry *entry); - static void addNativeDirActions(QMenu *contextMenu, DocumentModel::Entry *entry); + static void addNativeDirAndOpenWithActions(QMenu *contextMenu, DocumentModel::Entry *entry); signals: void currentEditorChanged(Core::IEditor *editor); @@ -264,14 +269,10 @@ private: static void activateEditorForEntry(Internal::EditorView *view, DocumentModel::Entry *entry, OpenEditorFlags flags = NoFlags); static void activateView(Internal::EditorView *view); - static IEditor *openEditor(Internal::EditorView *view, const QString &fileName, - Id id = Id(), OpenEditorFlags flags = NoFlags, bool *newEditor = 0); static int visibleDocumentsCount(); static void setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory = false); static void setCurrentView(Internal::EditorView *view); - static Internal::EditorView *currentEditorView(); - static Internal::EditorView *viewForEditor(IEditor *editor); static Internal::SplitterOrView *findRoot(const Internal::EditorView *view, int *rootIndex = 0); static void closeView(Internal::EditorView *view); diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.cpp b/src/plugins/coreplugin/editormanager/openeditorsview.cpp index 550d563ef54..10ded003c55 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsview.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorsview.cpp @@ -208,7 +208,7 @@ void OpenEditorsWidget::contextMenuRequested(QPoint pos) m_model->mapToSource(editorIndex).row()); EditorManager::addSaveAndCloseEditorActions(&contextMenu, entry); contextMenu.addSeparator(); - EditorManager::addNativeDirActions(&contextMenu, entry); + EditorManager::addNativeDirAndOpenWithActions(&contextMenu, entry); contextMenu.exec(mapToGlobal(pos)); } diff --git a/src/plugins/coreplugin/editortoolbar.cpp b/src/plugins/coreplugin/editortoolbar.cpp index 2fabf7111c1..9cc2dd82f5f 100644 --- a/src/plugins/coreplugin/editortoolbar.cpp +++ b/src/plugins/coreplugin/editortoolbar.cpp @@ -325,7 +325,7 @@ void EditorToolBar::listContextMenu(QPoint pos) menu.addSeparator(); EditorManager::addSaveAndCloseEditorActions(&menu, entry); menu.addSeparator(); - EditorManager::addNativeDirActions(&menu, entry); + EditorManager::addNativeDirAndOpenWithActions(&menu, entry); QAction *result = menu.exec(d->m_editorList->mapToGlobal(pos)); if (result == copyPath) QApplication::clipboard()->setText(QDir::toNativeSeparators(fileName)); diff --git a/src/plugins/coreplugin/iwizardfactory.h b/src/plugins/coreplugin/iwizardfactory.h index f32ac26d660..9269e9f9705 100644 --- a/src/plugins/coreplugin/iwizardfactory.h +++ b/src/plugins/coreplugin/iwizardfactory.h @@ -57,7 +57,7 @@ public: }; Q_DECLARE_FLAGS(WizardFlags, WizardFlag) - IWizardFactory() { } + IWizardFactory() : m_kind(FileWizard) { } QString id() const { return m_id; } WizardKind kind() const { return m_kind; } diff --git a/src/plugins/coreplugin/locator/filesystemfilter.cpp b/src/plugins/coreplugin/locator/filesystemfilter.cpp index 350adab8738..f3c6aa0c824 100644 --- a/src/plugins/coreplugin/locator/filesystemfilter.cpp +++ b/src/plugins/coreplugin/locator/filesystemfilter.cpp @@ -89,7 +89,9 @@ QList FileSystemFilter::matchesFor(QFutureInterfaceincludePaths(), cmmi->frameworkPaths(), cmmi->definedMacros()); + dumper.dumpMergedEntities(cmmi->headerPaths(), cmmi->definedMacros()); } enum DocumentTabs { @@ -1559,8 +1559,7 @@ enum ProjectPartTabs { ProjectPartGeneralTab, ProjectPartFilesTab, ProjectPartDefinesTab, - ProjectPartIncludePathsTab, - ProjectPartFrameworkPathsTab, + ProjectPartHeaderPathsTab, ProjectPartPrecompiledHeadersTab }; @@ -1570,8 +1569,7 @@ static QString partTabName(int tabIndex, int numberOfEntries = -1) "&General", "Project &Files", "&Defines", - "&Include Paths", - "F&ramework Paths", + "&Header Paths", "Pre&compiled Headers" }; QString result = QLatin1String(names[tabIndex]); @@ -1591,13 +1589,9 @@ void CppCodeModelInspectorDialog::clearProjectPartData() m_ui->partProjectDefinesEdit->setPlainText(QString()); m_ui->projectPartTab->setTabText(ProjectPartDefinesTab, partTabName(ProjectPartDefinesTab)); - m_ui->partIncludePathsEdit->setPlainText(QString()); - m_ui->projectPartTab->setTabText(ProjectPartIncludePathsTab, - partTabName(ProjectPartIncludePathsTab)); - - m_ui->partFrameworkPathsEdit->setPlainText(QString()); - m_ui->projectPartTab->setTabText(ProjectPartFrameworkPathsTab, - partTabName(ProjectPartFrameworkPathsTab)); + m_ui->partHeaderPathsEdit->setPlainText(QString()); + m_ui->projectPartTab->setTabText(ProjectPartHeaderPathsTab, + partTabName(ProjectPartHeaderPathsTab)); m_ui->partPrecompiledHeadersEdit->setPlainText(QString()); m_ui->projectPartTab->setTabText(ProjectPartPrecompiledHeadersTab, @@ -1654,15 +1648,10 @@ void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr & m_ui->projectPartTab->setTabText(ProjectPartDefinesTab, partTabName(ProjectPartDefinesTab, numberOfDefines)); - // Include Paths - m_ui->partIncludePathsEdit->setPlainText(CMI::Utils::pathListToString(part->includePaths)); - m_ui->projectPartTab->setTabText(ProjectPartIncludePathsTab, - partTabName(ProjectPartIncludePathsTab, part->includePaths.size())); - - // Framework Paths - m_ui->partFrameworkPathsEdit->setPlainText(CMI::Utils::pathListToString(part->frameworkPaths)); - m_ui->projectPartTab->setTabText(ProjectPartFrameworkPathsTab, - partTabName(ProjectPartFrameworkPathsTab, part->frameworkPaths.size())); + // Header Paths + m_ui->partHeaderPathsEdit->setPlainText(CMI::Utils::pathListToString(part->headerPaths)); + m_ui->projectPartTab->setTabText(ProjectPartHeaderPathsTab, + partTabName(ProjectPartHeaderPathsTab, part->headerPaths.size())); // Precompiled Headers m_ui->partPrecompiledHeadersEdit->setPlainText( diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.ui b/src/plugins/cppeditor/cppcodemodelinspectordialog.ui index fbe95c08a78..3ef29c1f10a 100644 --- a/src/plugins/cppeditor/cppcodemodelinspectordialog.ui +++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.ui @@ -261,25 +261,11 @@ - &Include Paths + &Header Paths - - - true - - - - - - - - F&ramework Paths - - - - + true diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index c6c2d77d3dd..ec1f6aa8eb9 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -182,6 +182,7 @@ private slots: void test_quickfix_MoveFuncDefOutside_afterClass(); void test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames1(); void test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames2(); + void test_quickfix_MoveFuncDefOutside_macroUses(); void test_quickfix_MoveFuncDefToDecl_MemberFunc(); void test_quickfix_MoveFuncDefToDecl_MemberFuncOutside(); @@ -192,6 +193,7 @@ private slots: void test_quickfix_MoveFuncDefToDecl_FreeFuncToCppNS(); void test_quickfix_MoveFuncDefToDecl_CtorWithInitialization(); void test_quickfix_MoveFuncDefToDecl_structWithAssignedVariable(); + void test_quickfix_MoveFuncDefToDecl_macroUses(); void test_quickfix_AssignToLocalVariable_templates(); diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp index 1090d8eec38..9b4cb4934bf 100644 --- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp @@ -310,9 +310,10 @@ CPPEditorWidget::Link attemptFuncDeclDef(const QTextCursor &cursor, CPPEditorWidget *, CPlusPlus::Snapshot snapshot, const CPlusPlus::Document::Ptr &document, SymbolFinder *symbolFinder) { - snapshot.insert(document); - Link result; + QTC_ASSERT(document, return result); + + snapshot.insert(document); QList path = ASTPath(document)(cursor); @@ -518,7 +519,7 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & } // Check if we're on an operator declaration or definition. - if (!recognizedQtMethod) { + if (!recognizedQtMethod && documentFromSemanticInfo) { bool cursorRegionReached = false; for (int i = 0; i < tokens.size(); ++i) { const Token &tk = tokens.at(i); diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 7e142f5bde1..ce9853714b0 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -123,11 +123,12 @@ static QString &removeTrailingWhitespace(QString &input) /// Exactly one TestFile must contain the cursor position marker '@' in the originalSource. QuickFixTestCase::QuickFixTestCase(const QList &theTestFiles, CppQuickFixFactory *factory, - const QStringList &includePaths, - int resultIndex) + const ProjectPart::HeaderPaths &headerPaths, + int resultIndex, + const QByteArray &expectedFailMessage) : m_testFiles(theTestFiles) , m_cppCodeStylePreferences(0) - , m_restoreIncludePaths(false) + , m_restoreHeaderPaths(false) { QVERIFY(succeededSoFar()); @@ -144,10 +145,10 @@ QuickFixTestCase::QuickFixTestCase(const QList &theTe testFile->writeToDisk(); // Set appropriate include paths - if (!includePaths.isEmpty()) { - m_restoreIncludePaths = true; - m_includePathsToRestore = m_modelManager->includePaths(); - m_modelManager->setIncludePaths(includePaths); + if (!headerPaths.isEmpty()) { + m_restoreHeaderPaths = true; + m_headerPathsToRestore = m_modelManager->headerPaths(); + m_modelManager->setHeaderPaths(headerPaths); } // Update Code Model @@ -196,6 +197,8 @@ QuickFixTestCase::QuickFixTestCase(const QList &theTe // Check QString result = testFile->m_editorWidget->document()->toPlainText(); removeTrailingWhitespace(result); + if (!expectedFailMessage.isEmpty()) + QEXPECT_FAIL("", expectedFailMessage.data(), Continue); QCOMPARE(result, testFile->m_expectedSource); // Undo the change @@ -213,14 +216,22 @@ QuickFixTestCase::~QuickFixTestCase() m_cppCodeStylePreferences->setCurrentDelegate(m_cppCodeStylePreferencesOriginalDelegateId); // Restore include paths - if (m_restoreIncludePaths) - m_modelManager->setIncludePaths(m_includePathsToRestore); + if (m_restoreHeaderPaths) + m_modelManager->setHeaderPaths(m_headerPathsToRestore); // Remove created files from file system foreach (const QuickFixTestDocument::Ptr &testDocument, m_testFiles) QVERIFY(QFile::remove(testDocument->filePath())); } +void QuickFixTestCase::run(const QList &theTestFiles, + CppQuickFixFactory *factory, const QString &incPath) +{ + ProjectPart::HeaderPaths hps; + hps += ProjectPart::HeaderPath(incPath, ProjectPart::HeaderPath::IncludePath); + QuickFixTestCase(theTestFiles, factory, hps); +} + /// Delegates directly to AddIncludeForUndefinedIdentifierOp for easier testing. class AddIncludeForUndefinedIdentifierTestFactory : public CppQuickFixFactory { @@ -1289,7 +1300,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_afterClass() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory, QStringList(), 1); + QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check from header file: If there is a source file, insert the definition in the source file. @@ -1478,7 +1489,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_insideClass() "};"; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory, QStringList(), 1); + QuickFixTestCase(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 1); } /// Check not triggering when definition exists @@ -1492,7 +1503,8 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_notTriggeringWhenDefinitio const QByteArray expected = original; InsertDefFromDecl factory; - QuickFixTestCase test(singleDocument(original, expected), &factory, QStringList(), 1); + QuickFixTestCase test(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), + 1); } /// Find right implementation file. @@ -1910,7 +1922,7 @@ void insertToSectionDeclFromDef(const QByteArray §ion, int sectionIndex) testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDeclFromDef factory; - QuickFixTestCase(testFiles, &factory, QStringList(), sectionIndex); + QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), sectionIndex); } /// Check from source file: Insert in header file. @@ -1961,7 +1973,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_normal() // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Ignore *.moc includes @@ -1986,7 +1998,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_ignoremoc() + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include at top for a sorted group @@ -2012,7 +2024,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingTop( + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include in the middle for a sorted group @@ -2038,7 +2050,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingMidd + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include at bottom for a sorted group @@ -2064,7 +2076,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingBott + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: For an unsorted group the new include is appended @@ -2090,7 +2102,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_appendToUns + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert a local include at front if there are only global includes @@ -2117,7 +2129,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_firstLocalI + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert a global include at back if there are only local includes @@ -2146,7 +2158,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_firstGlobal + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Prefer group with longest matching prefix @@ -2176,7 +2188,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_preferGroup + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"prefixc.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Create a new include group if there are only include groups with a different include dir @@ -2203,7 +2215,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_newGroupIfO + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include dirs, sorted --> insert properly @@ -2231,7 +2243,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedDirsSo + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include dirs, unsorted --> append @@ -2259,7 +2271,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedDirsUn + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2285,7 +2297,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"z.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2311,7 +2323,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"a.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2337,7 +2349,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"lib/file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2363,7 +2375,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include @@ -2386,7 +2398,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noinclude() + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include if there is a c++ style comment on top @@ -2415,7 +2427,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_veryFirstIn + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include if there is a c style comment on top @@ -2448,7 +2460,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_veryFirstIn + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase(testFiles, &factory, QStringList(TestIncludePaths::globalIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: If a "Qt Class" was not found by the locator, check the header files in the Qt @@ -2472,8 +2484,8 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_checkQSomet + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase(testFiles,&factory, - QStringList(CppTools::Tests::TestIncludePaths::globalQtCoreIncludePath())); + QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalQtCoreIncludePath()); + } /// Check: Move definition from header to cpp. @@ -2638,7 +2650,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory, QStringList(), 1); + QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check: Move definition from header to cpp (with namespace). @@ -2951,7 +2963,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_afterClass() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory, QStringList(), 1); + QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check if whitespace is respected for operator functions @@ -2998,6 +3010,39 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames2 QuickFixTestCase(singleDocument(original, expected), &factory); } +void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_macroUses() +{ + QByteArray original = + "#define CONST const\n" + "#define VOLATILE volatile\n" + "class Foo\n" + "{\n" + " int fu@nc(int a, int b) CONST VOLATILE\n" + " {\n" + " return 42;\n" + " }\n" + "};\n"; + QByteArray expected = + "#define CONST const\n" + "#define VOLATILE volatile\n" + "class Foo\n" + "{\n" + " int func(int a, int b) CONST VOLATILE;\n" + "};\n" + "\n" + "\n" + // const volatile become lowercase: QTCREATORBUG-12620 + "int Foo::func(int a, int b) const volatile\n" + "{\n" + " return 42;\n" + "}\n" + ; + + MoveFuncDefOutside factory; + QuickFixTestCase(singleDocument(original, expected), &factory, + ProjectPart::HeaderPaths(), 0, "QTCREATORBUG-12314"); +} + /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCpp() void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFunc() { @@ -3301,6 +3346,37 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_structWithAssignedVariable QuickFixTestCase(singleDocument(original, expected), &factory); } +void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_macroUses() +{ + QByteArray original = + "#define CONST const\n" + "#define VOLATILE volatile\n" + "class Foo\n" + "{\n" + " int func(int a, int b) CONST VOLATILE;\n" + "};\n" + "\n" + "\n" + "int Foo::fu@nc(int a, int b) CONST VOLATILE" + "{\n" + " return 42;\n" + "}\n"; + QByteArray expected = + "#define CONST const\n" + "#define VOLATILE volatile\n" + "class Foo\n" + "{\n" + " int func(int a, int b) CONST VOLATILE\n" + " {\n" + " return 42;\n" + " }\n" + "};\n\n\n\n"; + + MoveFuncDefToDecl factory; + QuickFixTestCase(singleDocument(original, expected), &factory, + ProjectPart::HeaderPaths(), 0, "QTCREATORBUG-12314"); +} + void CppEditorPlugin::test_quickfix_AssignToLocalVariable_templates() { diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 615e814104e..a898c8bb36b 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -74,10 +74,14 @@ class QuickFixTestCase : public TestCase public: QuickFixTestCase(const QList &theTestFiles, CppQuickFixFactory *factory, - const QStringList &includePaths = QStringList(), - int resultIndex = 0); + const CppTools::ProjectPart::HeaderPaths &includePaths = + CppTools::ProjectPart::HeaderPaths(), + int resultIndex = 0, + const QByteArray &expectedFailMessage = QByteArray()); ~QuickFixTestCase(); + static void run(const QList &theTestFiles, + CppQuickFixFactory *factory, const QString &incPath); private: QSharedPointer getFix(CppQuickFixFactory *factory, CPPEditorWidget *editorWidget, @@ -89,8 +93,8 @@ private: CppTools::CppCodeStylePreferences *m_cppCodeStylePreferences; QByteArray m_cppCodeStylePreferencesOriginalDelegateId; - QStringList m_includePathsToRestore; - bool m_restoreIncludePaths; + CppTools::ProjectPart::HeaderPaths m_headerPathsToRestore; + bool m_restoreHeaderPaths; }; QList singleDocument(const QByteArray &original, diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 109a63f565f..5b7e48a0074 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -1896,7 +1896,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa return; // find the include paths - QStringList includePaths; + ProjectPart::HeaderPaths headerPaths; CppModelManagerInterface *modelManager = CppModelManagerInterface::instance(); QList projectInfos = modelManager->projectInfos(); bool inProject = false; @@ -1905,14 +1905,14 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa foreach (const ProjectFile &file, part->files) { if (file.path == doc->fileName()) { inProject = true; - includePaths += part->includePaths; + headerPaths += part->headerPaths; } } } } if (!inProject) { // better use all include paths than none - includePaths = modelManager->includePaths(); + headerPaths = modelManager->headerPaths(); } // find a include file through the locator @@ -1933,10 +1933,10 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa if (fileInfo.path() == QFileInfo(doc->fileName()).path()) { shortestInclude = QLatin1Char('"') + fileInfo.fileName() + QLatin1Char('"'); } else { - foreach (const QString &includePath, includePaths) { - if (!fileName.startsWith(includePath)) + foreach (const ProjectPart::HeaderPath &headerPath, headerPaths) { + if (!fileName.startsWith(headerPath.path)) continue; - QString relativePath = fileName.mid(includePath.size()); + QString relativePath = fileName.mid(headerPath.path.size()); if (!relativePath.isEmpty() && relativePath.at(0) == QLatin1Char('/')) relativePath = relativePath.mid(1); if (shortestInclude.isEmpty() || relativePath.size() + 2 < shortestInclude.size()) @@ -1965,11 +1965,11 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa // otherwise, check for a header file with the same name in the Qt include paths } else { - foreach (const QString &includePath, includePaths) { - if (!includePath.contains(QLatin1String("/Qt"))) // "QtCore", "QtGui" etc... + foreach (const ProjectPart::HeaderPath &headerPath, headerPaths) { + if (!headerPath.path.contains(QLatin1String("/Qt"))) // "QtCore", "QtGui" etc... continue; - const QString headerPathCandidate = includePath + QLatin1Char('/') + className; + const QString headerPathCandidate = headerPath.path + QLatin1Char('/') + className; const QFileInfo fileInfo(headerPathCandidate); if (fileInfo.exists() && fileInfo.isFile()) { const QString include = QLatin1Char('<') + className + QLatin1Char('>'); diff --git a/src/plugins/cpptools/builtinindexingsupport.cpp b/src/plugins/cpptools/builtinindexingsupport.cpp index fc51ad12f90..20eac41a033 100644 --- a/src/plugins/cpptools/builtinindexingsupport.cpp +++ b/src/plugins/cpptools/builtinindexingsupport.cpp @@ -51,7 +51,7 @@ static void parse(QFutureInterface &future, bool processingHeaders = false; CppModelManager *cmm = CppModelManager::instance(); - const QStringList fallbackIncludePaths = cmm->includePaths(); + const ProjectPart::HeaderPaths fallbackHeaderPaths = cmm->headerPaths(); for (int i = 0; i < files.size(); ++i) { if (future.isPaused()) future.waitForResume(); @@ -71,10 +71,10 @@ static void parse(QFutureInterface &future, } QList parts = cmm->projectPart(fileName); - QStringList includePaths = parts.isEmpty() - ? fallbackIncludePaths - : parts.first()->includePaths; - sourceProcessor->setIncludePaths(includePaths); + ProjectPart::HeaderPaths headerPaths = parts.isEmpty() + ? fallbackHeaderPaths + : parts.first()->headerPaths; + sourceProcessor->setHeaderPaths(headerPaths); sourceProcessor->run(fileName); future.setProgressValue(files.size() - sourceProcessor->todo().size()); @@ -190,8 +190,7 @@ QFuture BuiltinIndexingSupport::refreshSourceFiles(const QStringList &sour CppSourceProcessor *preproc = CppModelManager::createSourceProcessor(); preproc->setDumpFileNameWhileParsing(m_dumpFileNameWhileParsing); preproc->setRevision(++m_revision); - preproc->setIncludePaths(mgr->includePaths()); - preproc->setFrameworkPaths(mgr->frameworkPaths()); + preproc->setHeaderPaths(mgr->headerPaths()); preproc->setWorkingCopy(workingCopy); QFuture result = QtConcurrent::run(&parse, preproc, sourceFiles); diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp index cdad0fdddf0..6d6b7487378 100644 --- a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp +++ b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp @@ -413,6 +413,18 @@ QString Utils::pathListToString(const QStringList &pathList) return result.join(QLatin1String("\n")); } +QString Utils::pathListToString(const ProjectPart::HeaderPaths &pathList) +{ + QStringList result; + foreach (const ProjectPart::HeaderPath &path, pathList) { + result << QString(QLatin1String("%1 (%2 path)")).arg( + QDir::toNativeSeparators(path.path), + path.isFrameworkPath() ? QLatin1String("framework") : QLatin1String("include") + ); + } + return result.join(QLatin1String("\n")); +} + QList Utils::snapshotToList(const CPlusPlus::Snapshot &snapshot) { QList documents; @@ -511,16 +523,14 @@ void Dumper::dumpProjectInfos( const QListincludePaths.isEmpty()) { - m_out << i3 << "Include Paths:{{{4\n"; - foreach (const QString &includePath, part->includePaths) - m_out << i4 << includePath << "\n"; - } - - if (!part->frameworkPaths.isEmpty()) { - m_out << i3 << "Framework Paths:{{{4\n"; - foreach (const QString &frameworkPath, part->frameworkPaths) - m_out << i4 << frameworkPath << "\n"; + if (!part->headerPaths.isEmpty()) { + m_out << i3 << "Header Paths:{{{4\n"; + foreach (const ProjectPart::HeaderPath &headerPath, part->headerPaths) + m_out << i4 << headerPath.path + << (headerPath.type == ProjectPart::HeaderPath::IncludePath + ? "(include path)" + : "(framework path)") + << "\n"; } if (!part->precompiledHeaders.isEmpty()) { @@ -582,18 +592,18 @@ void Dumper::dumpWorkingCopy(const CppModelManagerInterface::WorkingCopy &workin } } -void Dumper::dumpMergedEntities(const QStringList &mergedIncludePaths, - const QStringList &mergedFrameworkPaths, +void Dumper::dumpMergedEntities(const ProjectPart::HeaderPaths &mergedHeaderPaths, const QByteArray &mergedMacros) { m_out << "Merged Entities{{{1\n"; const QByteArray i2 = indent(2); const QByteArray i3 = indent(3); - m_out << i2 << "Merged Include Paths{{{2\n"; - dumpStringList(mergedIncludePaths, i3); - m_out << i2 << "Merged Framework Paths{{{2\n"; - dumpStringList(mergedFrameworkPaths, i3); + m_out << i2 << "Merged Header Paths{{{2\n"; + foreach (const ProjectPart::HeaderPath &hp, mergedHeaderPaths) + m_out << i3 << hp.path + << (hp.isFrameworkPath() ? " (framework path)" : " (include path)") + << "\n"; m_out << i2 << "Merged Defines{{{2\n"; m_out << mergedMacros; } diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.h b/src/plugins/cpptools/cppcodemodelinspectordumper.h index 2fe43d40a4d..b7ada3084d6 100644 --- a/src/plugins/cpptools/cppcodemodelinspectordumper.h +++ b/src/plugins/cpptools/cppcodemodelinspectordumper.h @@ -58,6 +58,7 @@ struct CPPTOOLS_EXPORT Utils static QString partsForFile(const QString &fileName); static QString unresolvedFileNameWithDelimiters(const CPlusPlus::Document::Include &include); static QString pathListToString(const QStringList &pathList); + static QString pathListToString(const ProjectPart::HeaderPaths &pathList); static QList snapshotToList(const CPlusPlus::Snapshot &snapshot); }; @@ -73,8 +74,7 @@ public: const QString &title, bool isGlobalSnapshot = false); void dumpWorkingCopy(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy); - void dumpMergedEntities(const QStringList &mergedIncludePaths, - const QStringList &mergedFrameworkPaths, + void dumpMergedEntities(const ProjectPart::HeaderPaths &mergedHeaderPaths, const QByteArray &mergedMacros); private: diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 51f33591019..a55968da4a9 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -105,7 +105,7 @@ public: = new CppCompletionAssistInterface(m_editorWidget->document(), m_position, m_editorWidget->baseTextDocument()->filePath(), ExplicitlyInvoked, m_snapshot, - QStringList(), QStringList()); + ProjectPart::HeaderPaths()); CppCompletionAssistProcessor processor; IAssistProposal *proposal = processor.perform(ai); if (!proposal) @@ -2263,6 +2263,24 @@ void CppToolsPlugin::test_completion_data() ) << _("n2.n1.t.") << (QStringList() << QLatin1String("foo") << QLatin1String("Foo")); + + QTest::newRow("lambda_parameter") << _( + "auto func = [](int arg1) { return @; };\n" + ) << _("ar") << (QStringList() + << QLatin1String("arg1")); + + QTest::newRow("default_arguments_for_class_templates_and_base_class_QTCREATORBUG-12605") << _( + "struct Foo { int foo; };\n" + "template \n" + "struct Derived : T {};\n" + "void fun() {\n" + " Derived<> derived;\n" + " @\n" + "}\n" + ) << _("derived.") << (QStringList() + << QLatin1String("Derived") + << QLatin1String("foo") + << QLatin1String("Foo")); } void CppToolsPlugin::test_completion_member_access_operator() diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index 10a3412c1b5..d1f1322223f 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -1139,30 +1139,23 @@ bool CppCompletionAssistProcessor::completeInclude(const QTextCursor &cursor) } // Make completion for all relevant includes - QStringList includePaths = m_interface->includePaths(); - const QString ¤tFilePath = QFileInfo(m_interface->fileName()).path(); - if (!includePaths.contains(currentFilePath)) - includePaths.append(currentFilePath); + ProjectPart::HeaderPaths headerPaths = m_interface->headerPaths(); + const ProjectPart::HeaderPath currentFilePath(QFileInfo(m_interface->fileName()).path(), + ProjectPart::HeaderPath::IncludePath); + if (!headerPaths.contains(currentFilePath)) + headerPaths.append(currentFilePath); const Core::MimeType mimeType = Core::MimeDatabase::findByType(QLatin1String("text/x-c++hdr")); const QStringList suffixes = mimeType.suffixes(); - foreach (const QString &includePath, includePaths) { - QString realPath = includePath; + foreach (const ProjectPart::HeaderPath &headerPath, headerPaths) { + QString realPath = headerPath.path; if (!directoryPrefix.isEmpty()) { realPath += QLatin1Char('/'); realPath += directoryPrefix; - } - completeInclude(realPath, suffixes); - } - - foreach (const QString &frameworkPath, m_interface->frameworkPaths()) { - QString realPath = frameworkPath; - if (!directoryPrefix.isEmpty()) { - realPath += QLatin1Char('/'); - realPath += directoryPrefix; - realPath += QLatin1String(".framework/Headers"); + if (headerPath.isFrameworkPath()) + realPath += QLatin1String(".framework/Headers"); } completeInclude(realPath, suffixes); } @@ -1969,8 +1962,7 @@ void CppCompletionAssistInterface::getCppSpecifics() const if (QSharedPointer updater = supp->snapshotUpdater()) { updater->update(m_workingCopy); m_snapshot = updater->snapshot(); - m_includePaths = updater->includePaths(); - m_frameworkPaths = updater->frameworkPaths(); + m_headerPaths = updater->headerPaths(); } } } diff --git a/src/plugins/cpptools/cppcompletionassist.h b/src/plugins/cpptools/cppcompletionassist.h index ed56a780c88..4ecabc98117 100644 --- a/src/plugins/cpptools/cppcompletionassist.h +++ b/src/plugins/cpptools/cppcompletionassist.h @@ -191,22 +191,20 @@ public: const QString &fileName, TextEditor::AssistReason reason, const CPlusPlus::Snapshot &snapshot, - const QStringList &includePaths, - const QStringList &frameworkPaths) + const ProjectPart::HeaderPaths &headerPaths) : TextEditor::DefaultAssistInterface(textDocument, position, fileName, reason) , m_editor(0) , m_isObjCEnabled(false) , m_gotCppSpecifics(true) , m_snapshot(snapshot) - , m_includePaths(includePaths) - , m_frameworkPaths(frameworkPaths) + , m_headerPaths(headerPaths) {} bool isObjCEnabled() const { return m_isObjCEnabled; } const CPlusPlus::Snapshot &snapshot() const { getCppSpecifics(); return m_snapshot; } - const QStringList &includePaths() const { getCppSpecifics(); return m_includePaths; } - const QStringList &frameworkPaths() const { getCppSpecifics(); return m_frameworkPaths; } + const ProjectPart::HeaderPaths &headerPaths() const + { getCppSpecifics(); return m_headerPaths; } private: void getCppSpecifics() const; @@ -216,8 +214,7 @@ private: mutable bool m_gotCppSpecifics; CppModelManagerInterface::WorkingCopy m_workingCopy; mutable CPlusPlus::Snapshot m_snapshot; - mutable QStringList m_includePaths; - mutable QStringList m_frameworkPaths; + mutable ProjectPart::HeaderPaths m_headerPaths; }; } // Internal diff --git a/src/plugins/cpptools/cpplocalsymbols.cpp b/src/plugins/cpptools/cpplocalsymbols.cpp index a6eac214a6a..e491589fc6e 100644 --- a/src/plugins/cpptools/cpplocalsymbols.cpp +++ b/src/plugins/cpptools/cpplocalsymbols.cpp @@ -39,12 +39,9 @@ namespace { class FindLocalSymbols: protected ASTVisitor { - Scope *_functionScope; - Document::Ptr _doc; - public: FindLocalSymbols(Document::Ptr doc) - : ASTVisitor(doc->translationUnit()), _doc(doc) + : ASTVisitor(doc->translationUnit()) { } // local and external uses. @@ -59,12 +56,10 @@ public: if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) { if (def->symbol) { - _functionScope = def->symbol; accept(ast); } } else if (ObjCMethodDeclarationAST *decl = ast->asObjCMethodDeclaration()) { if (decl->method_prototype->symbol) { - _functionScope = decl->method_prototype->symbol; accept(ast); } } @@ -180,6 +175,19 @@ protected: _scopeStack.removeLast(); } + virtual bool visit(LambdaExpressionAST *ast) + { + if (ast->lambda_declarator && ast->lambda_declarator->symbol) + enterScope(ast->lambda_declarator->symbol); + return true; + } + + virtual void endVisit(LambdaExpressionAST *ast) + { + if (ast->lambda_declarator && ast->lambda_declarator->symbol) + _scopeStack.removeLast(); + } + virtual bool visit(CompoundStatementAST *ast) { if (ast->symbol) diff --git a/src/plugins/cpptools/cpplocalsymbols_test.cpp b/src/plugins/cpptools/cpplocalsymbols_test.cpp new file mode 100644 index 00000000000..2969f21b112 --- /dev/null +++ b/src/plugins/cpptools/cpplocalsymbols_test.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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 "cpptoolsplugin.h" + +#include "cpplocalsymbols.h" +#include "cppsemanticinfo.h" + +#include +#include + +#include + +namespace { + +class FindFirstFunctionDefinition: protected CPlusPlus::ASTVisitor +{ +public: + FindFirstFunctionDefinition(CPlusPlus::TranslationUnit *translationUnit) + : ASTVisitor(translationUnit) + , m_definition(0) + {} + + CPlusPlus::FunctionDefinitionAST *operator()() + { + accept(translationUnit()->ast()); + return m_definition; + } + +private: + bool preVisit(CPlusPlus::AST *ast) + { + if (CPlusPlus::FunctionDefinitionAST *f = ast->asFunctionDefinition()) { + m_definition = f; + return false; + } + return true; + } + +private: + CPlusPlus::FunctionDefinitionAST *m_definition; +}; + +struct Result +{ + Result() : line(0), column(0), length(0) {} + Result(const QByteArray &name, unsigned line, unsigned column, unsigned length) + : name(name), line(line), column(column), length(length) + {} + + QByteArray name; + unsigned line; + unsigned column; + unsigned length; + + bool operator==(const Result &other) const + { + return name == other.name + && line == other.line + && column == other.column + && length == other.length; + } + + static Result fromHighlightingResult(const CPlusPlus::Symbol *symbol, + TextEditor::HighlightingResult result) + { + const QByteArray name = CPlusPlus::Overview().prettyName(symbol->name()).toLatin1(); + return Result(name, result.line, result.column, result.length); + } + + static QList fromLocalUses(CppTools::SemanticInfo::LocalUseMap localUses) + { + QList result; + + CppTools::SemanticInfo::LocalUseIterator it(localUses); + while (it.hasNext()) { + it.next(); + const CPlusPlus::Symbol *symbol = it.key(); + const QList &uses = it.value(); + foreach (const CppTools::SemanticInfo::Use &use, uses) + result << fromHighlightingResult(symbol, use); + } + + Utils::sort(result, [](const Result &r1, const Result &r2) -> bool { + if (r1.line == r2.line) + return r1.column < r2.column; + return r1.line < r2.line; + }); + return result; + } +}; + +} // anonymous namespace + +Q_DECLARE_METATYPE(Result) +Q_DECLARE_METATYPE(QList) + +QT_BEGIN_NAMESPACE +namespace QTest { + template<> + char *toString(const Result &result) + { + QByteArray ba = "Result("; + ba += "_(\"" + result.name + "\"), "; + ba += QByteArray::number(result.line) + ", "; + ba += QByteArray::number(result.column) + ", "; + ba += QByteArray::number(result.length) + ")"; + return qstrdup(ba.data()); + } +} +QT_END_NAMESPACE + +namespace CppTools { +namespace Internal { + +void CppToolsPlugin::test_cpplocalsymbols_data() +{ + QTest::addColumn("source"); + QTest::addColumn>("expectedUses"); + + typedef QByteArray _; + + QTest::newRow("basic") + << _("int f(int arg)\n" + "{\n" + " int local;\n" + " g(&local);\n" + " return local + arg;\n" + "}\n") + << (QList() + << Result(_("arg"), 0, 10, 3) + << Result(_("local"), 2, 9, 5) + << Result(_("local"), 3, 8, 5) + << Result(_("local"), 4, 12, 5) + << Result(_("arg"), 4, 20, 3)); + + QTest::newRow("lambda") + << _("void f()\n" + "{\n" + " auto func = [](int arg) { return arg; };\n" + " func(1);\n" + "}\n") + << (QList() + << Result(_("func"), 2, 10, 4) + << Result(_("arg"), 2, 24, 3) + << Result(_("arg"), 2, 38, 3) + << Result(_("func"), 3, 5, 4)); +} + +void CppToolsPlugin::test_cpplocalsymbols() +{ + QFETCH(QByteArray, source); + QFETCH(QList, expectedUses); + + CPlusPlus::Document::Ptr document = CPlusPlus::Document::create(QLatin1String("test.cpp")); + document->setUtf8Source(source); + document->check(); + QVERIFY(document->diagnosticMessages().isEmpty()); + QVERIFY(document->translationUnit()); + QVERIFY(document->translationUnit()->ast()); + QVERIFY(document->globalNamespace()); + FindFirstFunctionDefinition find(document->translationUnit()); + CPlusPlus::DeclarationAST *functionDefinition = find(); + + LocalSymbols localSymbols(document, functionDefinition); + + const QList actualUses = Result::fromLocalUses(localSymbols.uses); +// foreach (const Result &result, actualUses) +// qDebug() << QTest::toString(result); + QCOMPARE(actualUses, expectedUses); +} + +} // namespace Internal +} // namespace CppTools diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 25300b1d1d1..8924f64cd89 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -298,8 +298,7 @@ void CppModelManager::ensureUpdated() return; m_projectFiles = internalProjectFiles(); - m_includePaths = internalIncludePaths(); - m_frameworkPaths = internalFrameworkPaths(); + m_headerPaths = internalHeaderPaths(); m_definedMacros = internalDefinedMacros(); m_dirty = false; } @@ -320,34 +319,23 @@ QStringList CppModelManager::internalProjectFiles() const return files; } -QStringList CppModelManager::internalIncludePaths() const +ProjectPart::HeaderPaths CppModelManager::internalHeaderPaths() const { - QStringList includePaths; + ProjectPart::HeaderPaths headerPaths; QMapIterator it(m_projectToProjectsInfo); while (it.hasNext()) { it.next(); const ProjectInfo pinfo = it.value(); - foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) - foreach (const QString &path, part->includePaths) - includePaths.append(CppSourceProcessor::cleanPath(path)); + foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) { + foreach (const ProjectPart::HeaderPath &path, part->headerPaths) { + const ProjectPart::HeaderPath hp(CppSourceProcessor::cleanPath(path.path), + path.type); + if (!headerPaths.contains(hp)) + headerPaths += hp; + } + } } - includePaths.removeDuplicates(); - return includePaths; -} - -QStringList CppModelManager::internalFrameworkPaths() const -{ - QStringList frameworkPaths; - QMapIterator it(m_projectToProjectsInfo); - while (it.hasNext()) { - it.next(); - const ProjectInfo pinfo = it.value(); - foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) - foreach (const QString &path, part->frameworkPaths) - frameworkPaths.append(CppSourceProcessor::cleanPath(path)); - } - frameworkPaths.removeDuplicates(); - return frameworkPaths; + return headerPaths; } static void addUnique(const QList &defs, QByteArray *macros, QSet *alreadyIn) @@ -396,7 +384,7 @@ void CppModelManager::dumpModelManagerConfiguration(const QString &logFileId) dumper.dumpSnapshot(globalSnapshot, globalSnapshotTitle, /*isGlobalSnapshot=*/ true); dumper.dumpWorkingCopy(workingCopy()); ensureUpdated(); - dumper.dumpMergedEntities(m_includePaths, m_frameworkPaths, m_definedMacros); + dumper.dumpMergedEntities(m_headerPaths, m_definedMacros); } void CppModelManager::addExtraEditorSupport(AbstractEditorSupport *editorSupport) @@ -595,8 +583,7 @@ public: bool configurationChanged() const { return definesChanged() - || m_new.includePaths() != m_old.includePaths() - || m_new.frameworkPaths() != m_old.frameworkPaths(); + || m_new.headerPaths() != m_old.headerPaths(); } bool nothingChanged() const @@ -761,8 +748,7 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart() const ProjectPart::Ptr part(new ProjectPart); part->projectDefines = m_definedMacros; - part->includePaths = m_includePaths; - part->frameworkPaths = m_frameworkPaths; + part->headerPaths = m_headerPaths; part->cVersion = ProjectPart::C11; part->cxxVersion = ProjectPart::CXX11; part->cxxExtensions = ProjectPart::AllExtensions; diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index bbdb2d6e79d..7936019a140 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -128,22 +128,16 @@ public: return m_projectFiles; } - QStringList includePaths() + ProjectPart::HeaderPaths headerPaths() { ensureUpdated(); - return m_includePaths; + return m_headerPaths; } // Use this *only* for auto tests - void setIncludePaths(const QStringList &includePaths) + void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths) { - m_includePaths = includePaths; - } - - QStringList frameworkPaths() - { - ensureUpdated(); - return m_frameworkPaths; + m_headerPaths = headerPaths; } QByteArray definedMacros() @@ -187,8 +181,7 @@ private: void ensureUpdated(); QStringList internalProjectFiles() const; - QStringList internalIncludePaths() const; - QStringList internalFrameworkPaths() const; + ProjectPart::HeaderPaths internalHeaderPaths() const; QByteArray internalDefinedMacros() const; void dumpModelManagerConfiguration(const QString &logFileId); @@ -210,8 +203,7 @@ private: // The members below are cached/(re)calculated from the projects and/or their project parts bool m_dirty; QStringList m_projectFiles; - QStringList m_includePaths; - QStringList m_frameworkPaths; + ProjectPart::HeaderPaths m_headerPaths; QByteArray m_definedMacros; // Editor integration diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index 4aef1c892b6..3ca3e3d49dd 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -220,23 +220,24 @@ void CppToolsPlugin::test_modelmanager_paths_are_clean() ProjectInfo pi = mm->projectInfo(project); QCOMPARE(pi.project().data(), project); + typedef ProjectPart::HeaderPath HeaderPath; + ProjectPart::Ptr part(new ProjectPart); part->cxxVersion = ProjectPart::CXX98; part->qtVersion = ProjectPart::Qt5; part->projectDefines = QByteArray("#define OH_BEHAVE -1\n"); - part->includePaths = QStringList() << testDataDir.includeDir(false); - part->frameworkPaths = QStringList() << testDataDir.frameworksDir(false); + part->headerPaths = QList() + << HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath) + << HeaderPath(testDataDir.frameworksDir(false), HeaderPath::FrameworkPath); pi.appendProjectPart(part); mm->updateProjectInfo(pi); - QStringList includePaths = mm->includePaths(); - QCOMPARE(includePaths.size(), 1); - QVERIFY(includePaths.contains(testDataDir.includeDir())); - - QStringList frameworkPaths = mm->frameworkPaths(); - QCOMPARE(frameworkPaths.size(), 1); - QVERIFY(frameworkPaths.contains(testDataDir.frameworksDir())); + QList headerPaths = mm->headerPaths(); + QCOMPARE(headerPaths.size(), 2); + QVERIFY(headerPaths.contains(HeaderPath(testDataDir.includeDir(), HeaderPath::IncludePath))); + QVERIFY(headerPaths.contains(HeaderPath(testDataDir.frameworksDir(), + HeaderPath::FrameworkPath))); } /// Check: Frameworks headers are resolved. @@ -254,12 +255,15 @@ void CppToolsPlugin::test_modelmanager_framework_headers() ProjectInfo pi = mm->projectInfo(project); QCOMPARE(pi.project().data(), project); + typedef ProjectPart::HeaderPath HeaderPath; + ProjectPart::Ptr part(new ProjectPart); part->cxxVersion = ProjectPart::CXX98; part->qtVersion = ProjectPart::Qt5; part->projectDefines = QByteArray("#define OH_BEHAVE -1\n"); - part->includePaths << testDataDir.includeDir(); - part->frameworkPaths << testDataDir.frameworksDir(); + part->headerPaths = QList() + << HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath) + << HeaderPath(testDataDir.frameworksDir(false), HeaderPath::FrameworkPath); const QString &source = testDataDir.fileFromSourcesDir( _("test_modelmanager_framework_headers.cpp")); part->files << ProjectFile(source, ProjectFile::CXXSource); @@ -303,11 +307,14 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() ProjectInfo pi = mm->projectInfo(project); QCOMPARE(pi.project().data(), project); + typedef ProjectPart::HeaderPath HeaderPath; + ProjectPart::Ptr part(new ProjectPart); part->cxxVersion = ProjectPart::CXX98; part->qtVersion = ProjectPart::Qt5; part->projectDefines = QByteArray("#define OH_BEHAVE -1\n"); - part->includePaths = QStringList() << testDataDir.includeDir(false); + part->headerPaths = QList() + << HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath); part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); pi.appendProjectPart(part); @@ -806,6 +813,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project() Project *project = helper.createProject(_("test_modelmanager_defines_per_project")); + typedef ProjectPart::HeaderPath HeaderPath; + ProjectPart::Ptr part1(new ProjectPart); part1->projectFile = QLatin1String("project1.projectfile"); part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource)); @@ -813,7 +822,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project() part1->cxxVersion = ProjectPart::CXX11; part1->qtVersion = ProjectPart::NoQt; part1->projectDefines = QByteArray("#define SUB1\n"); - part1->includePaths = QStringList() << testDataDirectory.includeDir(false); + part1->headerPaths = QList() + << HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath); ProjectPart::Ptr part2(new ProjectPart); part2->projectFile = QLatin1String("project1.projectfile"); @@ -822,7 +832,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project() part2->cxxVersion = ProjectPart::CXX11; part2->qtVersion = ProjectPart::NoQt; part2->projectDefines = QByteArray("#define SUB2\n"); - part2->includePaths = QStringList() << testDataDirectory.includeDir(false); + part2->headerPaths = QList() + << HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath); ProjectInfo pi = mm->projectInfo(project); pi.appendProjectPart(part1); @@ -877,6 +888,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch() Project *project = helper.createProject(_("test_modelmanager_defines_per_project_pch")); + typedef ProjectPart::HeaderPath HeaderPath; + ProjectPart::Ptr part1(new ProjectPart); part1->projectFile = QLatin1String("project1.projectfile"); part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource)); @@ -884,7 +897,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch() part1->cxxVersion = ProjectPart::CXX11; part1->qtVersion = ProjectPart::NoQt; part1->precompiledHeaders.append(pch1File); - part1->includePaths = QStringList() << testDataDirectory.includeDir(false); + part1->headerPaths = QList() + << HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath); ProjectPart::Ptr part2(new ProjectPart); part2->projectFile = QLatin1String("project2.projectfile"); @@ -893,7 +907,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch() part2->cxxVersion = ProjectPart::CXX11; part2->qtVersion = ProjectPart::NoQt; part2->precompiledHeaders.append(pch2File); - part2->includePaths = QStringList() << testDataDirectory.includeDir(false); + part2->headerPaths = QList() + << HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath); ProjectInfo pi = mm->projectInfo(project); pi.appendProjectPart(part1); @@ -949,19 +964,23 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor() Project *project = helper.createProject(_("test_modelmanager_defines_per_editor")); + typedef ProjectPart::HeaderPath HeaderPath; + ProjectPart::Ptr part1(new ProjectPart); part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource)); part1->files.append(ProjectFile(header, ProjectFile::CXXHeader)); part1->cxxVersion = ProjectPart::CXX11; part1->qtVersion = ProjectPart::NoQt; - part1->includePaths = QStringList() << testDataDirectory.includeDir(false); + part1->headerPaths = QList() + << HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath); ProjectPart::Ptr part2(new ProjectPart); part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource)); part2->files.append(ProjectFile(header, ProjectFile::CXXHeader)); part2->cxxVersion = ProjectPart::CXX11; part2->qtVersion = ProjectPart::NoQt; - part2->includePaths = QStringList() << testDataDirectory.includeDir(false); + part2->headerPaths = QList() + << HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath); ProjectInfo pi = mm->projectInfo(project); pi.appendProjectPart(part1); diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.cpp b/src/plugins/cpptools/cppmodelmanagerinterface.cpp index 5b31d4a2a25..8c79e3d0dab 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.cpp +++ b/src/plugins/cpptools/cppmodelmanagerinterface.cpp @@ -154,12 +154,12 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc, cWarningFlags = tc->warningFlags(cflags); cxxWarningFlags = tc->warningFlags(cxxflags); - const QList headers = tc->systemHeaderPaths(cxxflags, sysRoot); - foreach (const HeaderPath &header, headers) - if (header.kind() == HeaderPath::FrameworkHeaderPath) - frameworkPaths << header.path(); - else - includePaths << header.path(); + const QList headers = tc->systemHeaderPaths(cxxflags, sysRoot); + foreach (const ProjectExplorer::HeaderPath &header, headers) { + headerPaths << HeaderPath(header.path(), + header.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath + ? HeaderPath::FrameworkPath : HeaderPath::IncludePath); + } toolchainDefines = tc->predefinedMacros(cxxflags); } @@ -187,8 +187,7 @@ CppModelManagerInterface *CppModelManagerInterface::instance() void CppModelManagerInterface::ProjectInfo::clearProjectParts() { m_projectParts.clear(); - m_includePaths.clear(); - m_frameworkPaths.clear(); + m_headerPaths.clear(); m_sourceFiles.clear(); m_defines.clear(); } @@ -200,17 +199,16 @@ void CppModelManagerInterface::ProjectInfo::appendProjectPart(const ProjectPart: m_projectParts.append(part); - // Update include paths - QSet incs = QSet::fromList(m_includePaths); - foreach (const QString &ins, part->includePaths) - incs.insert(ins); - m_includePaths = incs.toList(); + typedef ProjectPart::HeaderPath HeaderPath; - // Update framework paths - QSet frms = QSet::fromList(m_frameworkPaths); - foreach (const QString &frm, part->frameworkPaths) - frms.insert(frm); - m_frameworkPaths = frms.toList(); + // Update header paths + QSet incs = QSet::fromList(m_headerPaths); + foreach (const HeaderPath &hp, part->headerPaths) { + if (!incs.contains(hp)) { + incs.insert(hp); + m_headerPaths += hp; + } + } // Update source files QSet srcs = QSet::fromList(m_sourceFiles); diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h index 608f199f3c6..bd40a9de01d 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.h +++ b/src/plugins/cpptools/cppmodelmanagerinterface.h @@ -101,6 +101,27 @@ public: typedef QSharedPointer Ptr; + struct HeaderPath { + enum Type { InvalidPath, IncludePath, FrameworkPath }; + + public: + QString path; + Type type; + + HeaderPath(): type(InvalidPath) {} + HeaderPath(const QString &path, Type type): path(path), type(type) {} + + bool isValid() const { return type != InvalidPath; } + bool isFrameworkPath() const { return type == FrameworkPath; } + + bool operator==(const HeaderPath &other) const + { return path == other.path && type == other.type; } + + bool operator!=(const HeaderPath &other) const + { return !(*this == other); } + }; + typedef QList HeaderPaths; + public: QString displayName; QString projectFile; @@ -109,8 +130,7 @@ public: QString projectConfigFile; // currently only used by the Generic Project Manager QByteArray projectDefines; QByteArray toolchainDefines; - QStringList includePaths; - QStringList frameworkPaths; + QList headerPaths; QStringList precompiledHeaders; CVersion cVersion; CXXVersion cxxVersion; @@ -120,6 +140,9 @@ public: ProjectExplorer::ToolChain::WarningFlags cxxWarningFlags; }; +inline uint qHash(const ProjectPart::HeaderPath &key, uint seed = 0) +{ return ((qHash(key.path) << 2) | key.type) ^ seed; } + class CPPTOOLS_EXPORT CppModelManagerInterface : public CPlusPlus::CppModelManagerBase { Q_OBJECT @@ -159,11 +182,8 @@ public: void clearProjectParts(); void appendProjectPart(const ProjectPart::Ptr &part); - const QStringList includePaths() const - { return m_includePaths; } - - const QStringList frameworkPaths() const - { return m_frameworkPaths; } + const ProjectPart::HeaderPaths headerPaths() const + { return m_headerPaths; } const QStringList sourceFiles() const { return m_sourceFiles; } @@ -175,8 +195,7 @@ public: QPointer m_project; QList m_projectParts; // The members below are (re)calculated from the project parts once a part is appended. - QStringList m_includePaths; - QStringList m_frameworkPaths; + ProjectPart::HeaderPaths m_headerPaths; QStringList m_sourceFiles; QByteArray m_defines; }; @@ -266,11 +285,10 @@ public: virtual void setIndexingSupport(CppTools::CppIndexingSupport *indexingSupport) = 0; virtual CppIndexingSupport *indexingSupport() = 0; - virtual void setIncludePaths(const QStringList &includePaths) = 0; + virtual void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths) = 0; virtual void enableGarbageCollector(bool enable) = 0; - virtual QStringList includePaths() = 0; - virtual QStringList frameworkPaths() = 0; + virtual ProjectPart::HeaderPaths headerPaths() = 0; virtual QByteArray definedMacros() = 0; signals: diff --git a/src/plugins/cpptools/cppsnapshotupdater.cpp b/src/plugins/cpptools/cppsnapshotupdater.cpp index 63dc943d962..60c8d3e4146 100644 --- a/src/plugins/cpptools/cppsnapshotupdater.cpp +++ b/src/plugins/cpptools/cppsnapshotupdater.cpp @@ -57,8 +57,7 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) CppModelManager *modelManager = dynamic_cast(CppModelManagerInterface::instance()); QByteArray configFile = modelManager->codeModelConfiguration(); - QStringList includePaths; - QStringList frameworkPaths; + ProjectPart::HeaderPaths headerPaths; QStringList precompiledHeaders; QString projectConfigFile; @@ -72,8 +71,7 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) if (m_projectPart) { configFile += m_projectPart->toolchainDefines; configFile += m_projectPart->projectDefines; - includePaths = m_projectPart->includePaths; - frameworkPaths = m_projectPart->frameworkPaths; + headerPaths = m_projectPart->headerPaths; projectConfigFile = m_projectPart->projectConfigFile; if (m_usePrecompiledHeaders) precompiledHeaders = m_projectPart->precompiledHeaders; @@ -91,13 +89,8 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) m_editorDefinesChangedSinceLastUpdate = false; } - if (includePaths != m_includePaths) { - m_includePaths = includePaths; - invalidateSnapshot = true; - } - - if (frameworkPaths != m_frameworkPaths) { - m_frameworkPaths = frameworkPaths; + if (headerPaths != m_headerPaths) { + m_headerPaths = headerPaths; invalidateSnapshot = true; } @@ -174,8 +167,7 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) globalSnapshot.remove(fileInEditor()); sourceProcessor.setGlobalSnapshot(globalSnapshot); sourceProcessor.setWorkingCopy(workingCopy); - sourceProcessor.setIncludePaths(m_includePaths); - sourceProcessor.setFrameworkPaths(m_frameworkPaths); + sourceProcessor.setHeaderPaths(m_headerPaths); sourceProcessor.run(configurationFileName); if (!m_projectConfigFile.isEmpty()) sourceProcessor.run(m_projectConfigFile); @@ -218,16 +210,10 @@ Snapshot SnapshotUpdater::snapshot() const return m_snapshot; } -QStringList SnapshotUpdater::includePaths() const +ProjectPart::HeaderPaths SnapshotUpdater::headerPaths() const { QMutexLocker locker(&m_mutex); - return m_includePaths; -} - -QStringList SnapshotUpdater::frameworkPaths() const -{ - QMutexLocker locker(&m_mutex); - return m_frameworkPaths; + return m_headerPaths; } ProjectPart::Ptr SnapshotUpdater::currentProjectPart() const diff --git a/src/plugins/cpptools/cppsnapshotupdater.h b/src/plugins/cpptools/cppsnapshotupdater.h index 92741cf006d..b7d786f3ed5 100644 --- a/src/plugins/cpptools/cppsnapshotupdater.h +++ b/src/plugins/cpptools/cppsnapshotupdater.h @@ -56,8 +56,7 @@ public: CPlusPlus::Document::Ptr document() const; CPlusPlus::Snapshot snapshot() const; - QStringList includePaths() const; - QStringList frameworkPaths() const; + ProjectPart::HeaderPaths headerPaths() const; ProjectPart::Ptr currentProjectPart() const; void setProjectPart(ProjectPart::Ptr projectPart); @@ -76,8 +75,7 @@ private: QByteArray m_configFile; bool m_editorDefinesChangedSinceLastUpdate; QByteArray m_editorDefines; - QStringList m_includePaths; - QStringList m_frameworkPaths; + ProjectPart::HeaderPaths m_headerPaths; QString m_projectConfigFile; QStringList m_precompiledHeaders; CPlusPlus::Snapshot m_snapshot; diff --git a/src/plugins/cpptools/cppsourceprocessor.cpp b/src/plugins/cpptools/cppsourceprocessor.cpp index 64fa8dca0b7..47986331b37 100644 --- a/src/plugins/cpptools/cppsourceprocessor.cpp +++ b/src/plugins/cpptools/cppsourceprocessor.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -98,38 +99,20 @@ void CppSourceProcessor::setRevision(unsigned revision) void CppSourceProcessor::setWorkingCopy(const CppModelManagerInterface::WorkingCopy &workingCopy) { m_workingCopy = workingCopy; } -void CppSourceProcessor::setIncludePaths(const QStringList &includePaths) +void CppSourceProcessor::setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths) { - m_includePaths.clear(); + m_headerPaths.clear(); - for (int i = 0; i < includePaths.size(); ++i) { - const QString &path = includePaths.at(i); + for (int i = 0, ei = headerPaths.size(); i < ei; ++i) { + const ProjectPart::HeaderPath &path = headerPaths.at(i); - 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(cleanPath(path)); + if (path.type == ProjectPart::HeaderPath::IncludePath) + m_headerPaths.append(ProjectPart::HeaderPath(cleanPath(path.path), path.type)); + else + addFrameworkPath(path); } } -void CppSourceProcessor::setFrameworkPaths(const QStringList &frameworkPaths) -{ - m_frameworkPaths.clear(); - foreach (const QString &frameworkPath, frameworkPaths) - addFrameworkPath(frameworkPath); -} - // Add the given framework path, and expand private frameworks. // // Example: @@ -137,16 +120,19 @@ void CppSourceProcessor::setFrameworkPaths(const QStringList &frameworkPaths) // has private frameworks in: // /ApplicationServices.framework/Frameworks // if the "Frameworks" folder exists inside the top level framework. -void CppSourceProcessor::addFrameworkPath(const QString &frameworkPath) +void CppSourceProcessor::addFrameworkPath(const ProjectPart::HeaderPath &frameworkPath) { + QTC_ASSERT(frameworkPath.isFrameworkPath(), return); + // The algorithm below is a bit too eager, but that's because we're not getting // in the frameworks we're linking against. If we would have that, then we could // add only those private frameworks. - const QString cleanFrameworkPath = cleanPath(frameworkPath); - if (!m_frameworkPaths.contains(cleanFrameworkPath)) - m_frameworkPaths.append(cleanFrameworkPath); + const ProjectPart::HeaderPath cleanFrameworkPath(cleanPath(frameworkPath.path), + frameworkPath.type); + if (!m_headerPaths.contains(cleanFrameworkPath)) + m_headerPaths.append(cleanFrameworkPath); - const QDir frameworkDir(cleanFrameworkPath); + const QDir frameworkDir(cleanFrameworkPath.path); const QStringList filter = QStringList() << QLatin1String("*.framework"); foreach (const QFileInfo &framework, frameworkDir.entryInfoList(filter)) { if (!framework.isDir()) @@ -154,7 +140,8 @@ void CppSourceProcessor::addFrameworkPath(const QString &frameworkPath) const QFileInfo privateFrameworks(framework.absoluteFilePath(), QLatin1String("Frameworks")); if (privateFrameworks.exists() && privateFrameworks.isDir()) - addFrameworkPath(privateFrameworks.absoluteFilePath()); + addFrameworkPath(ProjectPart::HeaderPath(privateFrameworks.absoluteFilePath(), + frameworkPath.type)); } } @@ -259,8 +246,10 @@ QString CppSourceProcessor::resolveFile_helper(const QString &fileName, IncludeT // searching as if this would be a global include. } - foreach (const QString &includePath, m_includePaths) { - const QString path = includePath + fileName; + foreach (const ProjectPart::HeaderPath &headerPath, m_headerPaths) { + if (headerPath.isFrameworkPath()) + continue; + const QString path = headerPath.path + fileName; if (m_workingCopy.contains(path) || checkFile(path)) return path; } @@ -271,8 +260,10 @@ QString CppSourceProcessor::resolveFile_helper(const QString &fileName, IncludeT const QString name = frameworkName + QLatin1String(".framework/Headers/") + fileName.mid(index + 1); - foreach (const QString &frameworkPath, m_frameworkPaths) { - const QString path = frameworkPath + name; + foreach (const ProjectPart::HeaderPath &headerPath, m_headerPaths) { + if (!headerPath.isFrameworkPath()) + continue; + const QString path = headerPath.path + name; if (checkFile(path)) return path; } diff --git a/src/plugins/cpptools/cppsourceprocessor.h b/src/plugins/cpptools/cppsourceprocessor.h index 2b8aed6acb2..e10d1438163 100644 --- a/src/plugins/cpptools/cppsourceprocessor.h +++ b/src/plugins/cpptools/cppsourceprocessor.h @@ -40,8 +40,7 @@ public: void setRevision(unsigned revision); void setWorkingCopy(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy); - void setIncludePaths(const QStringList &includePaths); - void setFrameworkPaths(const QStringList &frameworkPaths); + void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths); void setTodo(const QStringList &files); void run(const QString &fileName); @@ -54,7 +53,7 @@ public: void setGlobalSnapshot(const CPlusPlus::Snapshot &snapshot) { m_globalSnapshot = snapshot; } private: - void addFrameworkPath(const QString &frameworkPath); + void addFrameworkPath(const ProjectPart::HeaderPath &frameworkPath); CPlusPlus::Document::Ptr switchCurrentDocument(CPlusPlus::Document::Ptr doc); @@ -90,9 +89,8 @@ private: bool m_dumpFileNameWhileParsing; CPlusPlus::Environment m_env; CPlusPlus::Preprocessor m_preprocess; - QStringList m_includePaths; + ProjectPart::HeaderPaths m_headerPaths; CppTools::CppModelManagerInterface::WorkingCopy m_workingCopy; - QStringList m_frameworkPaths; QSet m_included; CPlusPlus::Document::Ptr m_currentDoc; QSet m_todo; diff --git a/src/plugins/cpptools/cppsourceprocessor_test.cpp b/src/plugins/cpptools/cppsourceprocessor_test.cpp index 57974295f16..db7983cbf31 100644 --- a/src/plugins/cpptools/cppsourceprocessor_test.cpp +++ b/src/plugins/cpptools/cppsourceprocessor_test.cpp @@ -71,7 +71,9 @@ public: QScopedPointer sourceProcessor( CppModelManager::createSourceProcessor()); - sourceProcessor->setIncludePaths(QStringList(TestIncludePaths::directoryOfTestFile())); + const ProjectPart::HeaderPath hp(TestIncludePaths::directoryOfTestFile(), + ProjectPart::HeaderPath::IncludePath); + sourceProcessor->setHeaderPaths(ProjectPart::HeaderPaths() << hp); sourceProcessor->run(fileName); Document::Ptr document = m_cmm->document(fileName); diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index e528f3e3d6c..451be672256 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -128,6 +128,7 @@ equals(TEST, 1) { cppcodegen_test.cpp \ cppcompletion_test.cpp \ cppheadersource_test.cpp \ + cpplocalsymbols_test.cpp \ cpplocatorfilter_test.cpp \ cppmodelmanager_test.cpp \ cpppointerdeclarationformatter_test.cpp \ diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 53fc46f23c0..92c4b303910 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -87,6 +87,7 @@ QtcPlugin { "cppcodegen_test.cpp", "cppcompletion_test.cpp", "cppheadersource_test.cpp", + "cpplocalsymbols_test.cpp", "cpplocatorfilter_test.cpp", "cppmodelmanager_test.cpp", "cpppointerdeclarationformatter_test.cpp", diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index a3e137c640e..3d54eb0cdee 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -162,6 +162,9 @@ private slots: void test_typehierarchy_data(); void test_typehierarchy(); + void test_cpplocalsymbols_data(); + void test_cpplocalsymbols(); + void test_includeGroups_detectIncludeGroupsByNewLines(); void test_includeGroups_detectIncludeGroupsByIncludeDir(); void test_includeGroups_detectIncludeGroupsByIncludeType(); diff --git a/src/plugins/cpptools/includeutils.cpp b/src/plugins/cpptools/includeutils.cpp index a01fa5a9b87..490e9fcb799 100644 --- a/src/plugins/cpptools/includeutils.cpp +++ b/src/plugins/cpptools/includeutils.cpp @@ -518,7 +518,10 @@ static QList includesForSource(const QByteArray &source) CppModelManager *cmm = CppModelManager::instance(); cmm->GC(); QScopedPointer sourceProcessor(CppModelManager::createSourceProcessor()); - sourceProcessor->setIncludePaths(QStringList(TestIncludePaths::globalIncludePath())); + sourceProcessor->setHeaderPaths(ProjectPart::HeaderPaths() + << ProjectPart::HeaderPath( + TestIncludePaths::globalIncludePath(), + ProjectPart::HeaderPath::IncludePath)); sourceProcessor->run(fileName); Document::Ptr document = cmm->document(fileName); diff --git a/src/plugins/cpptools/modelmanagertesthelper.cpp b/src/plugins/cpptools/modelmanagertesthelper.cpp index b53cd405062..efcf81e4b0a 100644 --- a/src/plugins/cpptools/modelmanagertesthelper.cpp +++ b/src/plugins/cpptools/modelmanagertesthelper.cpp @@ -87,8 +87,7 @@ void ModelManagerTestHelper::verifyClean() assert(mm); QVERIFY(mm->projectInfos().isEmpty()); - QVERIFY(mm->includePaths().isEmpty()); - QVERIFY(mm->frameworkPaths().isEmpty()); + QVERIFY(mm->headerPaths().isEmpty()); QVERIFY(mm->definedMacros().isEmpty()); QVERIFY(mm->projectFiles().isEmpty()); QVERIFY(mm->snapshot().isEmpty()); diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index bdeff938c2d..1614486ca01 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -34,6 +34,7 @@ #include "debuggercore.h" #include "debuggerengine.h" #include "debuggerstringutils.h" +#include "simplifytype.h" #include #include @@ -593,7 +594,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const case 1: if (role == Qt::DisplayRole) { if (!response.functionName.isEmpty()) - return response.functionName; + return simplifyType(response.functionName); if (!data.functionName.isEmpty()) return data.functionName; if (data.type == BreakpointAtMain diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index 967dd010570..8fbfcf53ff2 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -184,7 +184,7 @@ QVariantMap DebuggerItem::toMap() const QVariantMap data; data.insert(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME), m_displayName); data.insert(QLatin1String(DEBUGGER_INFORMATION_ID), m_id); - data.insert(QLatin1String(DEBUGGER_INFORMATION_COMMAND), m_command.toUserOutput()); + data.insert(QLatin1String(DEBUGGER_INFORMATION_COMMAND), m_command.toString()); data.insert(QLatin1String(DEBUGGER_INFORMATION_ENGINETYPE), int(m_engineType)); data.insert(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED), m_isAutoDetected); data.insert(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTION_SOURCE), m_autoDetectionSource); diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index 9fa40c2fa02..05a6b428ea8 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -117,7 +117,7 @@ DebuggerItemManager::DebuggerItemManager(QObject *parent) : QObject(parent) { m_instance = this; - m_writer = new PersistentSettingsWriter(userSettingsFileName(), QLatin1String("QtCreatorDebugger")); + m_writer = new PersistentSettingsWriter(userSettingsFileName(), QLatin1String("QtCreatorDebuggers")); connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), this, SLOT(saveDebuggers())); } @@ -297,6 +297,8 @@ void DebuggerItemManager::readLegacyDebuggers(const FileName &file) if (fn == QLatin1String("auto")) continue; FileName command = FileName::fromUserInput(fn); + if (!command.toFileInfo().exists()) + continue; if (findByCommand(command)) continue; DebuggerItem item; diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp index 5cfdfba1f89..e7cb80c7c4b 100644 --- a/src/plugins/debugger/debuggeroptionspage.cpp +++ b/src/plugins/debugger/debuggeroptionspage.cpp @@ -159,7 +159,7 @@ void DebuggerItemConfigWidget::setItem(const DebuggerItem &item) m_displayNameLineEdit->setEnabled(!item.isAutoDetected()); m_displayNameLineEdit->setText(item.displayName()); - m_binaryChooser->setEnabled(!item.isAutoDetected()); + m_binaryChooser->setReadOnly(item.isAutoDetected()); m_binaryChooser->setFileName(item.command()); QString text; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 3b8e2bc3661..ac39ec1cadd 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2322,12 +2322,15 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_hiddenStopAction->setAction(m_interruptAction); m_localsAndExpressionsWindow->setShowLocals(false); } else if (state == DebuggerFinished) { + ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance(); + Project *project = SessionManager::startupProject(); + const bool canRun = pe->canRun(project, DebugRunMode); // We don't want to do anything anymore. m_interruptAction->setEnabled(false); m_continueAction->setEnabled(false); m_exitAction->setEnabled(false); - m_startAction->setEnabled(true); - m_debugWithoutDeployAction->setEnabled(true); + m_startAction->setEnabled(canRun); + m_debugWithoutDeployAction->setEnabled(canRun); setProxyAction(m_visibleStartAction, Core::Id(Constants::DEBUG)); m_hiddenStopAction->setAction(m_undisturbableAction); m_codeModelSnapshot = CPlusPlus::Snapshot(); diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index 60e0cb85523..e13c7577a03 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -31,6 +31,7 @@ #include "debuggeractions.h" #include "debuggercore.h" +#include "simplifytype.h" #include #include @@ -103,7 +104,7 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const case 0: // Stack frame level return QString::number(frame.level); case 1: // Function name - return frame.function; + return simplifyType(frame.function); case 2: // File name return frame.file.isEmpty() ? frame.from : QFileInfo(frame.file).fileName(); case 3: // Line number diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 754e09b67b5..6c8717ca8de 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -41,6 +41,7 @@ #include "watchutils.h" #include +#include #include #include @@ -1070,6 +1071,14 @@ QString WatchModel::displayName(const WatchItem *item) const result = QLatin1Char('*') + item->parent->name; else result = removeNamespaces(item->name); + + // Simplyfy names that refer to base classes. + if (result.startsWith(QLatin1Char('['))) { + result = simplifyType(result); + if (result.size() > 30) + result = result.left(27) + QLatin1String("...]"); + } + return result; } diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index 2f887680f87..d89513b5288 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -47,17 +47,18 @@ #include #include -#include -#include -#include - #include #include +#include #include +#include #include #include -#include #include +#include +#include +#include +#include //#define USE_WATCH_MODEL_TEST 1 @@ -1055,6 +1056,23 @@ void WatchTreeView::reset() resetHelper(); } +void WatchTreeView::doItemsLayout() +{ + if (m_sliderPosition == 0) + m_sliderPosition = verticalScrollBar()->sliderPosition(); + Utils::BaseTreeView::doItemsLayout(); + if (m_sliderPosition) + QTimer::singleShot(0, this, SLOT(adjustSlider())); +} + +void WatchTreeView::adjustSlider() +{ + if (m_sliderPosition) { + verticalScrollBar()->setSliderPosition(m_sliderPosition); + m_sliderPosition = 0; + } +} + void WatchTreeView::watchExpression(const QString &exp) { watchExpression(exp, QString()); diff --git a/src/plugins/debugger/watchwindow.h b/src/plugins/debugger/watchwindow.h index 3651e831a36..2e322dcb090 100644 --- a/src/plugins/debugger/watchwindow.h +++ b/src/plugins/debugger/watchwindow.h @@ -69,6 +69,7 @@ private slots: void resetHelper(); void expandNode(const QModelIndex &idx); void collapseNode(const QModelIndex &idx); + void adjustSlider(); void onClearIndividualFormat(); void onClearTypeFormat(); @@ -78,6 +79,7 @@ private slots: void onIndividualFormatChange(); private: + void doItemsLayout(); void keyPressEvent(QKeyEvent *ev); void contextMenuEvent(QContextMenuEvent *ev); void dragEnterEvent(QDragEnterEvent *ev); @@ -95,6 +97,7 @@ private: WatchType m_type; bool m_grabbing; + int m_sliderPosition; }; } // namespace Internal diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp index d18e7bbfb28..34d75a2bbcd 100644 --- a/src/plugins/diffeditor/diffeditor.cpp +++ b/src/plugins/diffeditor/diffeditor.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -209,6 +210,7 @@ DiffEditor::DiffEditor() , m_toolBar(0) , m_entriesComboBox(0) , m_toggleDescriptionAction(0) + , m_reloadAction(0) , m_diffEditorSwitcher(0) { ctor(); @@ -227,6 +229,7 @@ DiffEditor::DiffEditor(DiffEditor *other) , m_toolBar(0) , m_entriesComboBox(0) , m_toggleDescriptionAction(0) + , m_reloadAction(0) , m_diffEditorSwitcher(0) { ctor(); @@ -316,13 +319,9 @@ bool DiffEditor::open(QString *errorString, if (!m_controller) return false; - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - *errorString = tr("Could not open patch file \"%1\".").arg(fileName); + QString patch; + if (m_document->read(fileName, &patch, errorString) != Utils::TextFileFormat::ReadSuccess) return false; - } - - const QString patch = Core::EditorManager::defaultTextCodec()->toUnicode(file.readAll()); bool ok = false; QList fileDataList @@ -336,7 +335,9 @@ bool DiffEditor::open(QString *errorString, return false; } - m_controller->setDiffFiles(fileDataList, QFileInfo(fileName).absolutePath()); + const QFileInfo fi(fileName); + m_document->setFilePath(QDir::cleanPath(fi.absoluteFilePath())); + m_controller->setDiffFiles(fileDataList, fi.absolutePath()); return true; } @@ -393,13 +394,6 @@ QWidget *DiffEditor::toolBar() QSizePolicy::Expanding); // Mac Qt5 m_toolBar->addWidget(contextSpinBox); - QToolButton *toggleSync = new QToolButton(m_toolBar); - toggleSync->setIcon(QIcon(QLatin1String(Core::Constants::ICON_LINK))); - toggleSync->setCheckable(true); - toggleSync->setChecked(m_guiController->horizontalScrollBarSynchronization()); - toggleSync->setToolTip(tr("Synchronize Horizontal Scroll Bars")); - m_toolBar->addWidget(toggleSync); - QToolButton *toggleDescription = new QToolButton(m_toolBar); toggleDescription->setIcon( QIcon(QLatin1String(Constants::ICON_TOP_BAR))); @@ -411,7 +405,15 @@ QWidget *DiffEditor::toolBar() QToolButton *reloadButton = new QToolButton(m_toolBar); reloadButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_RELOAD_GRAY))); reloadButton->setToolTip(tr("Reload Editor")); - m_toolBar->addWidget(reloadButton); + m_reloadAction = m_toolBar->addWidget(reloadButton); + slotReloaderChanged(m_controller->reloader()); + + QToolButton *toggleSync = new QToolButton(m_toolBar); + toggleSync->setIcon(QIcon(QLatin1String(Core::Constants::ICON_LINK))); + toggleSync->setCheckable(true); + toggleSync->setChecked(m_guiController->horizontalScrollBarSynchronization()); + toggleSync->setToolTip(tr("Synchronize Horizontal Scroll Bars")); + m_toolBar->addWidget(toggleSync); m_diffEditorSwitcher = new QToolButton(m_toolBar); m_toolBar->addWidget(m_diffEditorSwitcher); @@ -433,6 +435,8 @@ QWidget *DiffEditor::toolBar() this, SLOT(slotDiffEditorSwitched())); connect(reloadButton, SIGNAL(clicked()), m_controller, SLOT(requestReload())); + connect(m_controller, SIGNAL(reloaderChanged(DiffEditorReloader*)), + this, SLOT(slotReloaderChanged(DiffEditorReloader*))); return m_toolBar; } @@ -548,6 +552,11 @@ void DiffEditor::slotDescriptionVisibilityChanged() m_toggleDescriptionAction->setVisible(enabled); } +void DiffEditor::slotReloaderChanged(DiffEditorReloader *reloader) +{ + m_reloadAction->setVisible(reloader); +} + void DiffEditor::slotDiffEditorSwitched() { QWidget *oldEditor = m_currentEditor; diff --git a/src/plugins/diffeditor/diffeditor.h b/src/plugins/diffeditor/diffeditor.h index cd09ee1e460..1082b6e6549 100644 --- a/src/plugins/diffeditor/diffeditor.h +++ b/src/plugins/diffeditor/diffeditor.h @@ -83,6 +83,7 @@ private slots: void entryActivated(int index); void slotDescriptionChanged(const QString &description); void slotDescriptionVisibilityChanged(); + void slotReloaderChanged(DiffEditorReloader *reloader); void slotDiffEditorSwitched(); private: @@ -105,6 +106,7 @@ private: QToolBar *m_toolBar; QComboBox *m_entriesComboBox; QAction *m_toggleDescriptionAction; + QAction *m_reloadAction; QToolButton *m_diffEditorSwitcher; }; diff --git a/src/plugins/diffeditor/diffeditorcontroller.cpp b/src/plugins/diffeditor/diffeditorcontroller.cpp index 1d9d76448fa..7ff6a983481 100644 --- a/src/plugins/diffeditor/diffeditorcontroller.cpp +++ b/src/plugins/diffeditor/diffeditorcontroller.cpp @@ -29,6 +29,7 @@ #include "diffeditorconstants.h" #include "diffeditorcontroller.h" +#include "diffeditorreloader.h" #include @@ -44,7 +45,8 @@ DiffEditorController::DiffEditorController(QObject *parent) : QObject(parent), m_descriptionEnabled(false), m_contextLinesNumber(3), - m_ignoreWhitespace(true) + m_ignoreWhitespace(true), + m_reloader(0) { QSettings *s = Core::ICore::settings(); s->beginGroup(QLatin1String(settingsGroupC)); @@ -124,6 +126,27 @@ QString DiffEditorController::makePatch(int diffFileIndex, lastChunk && fileData.lastChunkAtTheEndOfFile); } +DiffEditorReloader *DiffEditorController::reloader() const +{ + return m_reloader; +} + +void DiffEditorController::setReloader(DiffEditorReloader *reloader) +{ + if (m_reloader == reloader) + return; // nothing changes + + if (m_reloader) + m_reloader->setController(0); + + m_reloader = reloader; + + if (m_reloader) + m_reloader->setController(this); + + reloaderChanged(m_reloader); +} + void DiffEditorController::clear() { clear(tr("No difference")); @@ -238,7 +261,8 @@ void DiffEditorController::setIgnoreWhitespace(bool ignore) void DiffEditorController::requestReload() { - emit reloadRequested(); + if (m_reloader) + m_reloader->requestReload(); } void DiffEditorController::requestChunkActions(QMenu *menu, diff --git a/src/plugins/diffeditor/diffeditorcontroller.h b/src/plugins/diffeditor/diffeditorcontroller.h index 82c150435ff..8314e1bda21 100644 --- a/src/plugins/diffeditor/diffeditorcontroller.h +++ b/src/plugins/diffeditor/diffeditorcontroller.h @@ -37,6 +37,8 @@ namespace DiffEditor { +class DiffEditorReloader; + class DIFFEDITOR_EXPORT DiffEditorController : public QObject { Q_OBJECT @@ -55,6 +57,9 @@ public: QString makePatch(int diffFileIndex, int chunkIndex, bool revert) const; + DiffEditorReloader *reloader() const; + void setReloader(DiffEditorReloader *reloader); + public slots: void clear(); void clear(const QString &message); @@ -79,11 +84,11 @@ signals: void descriptionEnablementChanged(bool on); void contextLinesNumberChanged(int lines); void ignoreWhitespaceChanged(bool ignore); - void reloadRequested(); void chunkActionsRequested(QMenu *menu, int diffFileIndex, int chunkIndex); void expandBranchesRequested(const QString &revision); + void reloaderChanged(DiffEditorReloader *reloader); private: QString prepareBranchesForCommit(const QString &output); @@ -95,6 +100,7 @@ private: bool m_descriptionEnabled; int m_contextLinesNumber; bool m_ignoreWhitespace; + DiffEditorReloader *m_reloader; }; } // namespace DiffEditor diff --git a/src/plugins/diffeditor/diffeditordocument.cpp b/src/plugins/diffeditor/diffeditordocument.cpp index a13e23f2e54..817f0d946cb 100644 --- a/src/plugins/diffeditor/diffeditordocument.cpp +++ b/src/plugins/diffeditor/diffeditordocument.cpp @@ -30,17 +30,22 @@ #include "diffeditordocument.h" #include "diffeditorconstants.h" #include "diffeditorcontroller.h" +#include "diffutils.h" + +#include #include +#include +#include +#include namespace DiffEditor { DiffEditorDocument::DiffEditorDocument() : - Core::IDocument(), - m_diffEditorController(new DiffEditorController(this)) + Core::TextDocument(), + m_controller(new DiffEditorController(this)) { setId(Constants::DIFF_EDITOR_ID); - setDisplayName(QCoreApplication::translate("DiffEditor", Constants::DIFF_EDITOR_DISPLAY_NAME)); setTemporary(true); } @@ -50,7 +55,7 @@ DiffEditorDocument::~DiffEditorDocument() DiffEditorController *DiffEditorDocument::controller() const { - return m_diffEditorController; + return m_controller; } bool DiffEditorDocument::setContents(const QByteArray &contents) @@ -59,12 +64,33 @@ bool DiffEditorDocument::setContents(const QByteArray &contents) return true; } +QString DiffEditorDocument::defaultPath() const +{ + if (!m_controller) + return QString(); + + return m_controller->workingDirectory(); +} + bool DiffEditorDocument::save(QString *errorString, const QString &fileName, bool autoSave) { Q_UNUSED(errorString) - Q_UNUSED(fileName) Q_UNUSED(autoSave) - return false; + + if (!m_controller) + return false; + + const QString contents = DiffUtils::makePatch(m_controller->diffFiles()); + + const bool ok = write(fileName, format(), contents, errorString); + + if (!ok) + return false; + + const QFileInfo fi(fileName); + setFilePath(QDir::cleanPath(fi.absoluteFilePath())); + setDisplayName(QString()); + return true; } Core::IDocument::ReloadBehavior DiffEditorDocument::reloadBehavior(ChangeTrigger state, ChangeType type) const diff --git a/src/plugins/diffeditor/diffeditordocument.h b/src/plugins/diffeditor/diffeditordocument.h index 86263562889..6785a71553f 100644 --- a/src/plugins/diffeditor/diffeditordocument.h +++ b/src/plugins/diffeditor/diffeditordocument.h @@ -32,13 +32,13 @@ #include "diffeditor_global.h" -#include +#include namespace DiffEditor { class DiffEditorController; -class DIFFEDITOR_EXPORT DiffEditorDocument : public Core::IDocument +class DIFFEDITOR_EXPORT DiffEditorDocument : public Core::TextDocument { Q_OBJECT public: @@ -48,17 +48,17 @@ public: DiffEditorController *controller() const; bool setContents(const QByteArray &contents); - QString defaultPath() const { return QString(); } + QString defaultPath() const; QString suggestedFileName() const { return QString(); } bool isModified() const { return false; } - bool isSaveAsAllowed() const { return false; } + bool isSaveAsAllowed() const { return true; } bool save(QString *errorString, const QString &fileName, bool autoSave); ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const; bool reload(QString *errorString, ReloadFlag flag, ChangeType type); private: - DiffEditorController *m_diffEditorController; + DiffEditorController *m_controller; }; } // namespace DiffEditor diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 7dbf1bb28b7..0d6ad83df02 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -61,8 +61,6 @@ protected: void reload(); private: - QString getFileContents(const QString &fileName) const; - QString m_leftFileName; QString m_rightFileName; }; @@ -78,8 +76,27 @@ SimpleDiffEditorReloader::SimpleDiffEditorReloader(QObject *parent, void SimpleDiffEditorReloader::reload() { - const QString leftText = getFileContents(m_leftFileName); - const QString rightText = getFileContents(m_rightFileName); + QString errorString; + Utils::TextFileFormat format; + format.codec = Core::EditorManager::defaultTextCodec(); + + QString leftText; + if (Utils::TextFileFormat::readFile(m_leftFileName, + format.codec, + &leftText, &format, &errorString) + != Utils::TextFileFormat::ReadSuccess) { + + return; + } + + QString rightText; + if (Utils::TextFileFormat::readFile(m_rightFileName, + format.codec, + &rightText, &format, &errorString) + != Utils::TextFileFormat::ReadSuccess) { + + return; + } Differ differ; QList diffList = differ.cleanupSemantics( @@ -91,7 +108,7 @@ void SimpleDiffEditorReloader::reload() QList outputLeftDiffList; QList outputRightDiffList; - if (diffEditorController()->isIgnoreWhitespace()) { + if (controller()->isIgnoreWhitespace()) { const QList leftIntermediate = Differ::moveWhitespaceIntoEqualities(leftDiffList); const QList rightIntermediate = @@ -108,26 +125,18 @@ void SimpleDiffEditorReloader::reload() const ChunkData chunkData = DiffUtils::calculateOriginalData( outputLeftDiffList, outputRightDiffList); FileData fileData = DiffUtils::calculateContextData( - chunkData, diffEditorController()->contextLinesNumber(), 0); + chunkData, controller()->contextLinesNumber(), 0); fileData.leftFileInfo.fileName = m_leftFileName; fileData.rightFileInfo.fileName = m_rightFileName; QList fileDataList; fileDataList << fileData; - diffEditorController()->setDiffFiles(fileDataList); + controller()->setDiffFiles(fileDataList); reloadFinished(); } -QString SimpleDiffEditorReloader::getFileContents(const QString &fileName) const -{ - QFile file(fileName); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) - return Core::EditorManager::defaultTextCodec()->toUnicode(file.readAll()); - return QString(); -} - ///////////////// DiffEditorPlugin::DiffEditorPlugin() @@ -186,16 +195,16 @@ void DiffEditorPlugin::diff() const QString documentId = QLatin1String("Diff ") + fileName1 + QLatin1String(", ") + fileName2; DiffEditorDocument *document = DiffEditorManager::find(documentId); - if (!document) { - QString title = tr("Diff \"%1\", \"%2\"").arg(fileName1).arg(fileName2); - document = DiffEditorManager::findOrCreate(documentId, title); - if (!document) - return; + QString title = tr("Diff \"%1\", \"%2\"").arg(fileName1).arg(fileName2); + document = DiffEditorManager::findOrCreate(documentId, title); + if (!document) + return; - DiffEditorController *controller = document->controller(); + DiffEditorController *controller = document->controller(); + if (!controller->reloader()) { SimpleDiffEditorReloader *reloader = new SimpleDiffEditorReloader(controller, fileName1, fileName2); - reloader->setDiffEditorController(controller); + controller->setReloader(reloader); } Core::EditorManager::activateEditorForDocument(document); @@ -474,7 +483,23 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data() "diff --git a/empty b/empty\n" "deleted file mode 100644\n" "index e69de29..0000000\n" - ); + "diff --git a/file a.txt b/file b.txt\n" + "similarity index 99%\n" + "copy from file a.txt\n" + "copy to file b.txt\n" + "index 1234567..9876543\n" + "--- a/file a.txt\n" + "+++ b/file b.txt\n" + "@@ -20,3 +20,3 @@\n" + " A\n" + "-B\n" + "+C\n" + " D\n" + "diff --git a/file a.txt b/file b.txt\n" + "similarity index 99%\n" + "rename from file a.txt\n" + "rename to file b.txt\n" + ); FileData fileData1; fileData1.leftFileInfo = DiffFileInfo(QLatin1String("src/plugins/diffeditor/diffeditor.cpp"), @@ -534,6 +559,7 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data() FileData fileData3; fileData3.leftFileInfo = DiffFileInfo(QLatin1String("new"), QLatin1String("0000000")); fileData3.rightFileInfo = DiffFileInfo(QLatin1String("new"), QLatin1String("257cc56")); + fileData3.fileOperation = FileData::NewFile; ChunkData chunkData3; chunkData3.leftStartingLineNumber = -1; chunkData3.rightStartingLineNumber = 0; @@ -547,6 +573,7 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data() FileData fileData4; fileData4.leftFileInfo = DiffFileInfo(QLatin1String("deleted"), QLatin1String("257cc56")); fileData4.rightFileInfo = DiffFileInfo(QLatin1String("deleted"), QLatin1String("0000000")); + fileData4.fileOperation = FileData::DeleteFile; ChunkData chunkData4; chunkData4.leftStartingLineNumber = 0; chunkData4.rightStartingLineNumber = -1; @@ -560,13 +587,35 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data() FileData fileData5; fileData5.leftFileInfo = DiffFileInfo(QLatin1String("empty"), QLatin1String("0000000")); fileData5.rightFileInfo = DiffFileInfo(QLatin1String("empty"), QLatin1String("e69de29")); + fileData5.fileOperation = FileData::NewFile; FileData fileData6; fileData6.leftFileInfo = DiffFileInfo(QLatin1String("empty"), QLatin1String("e69de29")); fileData6.rightFileInfo = DiffFileInfo(QLatin1String("empty"), QLatin1String("0000000")); + fileData6.fileOperation = FileData::DeleteFile; + + FileData fileData7; + fileData7.leftFileInfo = DiffFileInfo(QLatin1String("file a.txt"), QLatin1String("1234567")); + fileData7.rightFileInfo = DiffFileInfo(QLatin1String("file b.txt"), QLatin1String("9876543")); + fileData7.fileOperation = FileData::CopyFile; + ChunkData chunkData7; + chunkData7.leftStartingLineNumber = 19; + chunkData7.rightStartingLineNumber = 19; + QList rows7; + rows7.append(RowData(TextLineData(QLatin1String("A")))); + rows7.append(RowData(TextLineData(QLatin1String("B")), + TextLineData(QLatin1String("C")))); + rows7.append(RowData(TextLineData(QLatin1String("D")))); + chunkData7.rows = rows7; + fileData7.chunks.append(chunkData7); + + FileData fileData8; + fileData8.leftFileInfo = DiffFileInfo(QLatin1String("file a.txt")); + fileData8.rightFileInfo = DiffFileInfo(QLatin1String("file b.txt")); + fileData8.fileOperation = FileData::RenameFile; QList fileDataList; - fileDataList << fileData1 << fileData2 << fileData3 << fileData4 << fileData5 << fileData6; + fileDataList << fileData1 << fileData2 << fileData3 << fileData4 << fileData5 << fileData6 << fileData7 << fileData8; QTest::newRow("Git patch") << patch << fileDataList; @@ -590,6 +639,7 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch() QCOMPARE(resultFileData.rightFileInfo.fileName, origFileData.rightFileInfo.fileName); QCOMPARE(resultFileData.rightFileInfo.typeInfo, origFileData.rightFileInfo.typeInfo); QCOMPARE(resultFileData.chunks.count(), origFileData.chunks.count()); + QCOMPARE(resultFileData.fileOperation, origFileData.fileOperation); for (int j = 0; j < origFileData.chunks.count(); j++) { const ChunkData &origChunkData = origFileData.chunks.at(j); const ChunkData &resultChunkData = resultFileData.chunks.at(j); diff --git a/src/plugins/diffeditor/diffeditorreloader.cpp b/src/plugins/diffeditor/diffeditorreloader.cpp index 77087c1bda8..911b736febb 100644 --- a/src/plugins/diffeditor/diffeditorreloader.cpp +++ b/src/plugins/diffeditor/diffeditorreloader.cpp @@ -44,20 +44,21 @@ DiffEditorReloader::~DiffEditorReloader() } -DiffEditorController *DiffEditorReloader::diffEditorController() const +DiffEditorController *DiffEditorReloader::controller() const { return m_controller; } -void DiffEditorReloader::setDiffEditorController(DiffEditorController *controller) +void DiffEditorReloader::setController(DiffEditorController *controller) { + if (m_controller == controller) + return; // nothing changes + if (m_controller) { disconnect(m_controller, SIGNAL(ignoreWhitespaceChanged(bool)), this, SLOT(requestReload())); disconnect(m_controller, SIGNAL(contextLinesNumberChanged(int)), this, SLOT(requestReload())); - disconnect(m_controller, SIGNAL(reloadRequested()), - this, SLOT(requestReload())); } m_controller = controller; @@ -67,8 +68,6 @@ void DiffEditorReloader::setDiffEditorController(DiffEditorController *controlle this, SLOT(requestReload())); connect(m_controller, SIGNAL(contextLinesNumberChanged(int)), this, SLOT(requestReload())); - connect(m_controller, SIGNAL(reloadRequested()), - this, SLOT(requestReload())); } } diff --git a/src/plugins/diffeditor/diffeditorreloader.h b/src/plugins/diffeditor/diffeditorreloader.h index 962902fb9db..e1b6408e56a 100644 --- a/src/plugins/diffeditor/diffeditorreloader.h +++ b/src/plugins/diffeditor/diffeditorreloader.h @@ -45,26 +45,27 @@ public: DiffEditorReloader(QObject *parent = 0); ~DiffEditorReloader(); - DiffEditorController *diffEditorController() const; - void setDiffEditorController(DiffEditorController *controller); - bool isReloading() const; +public slots: + void requestReload(); + protected: // reloadFinished() should be called // inside reload() (for synchronous reload) // or later (for asynchronous reload) virtual void reload() = 0; + DiffEditorController *controller() const; + void setController(DiffEditorController *controller); protected slots: void reloadFinished(); -private slots: - void requestReload(); - private: DiffEditorController *m_controller; bool m_reloading; + + friend class DiffEditorController; }; } // namespace DiffEditor diff --git a/src/plugins/diffeditor/diffutils.cpp b/src/plugins/diffeditor/diffutils.cpp index e12d257439c..18725363fb3 100644 --- a/src/plugins/diffeditor/diffutils.cpp +++ b/src/plugins/diffeditor/diffutils.cpp @@ -346,9 +346,7 @@ QString DiffUtils::makePatchLine(const QChar &startLineCharacter, } QString DiffUtils::makePatch(const ChunkData &chunkData, - const QString &leftFileName, - const QString &rightFileName, - bool lastChunk) + bool lastChunk) { QString diffText; int leftLineCount = 0; @@ -425,6 +423,16 @@ QString DiffUtils::makePatch(const ChunkData &chunkData, diffText.prepend(chunkLine); + return diffText; +} + +QString DiffUtils::makePatch(const ChunkData &chunkData, + const QString &leftFileName, + const QString &rightFileName, + bool lastChunk) +{ + QString diffText = makePatch(chunkData, lastChunk); + const QString rightFileInfo = QLatin1String("+++ ") + rightFileName + QLatin1Char('\n'); const QString leftFileInfo = QLatin1String("--- ") + leftFileName + QLatin1Char('\n'); @@ -434,6 +442,39 @@ QString DiffUtils::makePatch(const ChunkData &chunkData, return diffText; } +QString DiffUtils::makePatch(const QList &fileDataList) +{ + QString diffText; + + for (int i = 0; i < fileDataList.count(); i++) { + const FileData &fileData = fileDataList.at(i); + + if (fileData.binaryFiles) { + const QString binaryLine = QLatin1String("Binary files ") + + fileData.leftFileInfo.fileName + + QLatin1String(" and ") + + fileData.rightFileInfo.fileName + + QLatin1String(" differ\n"); + diffText += binaryLine; + } else { + const QString leftFileInfo = QLatin1String("--- ") + + fileData.leftFileInfo.fileName + QLatin1Char('\n'); + const QString rightFileInfo = QLatin1String("+++ ") + + fileData.rightFileInfo.fileName + QLatin1Char('\n'); + + diffText += leftFileInfo; + diffText += rightFileInfo; + + for (int j = 0; j < fileData.chunks.count(); j++) { + diffText += makePatch(fileData.chunks.at(j), + (j == fileData.chunks.count() - 1) + && fileData.lastChunkAtTheEndOfFile); + } + } + } + return diffText; +} + static QList readLines(const QString &patch, bool ignoreWhitespace, bool lastChunk, @@ -818,11 +859,11 @@ static FileData readGitHeaderAndChunks(const QString &headerAndChunks, QString rightFileName = QLatin1String("b/") + fileName; if (newFileMode.indexIn(patch, 0) == 0) { - fileData.leftFileInfo.devNull = true; + fileData.fileOperation = FileData::NewFile; leftFileName = devNull; patch = patch.mid(newFileMode.capturedTexts().at(1).count()); } else if (deletedFileMode.indexIn(patch, 0) == 0) { - fileData.rightFileInfo.devNull = true; + fileData.fileOperation = FileData::DeleteFile; rightFileName = devNull; patch = patch.mid(deletedFileMode.capturedTexts().at(1).count()); } @@ -848,7 +889,8 @@ static FileData readGitHeaderAndChunks(const QString &headerAndChunks, + QLatin1String(" differ$)")); // empty or followed either by leftFileRegExp or by binaryRegExp - if (patch.isEmpty() && (fileData.leftFileInfo.devNull || fileData.rightFileInfo.devNull)) { + if (patch.isEmpty() && (fileData.fileOperation == FileData::NewFile + || fileData.fileOperation == FileData::DeleteFile)) { readOk = true; } else if (leftFileRegExp.indexIn(patch, 0) == 0) { patch = patch.mid(leftFileRegExp.capturedTexts().at(1).count()); @@ -877,51 +919,193 @@ static FileData readGitHeaderAndChunks(const QString &headerAndChunks, return fileData; } +static FileData readCopyRenameChunks(const QString ©RenameChunks, + FileData::FileOperation fileOperation, + const QString &leftFileName, + const QString &rightFileName, + bool ignoreWhitespace, + bool *ok) +{ + FileData fileData; + fileData.fileOperation = fileOperation; + fileData.leftFileInfo.fileName = leftFileName; + fileData.rightFileInfo.fileName = rightFileName; + + QString patch = copyRenameChunks; + bool readOk = false; + + const QRegExp indexRegExp(QLatin1String("(^index (\\w+)\\.{2}(\\w+)(?: \\d+)?(\\n|$))")); // index cap2..cap3(optionally: octal) + + QString leftGitFileName = QLatin1String("a/") + leftFileName; + QString rightGitFileName = QLatin1String("b/") + rightFileName; + + if (fileOperation == FileData::CopyFile || fileOperation == FileData::RenameFile) { + if (indexRegExp.indexIn(patch, 0) == 0) { + const QStringList capturedTexts = indexRegExp.capturedTexts(); + const QString captured = capturedTexts.at(1); + fileData.leftFileInfo.typeInfo = capturedTexts.at(2); + fileData.rightFileInfo.typeInfo = capturedTexts.at(3); + + patch = patch.mid(captured.count()); + + const QRegExp leftFileRegExp(QLatin1String("(^-{3} ") // "--- " + + leftGitFileName // "a/fileName" or "/dev/null" + + QLatin1String("(?:\\t[^\\n]*)*\\n)")); // optionally followed by: \t anything \t anything ...) + const QRegExp rightFileRegExp(QLatin1String("(^\\+{3} ") // "+++ " + + rightGitFileName // "b/fileName" or "/dev/null" + + QLatin1String("(?:\\t[^\\n]*)*\\n)")); // optionally followed by: \t anything \t anything ...) + + // followed by leftFileRegExp + if (leftFileRegExp.indexIn(patch, 0) == 0) { + patch = patch.mid(leftFileRegExp.capturedTexts().at(1).count()); + + // followed by rightFileRegExp + if (rightFileRegExp.indexIn(patch, 0) == 0) { + patch = patch.mid(rightFileRegExp.capturedTexts().at(1).count()); + + fileData.chunks = readChunks(patch, + ignoreWhitespace, + &fileData.lastChunkAtTheEndOfFile, + &readOk); + } + } + } else if (copyRenameChunks.isEmpty()) { + readOk = true; + } + } + + if (ok) + *ok = readOk; + + if (!readOk) + return FileData(); + + return fileData; +} + static QList readGitPatch(const QString &patch, bool ignoreWhitespace, bool *ok) { - const QRegExp gitRegExp(QLatin1String("((?:\\n|^)diff --git a/([^\\n]+) b/\\2\\n)")); // diff --git a/cap2 b/cap2 + const QRegExp simpleGitRegExp(QLatin1String("((?:\\n|^)diff --git a/([^\\n]+) b/\\2\\n)")); // diff --git a/cap2 b/cap2 + + const QRegExp similarityRegExp(QLatin1String( + "((?:\\n|^)diff --git a/([^\\n]+) b/([^\\n]+)\\n" // diff --git a/cap2 b/cap3 + "(?:dis)?similarity index \\d{1,3}%\\n" // similarity / dissimilarity index xxx% (100% max) + "(copy|rename) from \\2\\n" // copy / rename from cap2 + "\\4 to \\3\\n)")); // copy / rename (cap4) to cap3 bool readOk = false; QList fileDataList; - int pos = gitRegExp.indexIn(patch, 0); + const int simpleGitPos = simpleGitRegExp.indexIn(patch, 0); + const int similarityPos = similarityRegExp.indexIn(patch, 0); + + bool simpleGitMatched = false; + int pos = -1; + if (simpleGitPos < 0) { + pos = similarityPos; + } else if (similarityPos < 0) { + pos = simpleGitPos; + simpleGitMatched = true; + } else { + pos = qMin(simpleGitPos, similarityPos); + simpleGitMatched = (pos == simpleGitPos); + } + if (pos == 0) { // git style patch readOk = true; int endOfLastHeader = 0; - QString lastFileName; + QString lastLeftFileName; + QString lastRightFileName; + FileData::FileOperation lastOperation = FileData::ChangeFile; do { - const QStringList capturedTexts = gitRegExp.capturedTexts(); - const QString captured = capturedTexts.at(1); - const QString fileName = capturedTexts.at(2); if (endOfLastHeader > 0) { const QString headerAndChunks = patch.mid(endOfLastHeader, pos - endOfLastHeader); - const FileData fileData = readGitHeaderAndChunks(headerAndChunks, - lastFileName, - ignoreWhitespace, - &readOk); + FileData fileData; + if (lastOperation == FileData::ChangeFile) { + fileData = readGitHeaderAndChunks(headerAndChunks, + lastLeftFileName, + ignoreWhitespace, + &readOk); + } else { + fileData = readCopyRenameChunks(headerAndChunks, + lastOperation, + lastLeftFileName, + lastRightFileName, + ignoreWhitespace, + &readOk); + } if (!readOk) break; fileDataList.append(fileData); } - pos += captured.count(); - endOfLastHeader = pos; - lastFileName = fileName; - } while ((pos = gitRegExp.indexIn(patch, pos)) != -1); + + if (simpleGitMatched) { + const QStringList capturedTexts = simpleGitRegExp.capturedTexts(); + const QString captured = capturedTexts.at(1); + const QString fileName = capturedTexts.at(2); + pos += captured.count(); + endOfLastHeader = pos; + lastLeftFileName = fileName; + lastRightFileName = fileName; + lastOperation = FileData::ChangeFile; + } else { + const QStringList capturedTexts = similarityRegExp.capturedTexts(); + const QString captured = capturedTexts.at(1); + const QString leftFileName = capturedTexts.at(2); + const QString rightFileName = capturedTexts.at(3); + const QString operation = capturedTexts.at(4); + pos += captured.count(); + endOfLastHeader = pos; + lastLeftFileName = leftFileName; + lastRightFileName = rightFileName; + if (operation == QLatin1String("copy")) + lastOperation = FileData::CopyFile; + else if (operation == QLatin1String("rename")) + lastOperation = FileData::RenameFile; + else + break; // either copy or rename, otherwise broken + } + + const int simpleGitPos = simpleGitRegExp.indexIn(patch, pos); + const int similarityPos = similarityRegExp.indexIn(patch, pos); + + simpleGitMatched = false; + pos = -1; + if (simpleGitPos < 0) { + pos = similarityPos; + } else if (similarityPos < 0) { + pos = simpleGitPos; + simpleGitMatched = true; + } else { + pos = qMin(simpleGitPos, similarityPos); + simpleGitMatched = (pos == simpleGitPos); + } + } while (pos != -1); if (endOfLastHeader > 0 && readOk) { const QString headerAndChunks = patch.mid(endOfLastHeader, patch.count() - endOfLastHeader - 1); - const FileData fileData = readGitHeaderAndChunks(headerAndChunks, - lastFileName, - ignoreWhitespace, - &readOk); + FileData fileData; + if (lastOperation == FileData::ChangeFile) { + fileData = readGitHeaderAndChunks(headerAndChunks, + lastLeftFileName, + ignoreWhitespace, + &readOk); + } else { + fileData = readCopyRenameChunks(headerAndChunks, + lastOperation, + lastLeftFileName, + lastRightFileName, + ignoreWhitespace, + &readOk); + } if (readOk) fileDataList.append(fileData); } diff --git a/src/plugins/diffeditor/diffutils.h b/src/plugins/diffeditor/diffutils.h index 9043969929a..b649538026b 100644 --- a/src/plugins/diffeditor/diffutils.h +++ b/src/plugins/diffeditor/diffutils.h @@ -46,13 +46,12 @@ class Diff; class DIFFEDITOR_EXPORT DiffFileInfo { public: - DiffFileInfo() : devNull(false) {} - DiffFileInfo(const QString &file) : fileName(file), devNull(false) {} + DiffFileInfo() {} + DiffFileInfo(const QString &file) : fileName(file) {} DiffFileInfo(const QString &file, const QString &type) - : fileName(file), typeInfo(type), devNull(false) {} + : fileName(file), typeInfo(type) {} QString fileName; QString typeInfo; - bool devNull; }; class DIFFEDITOR_EXPORT TextLineData { @@ -100,17 +99,28 @@ public: class DIFFEDITOR_EXPORT FileData { public: + enum FileOperation { + ChangeFile, + NewFile, + DeleteFile, + CopyFile, + RenameFile + }; + FileData() - : binaryFiles(false), + : fileOperation(ChangeFile), + binaryFiles(false), lastChunkAtTheEndOfFile(false), contextChunksIncluded(false) {} FileData(const ChunkData &chunkData) - : binaryFiles(false), + : fileOperation(ChangeFile), + binaryFiles(false), lastChunkAtTheEndOfFile(false), contextChunksIncluded(false) { chunks.append(chunkData); } QList chunks; DiffFileInfo leftFileInfo; DiffFileInfo rightFileInfo; + FileOperation fileOperation; bool binaryFiles; bool lastChunkAtTheEndOfFile; bool contextChunksIncluded; @@ -128,10 +138,13 @@ public: const QString &textLine, bool lastChunk, bool lastLine); + static QString makePatch(const ChunkData &chunkData, + bool lastChunk = false); static QString makePatch(const ChunkData &chunkData, const QString &leftFileName, const QString &rightFileName, bool lastChunk = false); + static QString makePatch(const QList &fileDataList); static QList readPatch(const QString &patch, bool ignoreWhitespace, bool *ok = 0); diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp index 7ff3037a602..a8086227f6d 100644 --- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp +++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp @@ -1191,11 +1191,12 @@ void SideBySideDiffEditorWidget::slotLeftJumpToOriginalFileRequested( // The same file (e.g. in git diff), jump to the line number taken from the right editor. // Warning: git show SHA^ vs SHA or git diff HEAD vs Index // (when Working tree has changed in meantime) will not work properly. - int leftLineNumber = 0; - int rightLineNumber = 0; - for (int i = 0; i < fileData.chunks.count(); i++) { const ChunkData chunkData = fileData.chunks.at(i); + + int leftLineNumber = chunkData.leftStartingLineNumber; + int rightLineNumber = chunkData.rightStartingLineNumber; + for (int j = 0; j < chunkData.rows.count(); j++) { const RowData rowData = chunkData.rows.at(j); if (rowData.leftLine.textLineType == TextLineData::TextLine) diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp index def29363082..87001b3fe6f 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp @@ -730,21 +730,46 @@ void UnifiedDiffEditorWidget::jumpToOriginalFile(const QTextCursor &cursor) return; const int blockNumber = cursor.blockNumber(); + const int fileIndex = fileIndexForBlockNumber(blockNumber); + if (fileIndex < 0) + return; + + const FileData fileData = m_contextFileData.at(fileIndex); + const QString leftFileName = fileData.leftFileInfo.fileName; + const QString rightFileName = fileData.rightFileInfo.fileName; + const int columnNumber = cursor.positionInBlock() - 1; // -1 for the first character in line const int rightLineNumber = m_rightLineNumbers.value(blockNumber, -1); if (rightLineNumber >= 0) { - jumpToOriginalFile(m_contextFileData.at( - fileIndexForBlockNumber(blockNumber)).rightFileInfo.fileName, - rightLineNumber, columnNumber); + jumpToOriginalFile(rightFileName, rightLineNumber, columnNumber); return; } const int leftLineNumber = m_leftLineNumbers.value(blockNumber, -1); if (leftLineNumber >= 0) { - jumpToOriginalFile(m_contextFileData.at( - fileIndexForBlockNumber(blockNumber)).leftFileInfo.fileName, - leftLineNumber, columnNumber); + if (leftFileName == rightFileName) { + for (int i = 0; i < fileData.chunks.count(); i++) { + const ChunkData chunkData = fileData.chunks.at(i); + + int newLeftLineNumber = chunkData.leftStartingLineNumber; + int newRightLineNumber = chunkData.rightStartingLineNumber; + + for (int j = 0; j < chunkData.rows.count(); j++) { + const RowData rowData = chunkData.rows.at(j); + if (rowData.leftLine.textLineType == TextLineData::TextLine) + newLeftLineNumber++; + if (rowData.rightLine.textLineType == TextLineData::TextLine) + newRightLineNumber++; + if (newLeftLineNumber == leftLineNumber) { + jumpToOriginalFile(leftFileName, newRightLineNumber, 0); + return; + } + } + } + } else { + jumpToOriginalFile(leftFileName, leftLineNumber, columnNumber); + } return; } } diff --git a/src/plugins/find/Find.pluginspec.in b/src/plugins/find/Find.pluginspec.in deleted file mode 100644 index 8af87eb2e56..00000000000 --- a/src/plugins/find/Find.pluginspec.in +++ /dev/null @@ -1,16 +0,0 @@ - - Digia Plc - (C) 2014 Digia Plc - -Commercial Usage - -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. - - Qt Creator - Provides the find widget and the hooks for find implementations. - http://www.qt-project.org - diff --git a/src/plugins/find/find.pro b/src/plugins/find/find.pro deleted file mode 100644 index a7d911be0d5..00000000000 --- a/src/plugins/find/find.pro +++ /dev/null @@ -1,3 +0,0 @@ -include(../../qtcreatorplugin.pri) -DEFINES += FIND_LIBRARY -SOURCES += findplugin.cpp diff --git a/src/plugins/find/find.qbs b/src/plugins/find/find.qbs deleted file mode 100644 index 8e28788ff29..00000000000 --- a/src/plugins/find/find.qbs +++ /dev/null @@ -1,11 +0,0 @@ -import qbs 1.0 - -import QtcPlugin - -QtcPlugin { - name: "Find" - - Depends { name: "Core" } - - files: [ "findplugin.cpp" ] -} diff --git a/src/plugins/find/find_dependencies.pri b/src/plugins/find/find_dependencies.pri deleted file mode 100644 index 39a0b86f75e..00000000000 --- a/src/plugins/find/find_dependencies.pri +++ /dev/null @@ -1,3 +0,0 @@ -QTC_PLUGIN_NAME = Find -QTC_LIB_DEPENDS += -QTC_PLUGIN_DEPENDS += diff --git a/src/plugins/find/findplugin.cpp b/src/plugins/find/findplugin.cpp deleted file mode 100644 index a4428b657fd..00000000000 --- a/src/plugins/find/findplugin.cpp +++ /dev/null @@ -1,2 +0,0 @@ - -void dummyFindPlugin () {} diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 3b0f469ba32..b824aaf4131 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -246,7 +246,9 @@ void GenericProject::refresh(RefreshOptions options) part->displayName = displayName(); part->projectFile = projectFilePath().toString(); - part->includePaths += projectIncludePaths(); + foreach (const QString &inc, projectIncludePaths()) + part->headerPaths += CppTools::ProjectPart::HeaderPath( + inc, CppTools::ProjectPart::HeaderPath::IncludePath); Kit *k = activeTarget() ? activeTarget()->kit() : KitManager::defaultKit(); if (ToolChain *tc = ToolChainKitInformation::toolChain(k)) { diff --git a/src/plugins/git/changeselectiondialog.cpp b/src/plugins/git/changeselectiondialog.cpp index b56227316ad..a22c10783ee 100644 --- a/src/plugins/git/changeselectiondialog.cpp +++ b/src/plugins/git/changeselectiondialog.cpp @@ -33,6 +33,8 @@ #include "gitclient.h" #include "ui_changeselectiondialog.h" +#include + #include #include #include @@ -142,7 +144,7 @@ QString ChangeSelectionDialog::workingDirectory() const if (workingDir.isEmpty() || !QDir(workingDir).exists()) return QString(); - return GitPlugin::instance()->gitClient()->findRepositoryForDirectory(workingDir); + return Core::VcsManager::findTopLevelForDirectory(workingDir); } ChangeCommand ChangeSelectionDialog::command() const diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp index 855a9b01098..e89c2242da8 100644 --- a/src/plugins/git/gerrit/gerritplugin.cpp +++ b/src/plugins/git/gerrit/gerritplugin.cpp @@ -432,7 +432,7 @@ void GerritPlugin::fetch(const QSharedPointer &change, int mode) QString repository; bool verifiedRepository = false; if (!m_dialog.isNull() && !m_parameters.isNull() && QFile::exists(m_dialog->repositoryPath())) - repository = client->findRepositoryForDirectory(m_dialog->repositoryPath()); + repository = Core::VcsManager::findTopLevelForDirectory(m_dialog->repositoryPath()); if (!repository.isEmpty()) { // Check if remote from a working dir is the same as remote from patch diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 3d4aaf0372f..da79d36bd7c 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -86,6 +86,8 @@ static const char CHERRY_PICK_HEAD[] = "CHERRY_PICK_HEAD"; static const char noColorOption[] = "--no-color"; static const char decorateOption[] = "--decorate"; +using namespace Core; + namespace Git { namespace Internal { @@ -102,7 +104,7 @@ class GitDiffHandler : public QObject Q_OBJECT public: - GitDiffHandler(DiffEditor::DiffEditorController *editorController, + GitDiffHandler(DiffEditor::DiffEditorController *controller, const QString &workingDirectory); // index -> working tree @@ -133,7 +135,7 @@ private: QProcessEnvironment processEnvironment() const; QString gitPath() const; - QPointer m_editorController; + QPointer m_controller; const QString m_workingDirectory; GitClient *m_gitClient; const QString m_waitMessage; @@ -141,9 +143,9 @@ private: QString m_id; }; -GitDiffHandler::GitDiffHandler(DiffEditor::DiffEditorController *editorController, +GitDiffHandler::GitDiffHandler(DiffEditor::DiffEditorController *controller, const QString &workingDirectory) - : m_editorController(editorController), + : m_controller(controller), m_workingDirectory(workingDirectory), m_gitClient(GitPlugin::instance()->gitClient()), m_waitMessage(tr("Waiting for data...")) @@ -199,12 +201,12 @@ void GitDiffHandler::show(const QString &id) void GitDiffHandler::postCollectShowDescription(const QString &id) { - if (m_editorController.isNull()) { + if (m_controller.isNull()) { deleteLater(); return; } - m_editorController->clear(m_waitMessage); + m_controller->clear(m_waitMessage); VcsBase::Command *command = new VcsBase::Command(gitPath(), m_workingDirectory, processEnvironment()); @@ -224,7 +226,7 @@ void GitDiffHandler::postCollectShowDescription(const QString &id) void GitDiffHandler::slotShowDescriptionReceived(const QString &description) { - if (m_editorController.isNull()) { + if (m_controller.isNull()) { deleteLater(); return; } @@ -232,7 +234,7 @@ void GitDiffHandler::slotShowDescriptionReceived(const QString &description) postCollectDiffOutput(QStringList() << m_id + QLatin1Char('^') << m_id); // need to be called after postCollectDiffOutput(), since it clears the description - m_editorController->setDescription( + m_controller->setDescription( m_gitClient->extendedShowDescription(m_workingDirectory, description)); } @@ -241,10 +243,10 @@ void GitDiffHandler::addJob(VcsBase::Command *command, const QStringList &argume { QStringList args; args << QLatin1String("diff"); - if (m_editorController->isIgnoreWhitespace()) + if (m_controller->isIgnoreWhitespace()) args << QLatin1String("--ignore-space-change"); args << QLatin1String("--unified=") + QString::number( - m_editorController->contextLinesNumber()); + m_controller->contextLinesNumber()); args << arguments; command->addJob(args, timeout()); } @@ -256,16 +258,16 @@ void GitDiffHandler::postCollectDiffOutput(const QStringList &arguments) void GitDiffHandler::postCollectDiffOutput(const QList &argumentsList) { - if (m_editorController.isNull()) { + if (m_controller.isNull()) { deleteLater(); return; } - m_editorController->clear(m_waitMessage); + m_controller->clear(m_waitMessage); VcsBase::Command *command = new VcsBase::Command(gitPath(), m_workingDirectory, processEnvironment()); - command->setCodec(Core::EditorManager::defaultTextCodec()); + command->setCodec(EditorManager::defaultTextCodec()); connect(command, SIGNAL(output(QString)), this, SLOT(slotDiffOutputReceived(QString))); command->addFlags(diffExecutionFlags()); @@ -278,7 +280,7 @@ void GitDiffHandler::postCollectDiffOutput(const QList &argumentsLi void GitDiffHandler::slotDiffOutputReceived(const QString &contents) { - if (m_editorController.isNull()) { + if (m_controller.isNull()) { deleteLater(); return; } @@ -286,8 +288,8 @@ void GitDiffHandler::slotDiffOutputReceived(const QString &contents) bool ok; QList fileDataList = DiffEditor::DiffUtils::readPatch( - contents, m_editorController->isIgnoreWhitespace(), &ok); - m_editorController->setDiffFiles(fileDataList, m_workingDirectory); + contents, m_controller->isIgnoreWhitespace(), &ok); + m_controller->setDiffFiles(fileDataList, m_workingDirectory); deleteLater(); } @@ -369,7 +371,7 @@ GitDiffEditorReloader::GitDiffEditorReloader(QObject *parent) void GitDiffEditorReloader::reload() { - GitDiffHandler *handler = new GitDiffHandler(diffEditorController(), + GitDiffHandler *handler = new GitDiffHandler(controller(), m_workingDirectory); connect(handler, SIGNAL(destroyed()), this, SLOT(reloadFinished())); @@ -610,11 +612,11 @@ private: -Core::IEditor *locateEditor(const char *property, const QString &entry) +IEditor *locateEditor(const char *property, const QString &entry) { - foreach (Core::IDocument *document, Core::DocumentModel::openedDocuments()) + foreach (IDocument *document, DocumentModel::openedDocuments()) if (document->property(property).toString() == entry) - return Core::DocumentModel::editorsForDocument(document).first(); + return DocumentModel::editorsForDocument(document).first(); return 0; } @@ -658,7 +660,7 @@ static inline QString msgCannotLaunch(const QString &binary) static inline QString currentDocumentPath() { - if (Core::IDocument *document= Core::EditorManager::currentDocument()) + if (IDocument *document= EditorManager::currentDocument()) return QFileInfo(document->filePath()).path(); return QString(); } @@ -701,7 +703,7 @@ GitClient::GitClient(GitSettings *settings) : m_contextChunkIndex(-1) { QTC_CHECK(settings); - connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), this, SLOT(saveSettings())); + connect(ICore::instance(), SIGNAL(saveSettingsRequested()), this, SLOT(saveSettings())); m_gitQtcEditor = QString::fromLatin1("\"%1\" -client -block -pid %2") .arg(QCoreApplication::applicationFilePath()) .arg(QCoreApplication::applicationPid()); @@ -760,12 +762,12 @@ VcsBase::VcsBaseEditorWidget *GitClient::findExistingVCSEditor(const char *regis const QString &dynamicPropertyValue) const { VcsBase::VcsBaseEditorWidget *rc = 0; - Core::IEditor *outputEditor = locateEditor(registerDynamicProperty, dynamicPropertyValue); + IEditor *outputEditor = locateEditor(registerDynamicProperty, dynamicPropertyValue); if (!outputEditor) return 0; // Exists already - Core::EditorManager::activateEditor(outputEditor); + EditorManager::activateEditor(outputEditor); outputEditor->document()->setContents(m_msgWait.toUtf8()); rc = VcsBase::VcsBaseEditorWidget::getVcsBaseEditor(outputEditor); @@ -796,9 +798,9 @@ void GitClient::slotChunkActionsRequested(QMenu *menu, int diffFileIndex, int ch m_contextDiffFileIndex = diffFileIndex; m_contextChunkIndex = chunkIndex; - m_contextDocument = qobject_cast(sender()); + m_contextController = qobject_cast(sender()); - if (m_contextDiffFileIndex < 0 || m_contextChunkIndex < 0 || !m_contextDocument) { + if (m_contextDiffFileIndex < 0 || m_contextChunkIndex < 0 || !m_contextController) { stageChunkAction->setEnabled(false); unstageChunkAction->setEnabled(false); } @@ -806,13 +808,13 @@ void GitClient::slotChunkActionsRequested(QMenu *menu, int diffFileIndex, int ch QString GitClient::makePatch(int diffFileIndex, int chunkIndex, bool revert) const { - if (m_contextDocument.isNull()) + if (m_contextController.isNull()) return QString(); if (diffFileIndex < 0 || chunkIndex < 0) return QString(); - QList fileDataList = m_contextDocument->diffFiles(); + QList fileDataList = m_contextController->diffFiles(); if (diffFileIndex >= fileDataList.count()) return QString(); @@ -836,7 +838,7 @@ QString GitClient::makePatch(int diffFileIndex, int chunkIndex, bool revert) con void GitClient::slotStageChunk() { - if (m_contextDocument.isNull()) + if (m_contextController.isNull()) return; const QString patch = makePatch(m_contextDiffFileIndex, @@ -849,7 +851,7 @@ void GitClient::slotStageChunk() void GitClient::slotUnstageChunk() { - if (m_contextDocument.isNull()) + if (m_contextController.isNull()) return; const QString patch = makePatch(m_contextDiffFileIndex, @@ -868,8 +870,8 @@ void GitClient::stage(const QString &patch, bool revert) if (!patchFile.open()) return; - const QString baseDir = m_contextDocument->workingDirectory(); - QTextCodec *codec = Core::EditorManager::defaultTextCodec(); + const QString baseDir = m_contextController->workingDirectory(); + QTextCodec *codec = EditorManager::defaultTextCodec(); const QByteArray patchData = codec ? codec->fromUnicode(patch) : patch.toLocal8Bit(); patchFile.write(patchData); @@ -889,7 +891,7 @@ void GitClient::stage(const QString &patch, bool revert) } else { outwin->append(errorMessage); } - m_contextDocument->requestReload(); + m_contextController->requestReload(); } else { outwin->appendError(errorMessage); } @@ -900,7 +902,7 @@ void GitClient::stage(const QString &patch, bool revert) * existing instance and to reuse it (in case, say, 'git diff foo' is * already open). */ VcsBase::VcsBaseEditorWidget *GitClient::createVcsEditor( - Core::Id id, + Id id, QString title, const QString &source, // Source file or directory CodecType codecType, @@ -912,7 +914,7 @@ VcsBase::VcsBaseEditorWidget *GitClient::createVcsEditor( QTC_CHECK(!findExistingVCSEditor(registerDynamicProperty, dynamicPropertyValue)); // Create new, set wait message, set up with source and codec - Core::IEditor *outputEditor = Core::EditorManager::openEditorWithContents(id, &title, + IEditor *outputEditor = EditorManager::openEditorWithContents(id, &title, m_msgWait.toUtf8()); outputEditor->document()->setProperty(registerDynamicProperty, dynamicPropertyValue); rc = VcsBase::VcsBaseEditorWidget::getVcsBaseEditor(outputEditor); @@ -961,9 +963,9 @@ void GitClient::diff(const QString &workingDirectory, if (!diffEditorDocument) { diffEditorDocument = createDiffEditor(documentId, workingDirectory, title); - GitDiffEditorReloader *reloader = - new GitDiffEditorReloader(diffEditorDocument->controller()); - reloader->setDiffEditorController(diffEditorDocument->controller()); + DiffEditor::DiffEditorController *controller = diffEditorDocument->controller(); + GitDiffEditorReloader *reloader = new GitDiffEditorReloader(controller); + controller->setReloader(reloader); reloader->setWorkingDirectory(workingDirectory); reloader->setDiffType(diffType); @@ -975,7 +977,7 @@ void GitClient::diff(const QString &workingDirectory, diffEditorDocument->controller()->requestReload(); - Core::EditorManager::activateEditorForDocument(diffEditorDocument); + EditorManager::activateEditorForDocument(diffEditorDocument); } void GitClient::diff(const QString &workingDirectory, const QString &fileName) @@ -989,9 +991,9 @@ void GitClient::diff(const QString &workingDirectory, const QString &fileName) if (!diffEditorDocument) { diffEditorDocument = createDiffEditor(documentId, sourceFile, title); - GitDiffEditorReloader *reloader = - new GitDiffEditorReloader(diffEditorDocument->controller()); - reloader->setDiffEditorController(diffEditorDocument->controller()); + DiffEditor::DiffEditorController *controller = diffEditorDocument->controller(); + GitDiffEditorReloader *reloader = new GitDiffEditorReloader(controller); + controller->setReloader(reloader); reloader->setWorkingDirectory(workingDirectory); reloader->setDiffType(GitDiffEditorReloader::DiffFile); @@ -1000,7 +1002,7 @@ void GitClient::diff(const QString &workingDirectory, const QString &fileName) diffEditorDocument->controller()->requestReload(); - Core::EditorManager::activateEditorForDocument(diffEditorDocument); + EditorManager::activateEditorForDocument(diffEditorDocument); } void GitClient::diffBranch(const QString &workingDirectory, @@ -1013,9 +1015,9 @@ void GitClient::diffBranch(const QString &workingDirectory, if (!diffEditorDocument) { diffEditorDocument = createDiffEditor(documentId, workingDirectory, title); - GitDiffEditorReloader *reloader = - new GitDiffEditorReloader(diffEditorDocument->controller()); - reloader->setDiffEditorController(diffEditorDocument->controller()); + DiffEditor::DiffEditorController *controller = diffEditorDocument->controller(); + GitDiffEditorReloader *reloader = new GitDiffEditorReloader(controller); + controller->setReloader(reloader); reloader->setWorkingDirectory(workingDirectory); reloader->setDiffType(GitDiffEditorReloader::DiffBranch); @@ -1024,7 +1026,7 @@ void GitClient::diffBranch(const QString &workingDirectory, diffEditorDocument->controller()->requestReload(); - Core::EditorManager::activateEditorForDocument(diffEditorDocument); + EditorManager::activateEditorForDocument(diffEditorDocument); } void GitClient::merge(const QString &workingDirectory, @@ -1051,7 +1053,7 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName, { const QString msgArg = fileName.isEmpty() ? workingDirectory : fileName; const QString title = tr("Git Log \"%1\"").arg(msgArg); - const Core::Id editorId = Git::Constants::GIT_LOG_EDITOR_ID; + const Id editorId = Git::Constants::GIT_LOG_EDITOR_ID; const QString sourceFile = VcsBase::VcsBaseEditorWidget::getSource(workingDirectory, fileName); VcsBase::VcsBaseEditorWidget *editor = findExistingVCSEditor("logFileName", sourceFile); if (!editor) @@ -1086,7 +1088,7 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName, void GitClient::reflog(const QString &workingDirectory) { const QString title = tr("Git Reflog \"%1\"").arg(workingDirectory); - const Core::Id editorId = Git::Constants::GIT_LOG_EDITOR_ID; + const Id editorId = Git::Constants::GIT_LOG_EDITOR_ID; VcsBase::VcsBaseEditorWidget *editor = findExistingVCSEditor("reflogRepository", workingDirectory); if (!editor) { editor = createVcsEditor(editorId, title, workingDirectory, CodecLogOutput, @@ -1129,8 +1131,11 @@ void GitClient::show(const QString &source, const QString &id, const QString &na const QString title = tr("Git Show \"%1\"").arg(name.isEmpty() ? id : name); const QFileInfo sourceFi(source); - const QString workingDirectory = sourceFi.isDir() + QString workingDirectory = sourceFi.isDir() ? sourceFi.absoluteFilePath() : sourceFi.absolutePath(); + const QString repoDirectory = VcsManager::findTopLevelForDirectory(workingDirectory); + if (!repoDirectory.isEmpty()) + workingDirectory = repoDirectory; const QString documentId = QLatin1String("Show:") + id; DiffEditor::DiffEditorDocument *diffEditorDocument = DiffEditor::DiffEditorManager::find(documentId); @@ -1142,9 +1147,9 @@ void GitClient::show(const QString &source, const QString &id, const QString &na diffEditorDocument->controller()->setDescriptionEnabled(true); - GitDiffEditorReloader *reloader = - new GitDiffEditorReloader(diffEditorDocument->controller()); - reloader->setDiffEditorController(diffEditorDocument->controller()); + DiffEditor::DiffEditorController *controller = diffEditorDocument->controller(); + GitDiffEditorReloader *reloader = new GitDiffEditorReloader(controller); + controller->setReloader(reloader); reloader->setWorkingDirectory(workingDirectory); reloader->setDiffType(GitDiffEditorReloader::DiffShow); @@ -1154,12 +1159,12 @@ void GitClient::show(const QString &source, const QString &id, const QString &na diffEditorDocument->controller()->requestReload(); - Core::EditorManager::activateEditorForDocument(diffEditorDocument); + EditorManager::activateEditorForDocument(diffEditorDocument); } void GitClient::saveSettings() { - settings()->writeSettings(Core::ICore::settings()); + settings()->writeSettings(ICore::settings()); } void GitClient::slotBlameRevisionRequested(const QString &workingDirectory, const QString &file, @@ -1185,7 +1190,7 @@ void GitClient::blame(const QString &workingDirectory, const QString &revision, int lineNumber) { - const Core::Id editorId = Git::Constants::GIT_BLAME_EDITOR_ID; + const Id editorId = Git::Constants::GIT_BLAME_EDITOR_ID; const QString id = VcsBase::VcsBaseEditorWidget::getTitleId(workingDirectory, QStringList(fileName), revision); const QString title = tr("Git Blame \"%1\"").arg(id); const QString sourceFile = VcsBase::VcsBaseEditorWidget::getSource(workingDirectory, fileName); @@ -1239,7 +1244,7 @@ QStringList GitClient::setupCheckoutArguments(const QString &workingDirectory, if (localBranches.contains(ref)) return arguments; - if (QMessageBox::question(Core::ICore::mainWindow(), tr("Create Local Branch"), + if (QMessageBox::question(ICore::mainWindow(), tr("Create Local Branch"), tr("Would you like to create a local branch?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { return arguments; @@ -1272,7 +1277,7 @@ QStringList GitClient::setupCheckoutArguments(const QString &workingDirectory, } } - BranchAddDialog branchAddDialog(localBranches, true, Core::ICore::mainWindow()); + BranchAddDialog branchAddDialog(localBranches, true, ICore::mainWindow()); branchAddDialog.setTrackedBranchName(remoteBranch, true); if (branchAddDialog.exec() != QDialog::Accepted) @@ -1431,7 +1436,7 @@ bool GitClient::synchronousInit(const QString &workingDirectory) outputWindow()->appendError(commandOutputFromLocal8Bit(errorText)); } else { // TODO: Turn this into a VcsBaseClient and use resetCachedVcsInfo(...) - Core::VcsManager::resetVersionControlForDirectory(workingDirectory); + VcsManager::resetVersionControlForDirectory(workingDirectory); } return rc; } @@ -1745,14 +1750,14 @@ void GitClient::branchesForCommit(const QString &revision) arguments << QLatin1String("branch") << QLatin1String(noColorOption) << QLatin1String("-a") << QLatin1String("--contains") << revision; - DiffEditor::DiffEditorController *editorController + DiffEditor::DiffEditorController *controller = qobject_cast(sender()); - QString workingDirectory = editorController->workingDirectory(); + QString workingDirectory = controller->workingDirectory(); VcsBase::Command *command = new VcsBase::Command(gitBinaryPath(), workingDirectory, processEnvironment()); command->setCodec(getSourceCodec(currentDocumentPath())); - connect(command, SIGNAL(output(QString)), editorController, + connect(command, SIGNAL(output(QString)), controller, SLOT(branchesForCommitReceived(QString))); command->addJob(arguments, -1); @@ -1839,7 +1844,7 @@ QString GitClient::synchronousStash(const QString &workingDirectory, const QStri message = creatorStashMessage(messageKeyword); do { if ((flags & StashPromptDescription)) { - if (!inputText(Core::ICore::mainWindow(), + if (!inputText(ICore::mainWindow(), tr("Stash Description"), tr("Description:"), &message)) break; } @@ -2210,7 +2215,7 @@ QProcessEnvironment GitClient::processEnvironment() const bool GitClient::beginStashScope(const QString &workingDirectory, const QString &command, StashFlag flag, PushAction pushAction) { - const QString repoDirectory = findRepositoryForDirectory(workingDirectory); + const QString repoDirectory = VcsManager::findTopLevelForDirectory(workingDirectory); QTC_ASSERT(!repoDirectory.isEmpty(), return false); StashInfo &stashInfo = m_stashInfo[repoDirectory]; return stashInfo.init(repoDirectory, command, flag, pushAction); @@ -2218,14 +2223,14 @@ bool GitClient::beginStashScope(const QString &workingDirectory, const QString & GitClient::StashInfo &GitClient::stashInfo(const QString &workingDirectory) { - const QString repoDirectory = findRepositoryForDirectory(workingDirectory); + const QString repoDirectory = VcsManager::findTopLevelForDirectory(workingDirectory); QTC_CHECK(m_stashInfo.contains(repoDirectory)); return m_stashInfo[repoDirectory]; } void GitClient::endStashScope(const QString &workingDirectory) { - const QString repoDirectory = findRepositoryForDirectory(workingDirectory); + const QString repoDirectory = VcsManager::findTopLevelForDirectory(workingDirectory); QTC_ASSERT(m_stashInfo.contains(repoDirectory), return); m_stashInfo[repoDirectory].end(); } @@ -2284,7 +2289,7 @@ void GitClient::updateSubmodulesIfNeeded(const QString &workingDirectory, bool p if (!updateNeeded) return; - if (prompt && QMessageBox::question(Core::ICore::mainWindow(), tr("Submodules Found"), + if (prompt && QMessageBox::question(ICore::mainWindow(), tr("Submodules Found"), tr("Would you like to update submodules?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { return; @@ -2463,7 +2468,7 @@ void GitClient::continuePreviousGitCommand(const QString &workingDirectory, } QMessageBox msgBox(QMessageBox::Question, msgBoxTitle, msgBoxText, - QMessageBox::NoButton, Core::ICore::mainWindow()); + QMessageBox::NoButton, ICore::mainWindow()); if (hasChanges || isRebase) msgBox.addButton(hasChanges ? buttonName : tr("Skip"), QMessageBox::AcceptRole); msgBox.addButton(QMessageBox::Abort); @@ -2689,7 +2694,7 @@ bool GitClient::getCommitData(const QString &workingDirectory, commitData.clear(); // Find repo - const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory); + const QString repoDirectory = VcsManager::findTopLevelForDirectory(workingDirectory); if (repoDirectory.isEmpty()) { *errorMessage = msgRepositoryNotFound(workingDirectory); return false; @@ -2944,7 +2949,7 @@ GitClient::RevertResult GitClient::revertI(QStringList files, *ptrToIsDirectory = isDirectory; const QString workingDirectory = isDirectory ? firstFile.absoluteFilePath() : firstFile.absolutePath(); - const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory); + const QString repoDirectory = VcsManager::findTopLevelForDirectory(workingDirectory); if (repoDirectory.isEmpty()) { *errorMessage = msgRepositoryNotFound(workingDirectory); return RevertFailed; @@ -2992,7 +2997,7 @@ GitClient::RevertResult GitClient::revertI(QStringList files, // Ask to revert (to do: Handle lists with a selection dialog) const QMessageBox::StandardButton answer - = QMessageBox::question(Core::ICore::mainWindow(), + = QMessageBox::question(ICore::mainWindow(), tr("Revert"), tr("The file has been changed. Do you want to revert it?"), QMessageBox::Yes | QMessageBox::No, @@ -3085,7 +3090,8 @@ void GitClient::synchronousAbortCommand(const QString &workingDir, const QString // Abort to clean if something goes wrong if (abortCommand.isEmpty()) { // no abort command - checkout index to clean working copy. - synchronousCheckoutFiles(findRepositoryForDirectory(workingDir), QStringList(), QString(), 0, false); + synchronousCheckoutFiles(VcsManager::findTopLevelForDirectory(workingDir), + QStringList(), QString(), 0, false); return; } VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance(); @@ -3147,7 +3153,7 @@ void GitClient::handleMergeConflicts(const QString &workingDir, const QString &c else message = tr("Conflicts detected."); QMessageBox mergeOrAbort(QMessageBox::Question, tr("Conflicts Detected"), message, - QMessageBox::NoButton, Core::ICore::mainWindow()); + QMessageBox::NoButton, ICore::mainWindow()); QPushButton *mergeToolButton = mergeOrAbort.addButton(tr("Run &Merge Tool"), QMessageBox::AcceptRole); mergeOrAbort.addButton(QMessageBox::Ignore); @@ -3198,7 +3204,7 @@ void GitClient::subversionLog(const QString &workingDirectory) // Create a command editor, no highlighting or interaction. const QString title = tr("Git SVN Log"); - const Core::Id editorId = Git::Constants::C_GIT_COMMAND_LOG_EDITOR; + const Id editorId = Git::Constants::C_GIT_COMMAND_LOG_EDITOR; const QString sourceFile = VcsBase::VcsBaseEditorWidget::getSource(workingDirectory, QStringList()); VcsBase::VcsBaseEditorWidget *editor = findExistingVCSEditor("svnLog", sourceFile); if (!editor) @@ -3473,7 +3479,7 @@ bool GitClient::cloneRepository(const QString &directory,const QByteArray &url) const Utils::SynchronousProcessResponse resp = synchronousGit(workingDirectory.path(), arguments, flags); // TODO: Turn this into a VcsBaseClient and use resetCachedVcsInfo(...) - Core::VcsManager::resetVersionControlForDirectory(workingDirectory.absolutePath()); + VcsManager::resetVersionControlForDirectory(workingDirectory.absolutePath()); return (resp.result == Utils::SynchronousProcessResponse::Finished); } } @@ -3582,7 +3588,7 @@ void GitClient::StashInfo::stashPrompt(const QString &command, const QString &st tr("What would you like to do with local changes in:") + QLatin1String("\n\n\"") + QDir::toNativeSeparators(m_workingDir) + QLatin1Char('\"'), - QMessageBox::NoButton, Core::ICore::mainWindow()); + QMessageBox::NoButton, ICore::mainWindow()); msgBox.setDetailedText(statusOutput); diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index d2d24541d57..9c54da4f941 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -434,7 +434,7 @@ private: bool m_disableEditor; int m_contextDiffFileIndex; int m_contextChunkIndex; - QPointer m_contextDocument; + QPointer m_contextController; QFutureSynchronizer m_synchronizer; // for commit updates }; diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 468c5412381..edde549c247 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -206,15 +206,13 @@ void GitEditor::commandFinishedGotoLine(bool ok, int exitCode, const QVariant &v void GitEditor::checkoutChange() { - const QFileInfo fi(source()); - const QString workingDirectory = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); - GitPlugin::instance()->gitClient()->stashAndCheckout(workingDirectory, m_currentChange); + GitPlugin::instance()->gitClient()->stashAndCheckout( + sourceWorkingDirectory(), m_currentChange); } void GitEditor::resetChange() { - const QFileInfo fi(source()); - const QString workingDir = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); + const QString workingDir = sourceWorkingDirectory(); GitClient *client = GitPlugin::instance()->gitClient(); if (client->gitStatus(workingDir, StatusMode(NoUntracked | NoSubmodules)) @@ -232,16 +230,14 @@ void GitEditor::resetChange() void GitEditor::cherryPickChange() { - const QFileInfo fi(source()); - const QString workingDirectory = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); - GitPlugin::instance()->gitClient()->synchronousCherryPick(workingDirectory, m_currentChange); + GitPlugin::instance()->gitClient()->synchronousCherryPick( + sourceWorkingDirectory(), m_currentChange); } void GitEditor::revertChange() { - const QFileInfo fi(source()); - const QString workingDirectory = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); - GitPlugin::instance()->gitClient()->synchronousRevert(workingDirectory, m_currentChange); + GitPlugin::instance()->gitClient()->synchronousRevert( + sourceWorkingDirectory(), m_currentChange); } void GitEditor::stageDiffChunk() @@ -402,5 +398,11 @@ QString GitEditor::fileNameForLine(int line) const return source(); } +QString GitEditor::sourceWorkingDirectory() const +{ + const QFileInfo fi(source()); + return fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); +} + } // namespace Internal } // namespace Git diff --git a/src/plugins/git/giteditor.h b/src/plugins/git/giteditor.h index 35bfd53ef34..9247d7f46fa 100644 --- a/src/plugins/git/giteditor.h +++ b/src/plugins/git/giteditor.h @@ -77,6 +77,7 @@ private: QString revisionSubject(const QTextBlock &inBlock) const; bool supportChangeLinks() const; QString fileNameForLine(int line) const; + QString sourceWorkingDirectory() const; mutable QRegExp m_changeNumberPattern; QString m_currentChange; diff --git a/src/plugins/ios/ios.qbs b/src/plugins/ios/ios.qbs index a237ad7c5cf..dbfd995eb27 100644 --- a/src/plugins/ios/ios.qbs +++ b/src/plugins/ios/ios.qbs @@ -4,7 +4,6 @@ import QtcPlugin QtcPlugin { name: "Ios" - condition: qbs.targetOS.contains("osx") Depends { name: "Core" } Depends { name: "ProjectExplorer" } @@ -16,7 +15,7 @@ QtcPlugin { Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] } cpp.includePaths: base.concat("../../shared") - cpp.frameworks: base.concat(["CoreFoundation", "IOKit"]) + cpp.frameworks: base.concat(qbs.targetOS.contains("osx") ? ["CoreFoundation", "IOKit"] : []) files: [ "ios.qrc", diff --git a/src/plugins/ios/iosbuildstep.cpp b/src/plugins/ios/iosbuildstep.cpp index 529c097798b..78c225ab714 100644 --- a/src/plugins/ios/iosbuildstep.cpp +++ b/src/plugins/ios/iosbuildstep.cpp @@ -198,8 +198,8 @@ QStringList IosBuildStep::defaultArguments() const case BuildConfiguration::Unknown : break; default: - qDebug() << "IosBuildStep had an unknown buildType " - << target()->activeBuildConfiguration()->buildType(); + qCWarning(iosLog) << "IosBuildStep had an unknown buildType " + << target()->activeBuildConfiguration()->buildType(); } if (tc->type() == QLatin1String("gcc") || tc->type() == QLatin1String("clang")) { GccToolChain *gtc = static_cast(tc); diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index cfbd575510d..87da1bdc8a8 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -61,7 +61,9 @@ using namespace QtSupport; using namespace Utils; using namespace Debugger; -const bool debugProbe = false; +namespace { +Q_LOGGING_CATEGORY(kitSetupLog, "qtc.ios.kitSetup") +} namespace Ios { namespace Internal { @@ -84,9 +86,8 @@ void IosConfigurations::updateAutomaticKitList() || !p.compilerPath.toString().contains(QLatin1String("clang"))) iter = platforms.erase(iter); else { - if (debugProbe) - qDebug() << "keeping" << p.name << " " << p.compilerPath.toString() << " " - << p.backendFlags; + qCDebug(kitSetupLog) << "keeping" << p.name << " " << p.compilerPath.toString() << " " + << p.backendFlags; ++iter; } } @@ -123,20 +124,18 @@ void IosConfigurations::updateAutomaticKitList() found = true; if (p.architecture == QLatin1String("i386") && toolchain->targetAbi().wordWidth() != 32) { - if (debugProbe) - qDebug() << "resetting api of " << toolchain->displayName(); + qCDebug(kitSetupLog) << "resetting api of " << toolchain->displayName(); toolchain->setTargetAbi(Abi(Abi::X86Architecture, Abi::MacOS, Abi::GenericMacFlavor, Abi::MachOFormat, 32)); } platformToolchainMap[p.name] = toolchain; - if (debugProbe) - qDebug() << p.name << " -> " << toolchain->displayName(); + qCDebug(kitSetupLog) << p.name << " -> " << toolchain->displayName(); } } if (!found && (tc->displayName().startsWith(QLatin1String("iphone")) || tc->displayName().startsWith(QLatin1String("mac")))) { - qDebug() << "removing toolchain" << tc->displayName(); + qCWarning(kitSetupLog) << "removing toolchain" << tc->displayName(); ToolChainManager::deregisterToolChain(tc); } } @@ -173,13 +172,11 @@ void IosConfigurations::updateAutomaticKitList() toolchain->setPlatformLinkerFlags(p.backendFlags); toolchain->setCompilerCommand(p.compilerPath); if (p.architecture == QLatin1String("i386")) { - if (debugProbe) - qDebug() << "setting toolchain Abi for " << toolchain->displayName(); + qCDebug(kitSetupLog) << "setting toolchain Abi for " << toolchain->displayName(); toolchain->setTargetAbi(Abi(Abi::X86Architecture,Abi::MacOS, Abi::GenericMacFlavor, Abi::MachOFormat, 32)); } - if (debugProbe) - qDebug() << "adding toolchain " << p.name; + qCDebug(kitSetupLog) << "adding toolchain " << p.name; ToolChainManager::registerToolChain(toolchain); platformToolchainMap.insert(p.name, toolchain); QMapIterator iter2(iter); @@ -196,8 +193,7 @@ void IosConfigurations::updateAutomaticKitList() } QMap > qtVersionsForArch; foreach (BaseQtVersion *qtVersion, QtVersionManager::versions()) { - if (debugProbe) - qDebug() << "qt type " << qtVersion->type(); + qCDebug(kitSetupLog) << "qt type " << qtVersion->type(); if (qtVersion->type() != QLatin1String(Constants::IOSQT)) { if (qtVersion->qmakeProperty("QMAKE_PLATFORM").contains(QLatin1String("ios")) || qtVersion->qmakeProperty("QMAKE_XSPEC").contains(QLatin1String("ios"))) { @@ -208,8 +204,7 @@ void IosConfigurations::updateAutomaticKitList() qtVersion->isAutodetected(), qtVersion->autodetectionSource()); if (iosVersion && iosVersion->type() == QLatin1String(Constants::IOSQT)) { - if (debugProbe) - qDebug() << "converting QT to iOS QT for " << qtVersion->qmakeCommand().toUserOutput(); + qCDebug(kitSetupLog) << "converting QT to iOS QT for " << qtVersion->qmakeCommand().toUserOutput(); QtVersionManager::removeVersion(qtVersion); QtVersionManager::addVersion(iosVersion); qtVersion = iosVersion; @@ -225,8 +220,7 @@ void IosConfigurations::updateAutomaticKitList() QList qtAbis = qtVersion->qtAbis(); if (qtAbis.empty()) continue; - if (debugProbe) - qDebug() << "qt arch " << qtAbis.first().architecture(); + qCDebug(kitSetupLog) << "qt arch " << qtAbis.first().architecture(); foreach (const Abi &abi, qtAbis) qtVersionsForArch[abi.architecture()].append(qtVersion); } @@ -240,8 +234,7 @@ void IosConfigurations::updateAutomaticKitList() Core::Id deviceKind = DeviceTypeKitInformation::deviceTypeId(k); if (deviceKind != Constants::IOS_DEVICE_TYPE && deviceKind != Constants::IOS_SIMULATOR_TYPE) { - if (debugProbe) - qDebug() << "skipping existing kit with deviceKind " << deviceKind.toString(); + qCDebug(kitSetupLog) << "skipping existing kit with deviceKind " << deviceKind.toString(); continue; } if (!k->isAutoDetected()) @@ -259,17 +252,14 @@ void IosConfigurations::updateAutomaticKitList() if (!pToolchain) continue; Core::Id pDeviceType; - if (debugProbe) - qDebug() << "guaranteeing kit for " << p.name ; + qCDebug(kitSetupLog) << "guaranteeing kit for " << p.name ; if (p.name.startsWith(QLatin1String("iphoneos-"))) { pDeviceType = Constants::IOS_DEVICE_TYPE; } else if (p.name.startsWith(QLatin1String("iphonesimulator-"))) { pDeviceType = Constants::IOS_SIMULATOR_TYPE; - if (debugProbe) - qDebug() << "pDeviceType " << pDeviceType.toString(); + qCDebug(kitSetupLog) << "pDeviceType " << pDeviceType.toString(); } else { - if (debugProbe) - qDebug() << "skipping non ios kit " << p.name; + qCDebug(kitSetupLog) << "skipping non ios kit " << p.name; // we looked up only the ios qt build above... continue; //pDeviceType = Constants::DESKTOP_DEVICE_TYPE; @@ -292,9 +282,8 @@ void IosConfigurations::updateAutomaticKitList() // new Xcode is used). Change? kitExists = true; kitAtt = k; - if (debugProbe) - qDebug() << "found existing kit " << k->displayName() << " for " << p.name - << "," << qt->displayName(); + qCDebug(kitSetupLog) << "found existing kit " << k->displayName() << " for " << p.name + << "," << qt->displayName(); if (iblockNotification(); } else { - if (debugProbe) - qDebug() << "setting up new kit for " << p.name; + qCDebug(kitSetupLog) << "setting up new kit for " << p.name; kitAtt = new Kit; kitAtt->setAutoDetected(true); QString baseDisplayName = tr("%1 %2").arg(p.name, qt->displayName()); @@ -356,7 +344,7 @@ void IosConfigurations::updateAutomaticKitList() for (int i = 0; i < kitMatched.size(); ++i) { // deleting extra (old) kits if (!kitMatched.at(i)) { - qDebug() << "deleting kit " << existingKits.at(i)->displayName(); + qCWarning(kitSetupLog) << "deleting kit " << existingKits.at(i)->displayName(); KitManager::deregisterKit(existingKits.at(i)); } } diff --git a/src/plugins/ios/iosconstants.h b/src/plugins/ios/iosconstants.h index ccee6040d14..00ecdcd7cb5 100644 --- a/src/plugins/ios/iosconstants.h +++ b/src/plugins/ios/iosconstants.h @@ -30,10 +30,11 @@ #define IOSCONSTANTS_H #include +#include namespace Ios { namespace Internal { - +Q_DECLARE_LOGGING_CATEGORY(iosLog) } // namespace Internal namespace IosDeviceType { diff --git a/src/plugins/ios/iosdeploystepfactory.h b/src/plugins/ios/iosdeploystepfactory.h index 503cd82be82..e6288e981f1 100644 --- a/src/plugins/ios/iosdeploystepfactory.h +++ b/src/plugins/ios/iosdeploystepfactory.h @@ -45,7 +45,7 @@ public: QString displayNameForId(Core::Id id) const QTC_OVERRIDE; bool canCreate(ProjectExplorer::BuildStepList *parent, - const Core::Id id) const QTC_OVERRIDE; + Core::Id id) const QTC_OVERRIDE; ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, Core::Id id) QTC_OVERRIDE; bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const QTC_OVERRIDE; diff --git a/src/plugins/ios/iosdevice.cpp b/src/plugins/ios/iosdevice.cpp index b8fa1de7fe3..8bd85c71b8f 100644 --- a/src/plugins/ios/iosdevice.cpp +++ b/src/plugins/ios/iosdevice.cpp @@ -51,7 +51,9 @@ using namespace ProjectExplorer; -static bool debugDeviceDetection = false; +namespace { +Q_LOGGING_CATEGORY(detectLog, "qtc.ios.deviceDetect") +} #ifdef Q_OS_MAC static QString CFStringRef2QString(CFStringRef s) @@ -247,13 +249,11 @@ void IosDeviceManager::deviceConnected(const QString &uid, const QString &name) IosDevice *newDev = new IosDevice(uid); if (!name.isNull()) newDev->setDisplayName(name); - if (debugDeviceDetection) - qDebug() << "adding ios device " << uid; + qCDebug(detectLog) << "adding ios device " << uid; devManager->addDevice(IDevice::ConstPtr(newDev)); } else if (dev->deviceState() != IDevice::DeviceConnected && dev->deviceState() != IDevice::DeviceReadyToUse) { - if (debugDeviceDetection) - qDebug() << "updating ios device " << uid; + qCDebug(detectLog) << "updating ios device " << uid; IosDevice *newDev = 0; if (dev->type() == devType) { const IosDevice *iosDev = static_cast(dev.data()); @@ -268,23 +268,21 @@ void IosDeviceManager::deviceConnected(const QString &uid, const QString &name) void IosDeviceManager::deviceDisconnected(const QString &uid) { - if (debugDeviceDetection) - qDebug() << "detected disconnection of ios device " << uid; + qCDebug(detectLog) << "detected disconnection of ios device " << uid; DeviceManager *devManager = DeviceManager::instance(); Core::Id baseDevId(Constants::IOS_DEVICE_ID); Core::Id devType(Constants::IOS_DEVICE_TYPE); Core::Id devId = baseDevId.withSuffix(uid); IDevice::ConstPtr dev = devManager->find(devId); if (dev.isNull() || dev->type() != devType) { - qDebug() << "ignoring disconnection of ios device " << uid; // should neve happen + qCWarning(detectLog) << "ignoring disconnection of ios device " << uid; // should neve happen } else { const IosDevice *iosDev = static_cast(dev.data()); if (iosDev->m_extraInfo.isEmpty() || iosDev->m_extraInfo.value(QLatin1String("deviceName")) == QLatin1String("*unknown*")) { devManager->removeDevice(iosDev->id()); } else if (iosDev->deviceState() != IDevice::DeviceDisconnected) { - if (debugDeviceDetection) - qDebug() << "disconnecting device " << iosDev->uniqueDeviceID(); + qCDebug(detectLog) << "disconnecting device " << iosDev->uniqueDeviceID(); devManager->setDeviceState(iosDev->id(), IDevice::DeviceDisconnected); } } @@ -326,8 +324,7 @@ void IosDeviceManager::deviceInfo(IosToolHandler *, const QString &uid, if (info.contains(devNameKey)) newDev->setDisplayName(info.value(devNameKey)); newDev->m_extraInfo = info; - if (debugDeviceDetection) - qDebug() << "updated info of ios device " << uid; + qCDebug(detectLog) << "updated info of ios device " << uid; dev = IDevice::ConstPtr(newDev); devManager->addDevice(dev); } @@ -397,8 +394,7 @@ void deviceConnectedCallback(void *refCon, io_iterator_t iterator) QString name; if (KERN_SUCCESS == kr) name = QString::fromLocal8Bit(deviceName); - if (debugDeviceDetection) - qDebug() << "ios device " << name << " in deviceAddedCallback"; + qCDebug(detectLog) << "ios device " << name << " in deviceAddedCallback"; CFStringRef cfUid = static_cast(IORegistryEntryCreateCFProperty( usbDevice, @@ -413,10 +409,10 @@ void deviceConnectedCallback(void *refCon, io_iterator_t iterator) } } catch (std::exception &e) { - qDebug() << "Exception " << e.what() << " in iosdevice.cpp deviceConnectedCallback"; + qCWarning(detectLog) << "Exception " << e.what() << " in iosdevice.cpp deviceConnectedCallback"; } catch (...) { - qDebug() << "Exception in iosdevice.cpp deviceConnectedCallback"; + qCWarning(detectLog) << "Exception in iosdevice.cpp deviceConnectedCallback"; throw; } } @@ -435,8 +431,7 @@ void deviceDisconnectedCallback(void *refCon, io_iterator_t iterator) kr = IORegistryEntryGetName(usbDevice, deviceName); if (KERN_SUCCESS != kr) deviceName[0] = '\0'; - if (debugDeviceDetection) - qDebug() << "ios device " << deviceName << " in deviceDisconnectedCallback"; + qCDebug(detectLog) << "ios device " << deviceName << " in deviceDisconnectedCallback"; { CFStringRef cfUid = static_cast(IORegistryEntryCreateCFProperty( @@ -453,10 +448,10 @@ void deviceDisconnectedCallback(void *refCon, io_iterator_t iterator) } } catch (std::exception &e) { - qDebug() << "Exception " << e.what() << " in iosdevice.cpp deviceDisconnectedCallback"; + qCWarning(detectLog) << "Exception " << e.what() << " in iosdevice.cpp deviceDisconnectedCallback"; } catch (...) { - qDebug() << "Exception in iosdevice.cpp deviceDisconnectedCallback"; + qCWarning(detectLog) << "Exception in iosdevice.cpp deviceDisconnectedCallback"; throw; } } @@ -557,8 +552,7 @@ void IosDeviceManager::updateAvailableDevices(const QStringList &devices) if (devices.contains(iosDev->uniqueDeviceID())) continue; if (iosDev->deviceState() != IDevice::DeviceDisconnected) { - if (debugDeviceDetection) - qDebug() << "disconnecting device " << iosDev->uniqueDeviceID(); + qCDebug(detectLog) << "disconnecting device " << iosDev->uniqueDeviceID(); devManager->setDeviceState(iosDev->id(), IDevice::DeviceDisconnected); } } diff --git a/src/plugins/ios/iosplugin.cpp b/src/plugins/ios/iosplugin.cpp index fecc921b567..b039fa58797 100644 --- a/src/plugins/ios/iosplugin.cpp +++ b/src/plugins/ios/iosplugin.cpp @@ -52,6 +52,9 @@ #include namespace Ios { +namespace Internal { +Q_LOGGING_CATEGORY(iosLog, "qtc.ios.common") +} IosPlugin::IosPlugin() { diff --git a/src/plugins/ios/iosprobe.cpp b/src/plugins/ios/iosprobe.cpp index b628e2190fb..54c01975cd0 100644 --- a/src/plugins/ios/iosprobe.cpp +++ b/src/plugins/ios/iosprobe.cpp @@ -29,14 +29,16 @@ #include "iosprobe.h" -#include +#include + #include #include #include #include -static const bool debugProbe = false; - +namespace { +Q_LOGGING_CATEGORY(probeLog, "qtc.ios.probe") +} namespace Ios { static QString qsystem(const QString &exe, const QStringList &args = QStringList()) @@ -66,7 +68,7 @@ static int compareVersions(const QString &v1, const QString &v2) int n1 = v1L.value(i).toInt(&n1Ok); int n2 = v2L.value(i).toInt(&n2Ok); if (!(n1Ok && n2Ok)) { - qDebug() << QString::fromLatin1("Failed to compare version %1 and %2").arg(v1, v2); + qCWarning(probeLog) << QString::fromLatin1("Failed to compare version %1 and %2").arg(v1, v2); return 0; } if (n1 > n2) @@ -92,8 +94,7 @@ void IosProbe::addDeveloperPath(const QString &path) if (m_developerPaths.contains(path)) return; m_developerPaths.append(path); - if (debugProbe) - qDebug() << QString::fromLatin1("Added developer path %1").arg(path); + qCDebug(probeLog) << QString::fromLatin1("Added developer path %1").arg(path); } void IosProbe::detectDeveloperPaths() @@ -103,7 +104,7 @@ void IosProbe::detectDeveloperPaths() QStringList arguments(QLatin1String("--print-path")); selectedXcode.start(program, arguments, QProcess::ReadOnly); if (!selectedXcode.waitForFinished() || selectedXcode.exitCode()) { - qDebug() << QString::fromLatin1("Could not detect selected xcode with /usr/bin/xcode-select"); + qCWarning(probeLog) << QString::fromLatin1("Could not detect selected xcode with /usr/bin/xcode-select"); } else { QString path = QString::fromLocal8Bit(selectedXcode.readAllStandardOutput()); path.chop(1); @@ -114,8 +115,7 @@ void IosProbe::detectDeveloperPaths() void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xcodeName) { - if (debugProbe) - qDebug() << QString::fromLatin1("Setting up platform \"%1\".").arg(xcodeName); + qCDebug(probeLog) << QString::fromLatin1("Setting up platform \"%1\".").arg(xcodeName); QString indent = QLatin1String(" "); // detect clang (default toolchain) @@ -124,20 +124,19 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco + QLatin1String("/clang++")); bool hasClang = clangFileInfo.exists(); if (!hasClang) - qDebug() << indent << QString::fromLatin1("Default toolchain %1 not found.") - .arg(clangFileInfo.canonicalFilePath()); + qCWarning(probeLog) << indent << QString::fromLatin1("Default toolchain %1 not found.") + .arg(clangFileInfo.canonicalFilePath()); // Platforms QDir platformsDir(devPath + QLatin1String("/Platforms")); QFileInfoList platforms = platformsDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); foreach (const QFileInfo &fInfo, platforms) { if (fInfo.isDir() && fInfo.suffix() == QLatin1String("platform")) { - if (debugProbe) - qDebug() << indent << QString::fromLatin1("Setting up %1").arg(fInfo.fileName()); + qCDebug(probeLog) << indent << QString::fromLatin1("Setting up %1").arg(fInfo.fileName()); QSettingsPtr infoSettings(new QSettings( fInfo.absoluteFilePath() + QLatin1String("/Info.plist"), QSettings::NativeFormat)); if (!infoSettings->contains(QLatin1String("Name"))) { - qDebug() << indent << QString::fromLatin1("Missing platform name in Info.plist of %1") + qCWarning(probeLog) << indent << QString::fromLatin1("Missing platform name in Info.plist of %1") .arg(fInfo.absoluteFilePath()); continue; } @@ -145,7 +144,7 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco if (name != QLatin1String("macosx") && name != QLatin1String("iphoneos") && name != QLatin1String("iphonesimulator")) { - qDebug() << indent << QString::fromLatin1("Skipping unknown platform %1").arg(name); + qCWarning(probeLog) << indent << QString::fromLatin1("Skipping unknown platform %1").arg(name); continue; } @@ -174,7 +173,7 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco if (defaultProp.contains(QLatin1String("NATIVE_ARCH"))) { QString arch = defaultProp.value(QLatin1String("NATIVE_ARCH")).toString(); if (!arch.startsWith(QLatin1String("arm"))) - qDebug() << indent << QString::fromLatin1("Expected arm architecture, not %1").arg(arch); + qCWarning(probeLog) << indent << QString::fromLatin1("Expected arm architecture, not %1").arg(arch); extraFlags << QLatin1String("-arch") << arch; } else if (name == QLatin1String("iphonesimulator")) { // don't generate a toolchain for 64 bit (to fix when we support that) @@ -195,8 +194,7 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-')); clangProfile.architecture = compilerTripletl.value(0); clangProfile.backendFlags = extraFlags; - if (debugProbe) - qDebug() << indent << QString::fromLatin1("* adding profile %1").arg(clangProfile.name); + qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(clangProfile.name); m_platforms[clangProfile.name] = clangProfile; clangProfile.platformKind |= Platform::Cxx11Support; clangProfile.backendFlags.append(QLatin1String("-std=c++11")); @@ -220,8 +218,7 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-')); gccProfile.architecture = compilerTripletl.value(0); gccProfile.backendFlags = extraFlags; - if (debugProbe) - qDebug() << indent << QString::fromLatin1("* adding profile %1").arg(gccProfile.name); + qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(gccProfile.name); m_platforms[gccProfile.name] = gccProfile; } @@ -246,9 +243,8 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco bool isBaseSdk = sdkInfo->value((QLatin1String("isBaseSDK"))).toString() .toLower() != QLatin1String("no"); if (!isBaseSdk) { - if (debugProbe) - qDebug() << indent << QString::fromLatin1("Skipping non base Sdk %1") - .arg(currentSdkName.toString()); + qCDebug(probeLog) << indent << QString::fromLatin1("Skipping non base Sdk %1") + .arg(currentSdkName.toString()); continue; } if (sdkName.isEmpty()) { @@ -265,7 +261,7 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco if (!sdkPath.isEmpty()) sysRoot = sdkPath; else if (!sdkName.isEmpty()) - qDebug() << indent << QString::fromLatin1("Failed to find sysroot %1").arg(sdkName); + qCDebug(probeLog) << indent << QString::fromLatin1("Failed to find sysroot %1").arg(sdkName); } if (hasClang && !sysRoot.isEmpty()) { m_platforms[clangFullName].platformKind |= Platform::BasePlatform; diff --git a/src/plugins/ios/iosqtversionfactory.cpp b/src/plugins/ios/iosqtversionfactory.cpp index 4b2dcd880b6..600010fdfc4 100644 --- a/src/plugins/ios/iosqtversionfactory.cpp +++ b/src/plugins/ios/iosqtversionfactory.cpp @@ -35,7 +35,6 @@ #include #include -#include namespace Ios { namespace Internal { diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp index 85b2d80f45b..0be2fa1063e 100644 --- a/src/plugins/ios/iosrunconfiguration.cpp +++ b/src/plugins/ios/iosrunconfiguration.cpp @@ -28,6 +28,7 @@ ****************************************************************************/ #include "iosrunconfiguration.h" +#include "iosconstants.h" #include "iosmanager.h" #include "iosdeploystep.h" #include "ui_iosrunconfiguration.h" @@ -212,7 +213,7 @@ Utils::FileName IosRunConfiguration::bundleDirectory() const Core::Id devType = DeviceTypeKitInformation::deviceTypeId(target()->kit()); bool isDevice = (devType == Constants::IOS_DEVICE_TYPE); if (!isDevice && devType != Constants::IOS_SIMULATOR_TYPE) { - qDebug() << "unexpected device type in bundleDirForTarget: " << devType.toString(); + qCWarning(iosLog) << "unexpected device type in bundleDirForTarget: " << devType.toString(); return res; } QmakeBuildConfiguration *bc = @@ -246,7 +247,7 @@ Utils::FileName IosRunConfiguration::bundleDirectory() const res.appendPath(QLatin1String("Release-iphonesimulator")); break; default: - qDebug() << "IosBuildStep had an unknown buildType " + qCWarning(iosLog) << "IosBuildStep had an unknown buildType " << target()->activeBuildConfiguration()->buildType(); } } @@ -413,7 +414,7 @@ QStringList IosRunConfigurationWidget::stringToArgList(const QString &args) cons res = QtcProcess::splitArgs(args + QLatin1Char('\"'), OsTypeMac, false, &err); break; case QtcProcess::FoundMeta: - qDebug() << "IosRunConfigurationWidget FoundMeta (should not happen)"; + qCWarning(iosLog) << "IosRunConfigurationWidget FoundMeta (should not happen)"; break; } return res; diff --git a/src/plugins/ios/iosrunfactories.h b/src/plugins/ios/iosrunfactories.h index fceea1f1819..ff3ba59b2c8 100644 --- a/src/plugins/ios/iosrunfactories.h +++ b/src/plugins/ios/iosrunfactories.h @@ -68,7 +68,7 @@ public: ) QTC_OVERRIDE; private: ProjectExplorer::RunConfiguration *doCreate(ProjectExplorer::Target *parent, - const Core::Id id) QTC_OVERRIDE; + Core::Id id) QTC_OVERRIDE; ProjectExplorer::RunConfiguration *doRestore(ProjectExplorer::Target *parent, const QVariantMap &map) QTC_OVERRIDE; }; diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp index 6cd5e66d4e4..2ceff2685c5 100644 --- a/src/plugins/ios/iostoolhandler.cpp +++ b/src/plugins/ios/iostoolhandler.cpp @@ -34,11 +34,11 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -49,7 +49,9 @@ #include #include -static const bool debugToolHandler = false; +namespace { +Q_LOGGING_CATEGORY(toolHandlerLog, "qtc.ios.toolhandler") +} namespace Ios { @@ -220,8 +222,7 @@ IosToolHandlerPrivate::IosToolHandlerPrivate(IosDeviceType::Enum devType, frameworkPaths << QLatin1String("/System/Library/Frameworks") << QLatin1String("/System/Library/PrivateFrameworks"); env.insert(QLatin1String("DYLD_FALLBACK_FRAMEWORK_PATH"), frameworkPaths.join(QLatin1String(":"))); - if (debugToolHandler) - qDebug() << "IosToolHandler runEnv:" << env.toStringList(); + qCDebug(toolHandlerLog) << "IosToolHandler runEnv:" << env.toStringList(); process.setProcessEnvironment(env); QObject::connect(&process, SIGNAL(readyReadStandardOutput()), q, SLOT(subprocessHasData())); QObject::connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), @@ -241,26 +242,24 @@ void IosToolHandlerPrivate::start(const QString &exe, const QStringList &args) { QTC_CHECK(state == NonStarted); state = Starting; - if (debugToolHandler) - qDebug() << "running " << exe << args; + qCDebug(toolHandlerLog) << "running " << exe << args; process.start(exe, args); state = StartedInferior; } void IosToolHandlerPrivate::stop(int errorCode) { - if (debugToolHandler) - qDebug() << "IosToolHandlerPrivate::stop"; + qCDebug(toolHandlerLog) << "IosToolHandlerPrivate::stop"; State oldState = state; state = Stopped; switch (oldState) { case NonStarted: - qDebug() << "IosToolHandler::stop() when state was NonStarted"; + qCWarning(toolHandlerLog) << "IosToolHandler::stop() when state was NonStarted"; // pass case Starting: switch (op){ case OpNone: - qDebug() << "IosToolHandler::stop() when op was OpNone"; + qCWarning(toolHandlerLog) << "IosToolHandler::stop() when op was OpNone"; break; case OpAppTransfer: didTransferApp(bundlePath, deviceId, IosToolHandler::Failure); @@ -343,8 +342,7 @@ void IosToolHandlerPrivate::subprocessError(QProcess::ProcessError error) errorMsg(IosToolHandler::tr("iOS tool Error %1").arg(error)); stop(-1); if (error == QProcess::FailedToStart) { - if (debugToolHandler) - qDebug() << "IosToolHandler::finished(" << this << ")"; + qCDebug(toolHandlerLog) << "IosToolHandler::finished(" << this << ")"; emit q->finished(q); } } @@ -352,8 +350,7 @@ void IosToolHandlerPrivate::subprocessError(QProcess::ProcessError error) void IosToolHandlerPrivate::subprocessFinished(int exitCode, QProcess::ExitStatus exitStatus) { stop((exitStatus == QProcess::NormalExit) ? exitCode : -1 ); - if (debugToolHandler) - qDebug() << "IosToolHandler::finished(" << this << ")"; + qCDebug(toolHandlerLog) << "IosToolHandler::finished(" << this << ")"; killTimer.stop(); emit q->finished(q); } @@ -362,7 +359,7 @@ void IosToolHandlerPrivate::processXml() { while (!outputParser.atEnd()) { QXmlStreamReader::TokenType tt = outputParser.readNext(); - //qDebug() << "processXml, tt=" << tt; + //qCDebug(toolHandlerLog) << "processXml, tt=" << tt; switch (tt) { case QXmlStreamReader::NoToken: // The reader has not yet read anything. @@ -449,7 +446,7 @@ void IosToolHandlerPrivate::processXml() int qmlServerPort = attributes.value(QLatin1String("qml_server")).toString().toInt(); gotServerPorts(bundlePath, deviceId, gdbServerPort, qmlServerPort); } else { - qDebug() << "unexpected element " << elName; + qCWarning(toolHandlerLog) << "unexpected element " << elName; } break; } @@ -533,19 +530,18 @@ void IosToolHandlerPrivate::processXml() } if (outputParser.hasError() && outputParser.error() != QXmlStreamReader::PrematureEndOfDocumentError) { - qDebug() << "error parsing iosTool output:" << outputParser.errorString(); + qCWarning(toolHandlerLog) << "error parsing iosTool output:" << outputParser.errorString(); stop(-1); } } void IosToolHandlerPrivate::subprocessHasData() { - if (debugToolHandler) - qDebug() << "subprocessHasData, state:" << state; + qCDebug(toolHandlerLog) << "subprocessHasData, state:" << state; while (true) { switch (state) { case NonStarted: - qDebug() << "IosToolHandler unexpected state in subprocessHasData: NonStarted"; + qCWarning(toolHandlerLog) << "IosToolHandler unexpected state in subprocessHasData: NonStarted"; // pass case Starting: case StartedInferior: @@ -560,8 +556,7 @@ void IosToolHandlerPrivate::subprocessHasData() } if (rRead == 0) return; - if (debugToolHandler) - qDebug() << "subprocessHasData read " << QByteArray(buf, rRead); + qCDebug(toolHandlerLog) << "subprocessHasData read " << QByteArray(buf, rRead); outputParser.addData(QByteArray(buf, rRead)); processXml(); } @@ -697,7 +692,7 @@ void IosSimulatorToolHandlerPrivate::addDeviceArguments(QStringList &args) const { switch (devType) { case IosDeviceType::IosDevice: - qDebug() << "IosSimulatorToolHandlerPrivate has device type IosDeviceType"; + qCWarning(toolHandlerLog) << "IosSimulatorToolHandlerPrivate has device type IosDeviceType"; break; case IosDeviceType::SimulatedIphone: args << QLatin1String("--family") << QLatin1String("iphone"); diff --git a/src/plugins/locator/Locator.pluginspec.in b/src/plugins/locator/Locator.pluginspec.in deleted file mode 100644 index a67f7977e9f..00000000000 --- a/src/plugins/locator/Locator.pluginspec.in +++ /dev/null @@ -1,16 +0,0 @@ - - Digia Plc - (C) 2014 Digia Plc - -Commercial Usage - -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. - - Qt Creator - Provides the Locator widget and the hooks for Locator filter implementations. - http://www.qt-project.org - diff --git a/src/plugins/locator/locator.pro b/src/plugins/locator/locator.pro deleted file mode 100644 index a293b5ae63a..00000000000 --- a/src/plugins/locator/locator.pro +++ /dev/null @@ -1,4 +0,0 @@ -DEFINES += LOCATOR_LIBRARY -include(../../qtcreatorplugin.pri) - -SOURCES += locatorplugin.cpp diff --git a/src/plugins/locator/locator.qbs b/src/plugins/locator/locator.qbs deleted file mode 100644 index 0c52b46eed9..00000000000 --- a/src/plugins/locator/locator.qbs +++ /dev/null @@ -1,11 +0,0 @@ -import qbs 1.0 -import qbs.FileInfo - -import QtcPlugin - -QtcPlugin { - name: "Locator" - Depends { name: "Core" } - - files: [ "locatorplugin.cpp" ] -} diff --git a/src/plugins/locator/locator_dependencies.pri b/src/plugins/locator/locator_dependencies.pri deleted file mode 100644 index bb53d187025..00000000000 --- a/src/plugins/locator/locator_dependencies.pri +++ /dev/null @@ -1,2 +0,0 @@ -QTC_PLUGIN_NAME = Locator -QTC_PLUGIN_DEPENDS += diff --git a/src/plugins/locator/locatorplugin.cpp b/src/plugins/locator/locatorplugin.cpp deleted file mode 100644 index 802cedd7c5e..00000000000 --- a/src/plugins/locator/locatorplugin.cpp +++ /dev/null @@ -1,2 +0,0 @@ - -void dummyLocatorPlugin () {} diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index a8d0d6c8807..38173f736aa 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -4,7 +4,6 @@ TEMPLATE = subdirs SUBDIRS = \ coreplugin \ - find \ texteditor \ cppeditor \ bineditor \ @@ -20,7 +19,6 @@ SUBDIRS = \ cpptools \ qtsupport \ qmakeprojectmanager \ - locator \ debugger \ help \ cpaster \ diff --git a/src/plugins/plugins.qbs b/src/plugins/plugins.qbs index 28214e2f825..6bb73380df1 100644 --- a/src/plugins/plugins.qbs +++ b/src/plugins/plugins.qbs @@ -29,7 +29,6 @@ Project { "diffeditor/diffeditor.qbs", "fakevim/fakevim.qbs", "emacskeys/emacskeys.qbs", - "find/find.qbs", "genericprojectmanager/genericprojectmanager.qbs", "git/git.qbs", "glsleditor/glsleditor.qbs", @@ -37,7 +36,6 @@ Project { "help/help.qbs", "imageviewer/imageviewer.qbs", "ios/ios.qbs", - "locator/locator.qbs", "macros/macros.qbs", "mercurial/mercurial.qbs", "perforce/perforce.qbs", diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 33b8fbaa7a6..afd6952e23f 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -919,7 +919,7 @@ bool GccToolChainConfigWidget::isDirtyImpl() const void GccToolChainConfigWidget::makeReadOnlyImpl() { - m_compilerCommand->setEnabled(false); + m_compilerCommand->setReadOnly(true); m_abiWidget->setEnabled(false); m_platformCodeGenFlagsLineEdit->setEnabled(false); m_platformLinkerFlagsLineEdit->setEnabled(false); diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp index 971d262b7fb..b784e8a8ebc 100644 --- a/src/plugins/projectexplorer/projectwindow.cpp +++ b/src/plugins/projectexplorer/projectwindow.cpp @@ -290,8 +290,8 @@ void ProjectWindow::projectUpdated(Project *p) { // Called after a project was configured int index = m_tabWidget->currentIndex(); - deregisterProject(p); - registerProject(p); + if (deregisterProject(p)) // might return false if the project is unloading + registerProject(p); m_tabWidget->setCurrentIndex(index); } @@ -303,8 +303,8 @@ void ProjectWindow::handleKitChanges() foreach (ProjectExplorer::Project *project, projects) { if (m_hasTarget.value(project) != hasTarget(project)) { changed = true; - deregisterProject(project); - registerProject(project); + if (deregisterProject(project)) + registerProject(project); } } if (changed) @@ -354,16 +354,17 @@ void ProjectWindow::registerProject(ProjectExplorer::Project *project) this, SLOT(removedTarget(ProjectExplorer::Target*))); } -void ProjectWindow::deregisterProject(ProjectExplorer::Project *project) +bool ProjectWindow::deregisterProject(ProjectExplorer::Project *project) { int index = m_tabIndexToProject.indexOf(project); if (index < 0) - return; + return false; m_tabIndexToProject.removeAt(index); m_tabWidget->removeTab(index); disconnect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)), this, SLOT(removedTarget(ProjectExplorer::Target*))); + return true; } void ProjectWindow::startupProjectChanged(ProjectExplorer::Project *p) diff --git a/src/plugins/projectexplorer/projectwindow.h b/src/plugins/projectexplorer/projectwindow.h index a45ea75c00d..1bb580f0722 100644 --- a/src/plugins/projectexplorer/projectwindow.h +++ b/src/plugins/projectexplorer/projectwindow.h @@ -89,7 +89,7 @@ private slots: void handleKitChanges(); void showProperties(int index, int subIndex); void registerProject(ProjectExplorer::Project*); - void deregisterProject(ProjectExplorer::Project*); + bool deregisterProject(ProjectExplorer::Project*); void startupProjectChanged(ProjectExplorer::Project *); void removedTarget(ProjectExplorer::Target*); diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 46cdcfab84d..c0d69a8c1b3 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -546,19 +546,18 @@ void QbsProject::updateCppCodeModel(const qbs::ProjectData &prj) list = props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE), QLatin1String(CONFIG_INCLUDEPATHS)); - QStringList grpIncludePaths; - foreach (const QString &p, list) { - const QString cp = FileName::fromUserInput(p).toString(); - grpIncludePaths.append(cp); - } + CppTools::ProjectPart::HeaderPaths grpHeaderPaths; + foreach (const QString &p, list) + grpHeaderPaths += CppTools::ProjectPart::HeaderPath( + FileName::fromUserInput(p).toString(), + CppTools::ProjectPart::HeaderPath::IncludePath); list = props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE), QLatin1String(CONFIG_FRAMEWORKPATHS)); - QStringList grpFrameworkPaths; - foreach (const QString &p, list) { - const QString cp = FileName::fromUserInput(p).toString(); - grpFrameworkPaths.append(cp); - } + foreach (const QString &p, list) + grpHeaderPaths += CppTools::ProjectPart::HeaderPath( + FileName::fromUserInput(p).toString(), + CppTools::ProjectPart::HeaderPath::FrameworkPath); const QString pch = props.getModuleProperty(QLatin1String(CONFIG_CPP_MODULE), QLatin1String(CONFIG_PRECOMPILEDHEADER)).toString(); @@ -590,8 +589,7 @@ void QbsProject::updateCppCodeModel(const qbs::ProjectData &prj) CppTools::ProjectFile::CXXHeader); part->qtVersion = qtVersionForPart; - part->includePaths += grpIncludePaths; - part->frameworkPaths += grpFrameworkPaths; + part->headerPaths += grpHeaderPaths; part->precompiledHeaders = QStringList(pch); part->projectDefines += grpDefines; pinfo.appendProjectPart(part); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 17d86a2fd9c..cc89d31e85d 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -520,22 +520,27 @@ void QmakeProject::updateCppCodeModel() // part->defines part->projectDefines += pro->cxxDefines(); - // part->includePaths, part->frameworkPaths - part->includePaths.append(pro->variableValue(IncludePathVar)); + // part->headerPaths + foreach (const QString &inc, pro->variableValue(IncludePathVar)) + part->headerPaths += ProjectPart::HeaderPath(inc, ProjectPart::HeaderPath::IncludePath); if (qtVersion) { foreach (const HeaderPath &header, qtVersion->systemHeaderPathes(k)) { + ProjectPart::HeaderPath::Type type = ProjectPart::HeaderPath::IncludePath; if (header.kind() == HeaderPath::FrameworkHeaderPath) - part->frameworkPaths.append(header.path()); - else - part->includePaths.append(header.path()); + type = ProjectPart::HeaderPath::FrameworkPath; + part->headerPaths += ProjectPart::HeaderPath(header.path(), type); + } + if (!qtVersion->frameworkInstallPath().isEmpty()) { + part->headerPaths += ProjectPart::HeaderPath( + qtVersion->frameworkInstallPath(), + ProjectPart::HeaderPath::FrameworkPath); } - if (!qtVersion->frameworkInstallPath().isEmpty()) - part->frameworkPaths.append(qtVersion->frameworkInstallPath()); } if (QmakeProFileNode *node = rootQmakeProjectNode()) - part->includePaths.append(node->resolvedMkspecPath()); + part->headerPaths += ProjectPart::HeaderPath(node->resolvedMkspecPath(), + ProjectPart::HeaderPath::IncludePath); // part->precompiledHeaders part->precompiledHeaders.append(pro->variableValue(PrecompiledHeaderVar)); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp index 755c8b6dcd6..316e5f82d45 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp @@ -52,11 +52,6 @@ QString ItemLibraryItem::itemLibraryIconPath() const return QStringLiteral("image://qmldesigner_itemlibrary/") + m_itemLibraryEntry.libraryEntryIconPath(); } -QVariant ItemLibraryItem::sortingRole() const -{ - return itemName(); -} - bool ItemLibraryItem::setVisible(bool isVisible) { if (isVisible != m_isVisible) { diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h index f6a12ac712f..f28295ad2d4 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h @@ -46,7 +46,6 @@ class ItemLibraryItem: public QObject { Q_PROPERTY(QVariant itemLibraryEntry READ itemLibraryEntry FINAL) Q_PROPERTY(QString itemName READ itemName FINAL) Q_PROPERTY(QString itemLibraryIconPath READ itemLibraryIconPath FINAL) - Q_PROPERTY(QVariant sortingRole READ sortingRole FINAL) Q_PROPERTY(bool itemVisible READ isVisible NOTIFY visibilityChanged FINAL) public: @@ -55,7 +54,6 @@ public: QString itemName() const; QString itemLibraryIconPath() const; - QVariant sortingRole() const; bool setVisible(bool isVisible); bool isVisible() const; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index ad09b001860..c69d385b6c1 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -155,19 +155,20 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) || model->hasImport(entryToImport(entry), true, true))) { QString itemSectionName = entry.category(); ItemLibrarySection *sectionModel = sectionByName(itemSectionName); - ItemLibraryItem *itemModel; + ItemLibraryItem *item; if (sectionModel == 0) { sectionModel = new ItemLibrarySection(itemSectionName, this); m_sections.append(sectionModel); } - itemModel = new ItemLibraryItem(sectionModel); - itemModel->setItemLibraryEntry(entry); - sectionModel->addSectionEntry(itemModel); + item = new ItemLibraryItem(sectionModel); + item->setItemLibraryEntry(entry); + sectionModel->addSectionEntry(item); } } + sortSections(); resetModel(); updateVisibility(); } @@ -254,6 +255,18 @@ void ItemLibraryModel::resetModel() endResetModel(); } +void ItemLibraryModel::sortSections() +{ + auto sectionSort = [](ItemLibrarySection *first, ItemLibrarySection *second) { + return QString::localeAwareCompare(first->sortingName(), second->sortingName()) < 1; + }; + + std::sort(m_sections.begin(), m_sections.end(), sectionSort); + + foreach (ItemLibrarySection *itemLibrarySection, m_sections) + itemLibrarySection->sortItems(); +} + void registerQmlTypes() { registerItemLibrarySortedModel(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index 9a86453d9cd..063f70b95ac 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -86,6 +86,7 @@ private: // functions void updateVisibility(); void addRoleNames(); void resetModel(); + void sortSections(); private: // variables diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp index 513fd0f117e..a6006d6fca5 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp @@ -53,11 +53,11 @@ bool ItemLibrarySection::sectionExpanded() const return m_sectionExpanded; } -QVariant ItemLibrarySection::sortingRole() const +QString ItemLibrarySection::sortingName() const { if (sectionName() == QStringLiteral("QML Components")) //Qml Components always come first - return QVariant(QStringLiteral("AA.this_comes_first")); + return QStringLiteral("aaaa"); return sectionName(); } @@ -111,4 +111,9 @@ bool ItemLibrarySection::isVisible() const return m_isVisible; } +void ItemLibrarySection::sortItems() +{ + m_sectionEntries.sortItems(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.h index 0f05f945c9b..5d2fe889850 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.h @@ -42,14 +42,13 @@ class ItemLibrarySection: public QObject { Q_PROPERTY(QString sectionName READ sectionName FINAL) Q_PROPERTY(bool sectionVisible READ isVisible NOTIFY visibilityChanged FINAL) Q_PROPERTY(bool sectionExpanded READ sectionExpanded FINAL) - Q_PROPERTY(QVariant sortingRole READ sortingRole FINAL) public: ItemLibrarySection(const QString §ionName, QObject *parent = 0); QString sectionName() const; bool sectionExpanded() const; - QVariant sortingRole() const; + QString sortingName() const; void addSectionEntry(ItemLibraryItem *sectionEntry); QObject *sectionEntries(); @@ -59,6 +58,8 @@ public: bool setVisible(bool isVisible); bool isVisible() const; + void sortItems(); + signals: void sectionEntriesChanged(); void visibilityChanged(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp index b43632d95c0..430bf69d8eb 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp @@ -88,6 +88,15 @@ const QList &ItemLibrarySectionModel::items() const return m_itemList; } +void ItemLibrarySectionModel::sortItems() +{ + auto itemSort = [](ItemLibraryItem *first, ItemLibraryItem *second) { + return QString::localeAwareCompare(first->itemName(), second->itemName()) < 1; + }; + + std::sort(m_itemList.begin(), m_itemList.end(), itemSort); +} + void ItemLibrarySectionModel::resetModel() { beginResetModel(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.h index f47d75183a4..e38fffc95fe 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.h @@ -55,6 +55,7 @@ public: const QList &items() const; + void sortItems(); void resetModel(); private: // functions diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp index 68bb6ae4e69..2d052fd5f26 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp @@ -61,6 +61,7 @@ void ItemLibraryTreeView::drawSelectionBackground(QPainter *painter, const QStyl painter->restore(); } +namespace { // This style basically allows us to span the entire row // including the arrow indicators which would otherwise not be // drawn by the delegate @@ -82,6 +83,7 @@ public: } }; +} ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) : QTreeView(parent) { diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index c95fd7a30bc..d394cb3e81a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -66,7 +66,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : m_itemIconSize(24, 24), m_resIconSize(24, 24), m_iconProvider(m_resIconSize), - m_itemViewQuickWidget(new QQuickWidget), + m_itemsView(new QQuickView()), m_resourcesView(new ItemLibraryTreeView(this)), m_filterFlag(QtBasic) { @@ -75,16 +75,16 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : setWindowTitle(tr("Library", "Title of library view")); /* create Items view and its model */ - m_itemViewQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + m_itemsView->setResizeMode(QQuickView::SizeRootObjectToView); m_itemLibraryModel = new ItemLibraryModel(this); - QQmlContext *rootContext = m_itemViewQuickWidget->rootContext(); + QQmlContext *rootContext = m_itemsView->rootContext(); rootContext->setContextProperty(QStringLiteral("itemLibraryModel"), m_itemLibraryModel.data()); rootContext->setContextProperty(QStringLiteral("itemLibraryIconWidth"), m_itemIconSize.width()); rootContext->setContextProperty(QStringLiteral("itemLibraryIconHeight"), m_itemIconSize.height()); rootContext->setContextProperty(QStringLiteral("rootView"), this); - m_itemViewQuickWidget->rootContext()->setContextProperty(QStringLiteral("highlightColor"), Utils::StyleHelper::notTooBrightHighlightColor()); + m_itemsView->rootContext()->setContextProperty(QStringLiteral("highlightColor"), Utils::StyleHelper::notTooBrightHighlightColor()); /* create Resources view and its model */ m_resourcesFileSystemModel = new QFileSystemModel(this); @@ -93,7 +93,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : m_resourcesView->setIconSize(m_resIconSize); /* create image provider for loading item icons */ - m_itemViewQuickWidget->engine()->addImageProvider(QStringLiteral("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider); + m_itemsView->engine()->addImageProvider(QStringLiteral("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider); /* other widgets */ QTabBar *tabBar = new QTabBar(this); @@ -122,9 +122,9 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2); connect(m_filterLineEdit.data(), SIGNAL(filterChanged(QString)), this, SLOT(setSearchFilter(QString))); - + QWidget *container = createWindowContainer(m_itemsView.data()); m_stackedWidget = new QStackedWidget(this); - m_stackedWidget->addWidget(m_itemViewQuickWidget.data()); + m_stackedWidget->addWidget(container); m_stackedWidget->addWidget(m_resourcesView.data()); QWidget *spacer = new QWidget(this); @@ -228,7 +228,7 @@ void ItemLibraryWidget::setSearchFilter(const QString &searchFilter) { if (m_stackedWidget->currentIndex() == 0) { m_itemLibraryModel->setSearchText(searchFilter); - m_itemViewQuickWidget->update(); + m_itemsView->update(); } else { QStringList nameFilterList; if (searchFilter.contains('.')) { @@ -299,8 +299,8 @@ void ItemLibraryWidget::reloadQmlSource() { QString itemLibraryQmlFilePath = qmlSourcesPath() + QStringLiteral("/ItemsView.qml"); QTC_ASSERT(QFileInfo::exists(itemLibraryQmlFilePath), return); - m_itemViewQuickWidget->engine()->clearComponentCache(); - m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlFilePath)); + m_itemsView->engine()->clearComponentCache(); + m_itemsView->setSource(QUrl::fromLocalFile(itemLibraryQmlFilePath)); } void ItemLibraryWidget::setImportFilter(FilterChangeFlag flag) @@ -373,11 +373,10 @@ void ItemLibraryWidget::setResourcePath(const QString &resourcePath) updateSearch(); } -static void ungrabMouseOnQMLWorldWorkAround(QQuickWidget *quickWidget) +static void ungrabMouseOnQMLWorldWorkAround(QQuickView *quickView) { - const QQuickWidgetPrivate *widgetPrivate = QQuickWidgetPrivate::get(quickWidget); - if (widgetPrivate && widgetPrivate->offscreenWindow && widgetPrivate->offscreenWindow->mouseGrabberItem()) - widgetPrivate->offscreenWindow->mouseGrabberItem()->ungrabMouse(); + if (quickView->mouseGrabberItem()) + quickView->mouseGrabberItem()->ungrabMouse(); } void ItemLibraryWidget::startDragAndDrop(QVariant itemLibraryId) @@ -392,7 +391,7 @@ void ItemLibraryWidget::startDragAndDrop(QVariant itemLibraryId) drag->exec(); - ungrabMouseOnQMLWorldWorkAround(m_itemViewQuickWidget.data()); + ungrabMouseOnQMLWorldWorkAround(m_itemsView.data()); } void ItemLibraryWidget::removeImport(const QString &name) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 4e96e8ff2aa..24a585378b3 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include QT_BEGIN_NAMESPACE class QFileSystemModel; @@ -132,7 +132,7 @@ private: QPointer m_stackedWidget; QPointer m_filterLineEdit; - QScopedPointer m_itemViewQuickWidget; + QScopedPointer m_itemsView; QScopedPointer m_resourcesView; QShortcut *m_qmlSourceUpdateShortcut; diff --git a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp index 13cb12385e7..7ae2d1ecec9 100644 --- a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp @@ -82,7 +82,7 @@ void IconCheckboxItemDelegate::paint(QPainter *painter, if (indexIsHolingModelNode(modelIndex)) { painter->save(); if (styleOption.state & QStyle::State_Selected) - drawSelectionBackground(painter, styleOption); + NavigatorTreeView::drawSelectionBackground(painter, styleOption); if (!m_navigatorTreeModel->nodeForIndex(modelIndex).isRootNode()) { diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp index 62ceb889f87..6fd880aaacc 100644 --- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp @@ -224,7 +224,7 @@ void NameItemDelegate::paint(QPainter *painter, painter->save(); if (styleOption.state & QStyle::State_Selected) - drawSelectionBackground(painter, styleOption); + NavigatorTreeView::drawSelectionBackground(painter, styleOption); int iconOffset = drawTypeIcon(painter, styleOption, modelIndex, m_navigatorTreeModel); diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index b55e3ada181..e967ad9e4c6 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -623,7 +623,7 @@ static bool isInLayoutable(NodeAbstractProperty &parentProperty) static void reparentModelNodeToNodeProperty(NodeAbstractProperty &parentProperty, const ModelNode &modelNode) { - if (parentProperty != modelNode.parentProperty()) { + if (!modelNode.hasParentProperty() || parentProperty != modelNode.parentProperty()) { if (isInLayoutable(parentProperty)) { removePosition(modelNode); parentProperty.reparentHere(modelNode); diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp index 7a9b2a36818..1d48c10a6d5 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp @@ -48,23 +48,7 @@ namespace QmlDesigner { -void drawSelectionBackground(QPainter *painter, const QStyleOption &option) -{ - painter->save(); - QLinearGradient gradient; - - QColor highlightColor = Utils::StyleHelper::notTooBrightHighlightColor(); - gradient.setColorAt(0, highlightColor.lighter(130)); - gradient.setColorAt(1, highlightColor.darker(130)); - gradient.setStart(option.rect.topLeft()); - gradient.setFinalStop(option.rect.bottomLeft()); - painter->fillRect(option.rect, gradient); - painter->setPen(highlightColor.lighter()); - painter->drawLine(option.rect.topLeft(),option.rect.topRight()); - painter->setPen(highlightColor.darker()); - painter->drawLine(option.rect.bottomLeft(),option.rect.bottomRight()); - painter->restore(); -} +namespace { // This style basically allows us to span the entire row // including the arrow indicators which would otherwise not be @@ -76,7 +60,7 @@ public: { if (element == QStyle::PE_PanelItemViewRow) { if (option->state & QStyle::State_Selected) { - drawSelectionBackground(painter, *option); + NavigatorTreeView::drawSelectionBackground(painter, *option); } else { // // 3D shadows // painter->save(); @@ -118,6 +102,8 @@ public: } }; +} + NavigatorTreeView::NavigatorTreeView(QWidget *parent) : QTreeView(parent) { @@ -126,4 +112,23 @@ NavigatorTreeView::NavigatorTreeView(QWidget *parent) style->setParent(this); } +void NavigatorTreeView::drawSelectionBackground(QPainter *painter, const QStyleOption &option) +{ + painter->save(); + QLinearGradient gradient; + + QColor highlightColor = Utils::StyleHelper::notTooBrightHighlightColor(); + gradient.setColorAt(0, highlightColor.lighter(130)); + gradient.setColorAt(1, highlightColor.darker(130)); + gradient.setStart(option.rect.topLeft()); + gradient.setFinalStop(option.rect.bottomLeft()); + painter->fillRect(option.rect, gradient); + painter->setPen(highlightColor.lighter()); + painter->drawLine(option.rect.topLeft(),option.rect.topRight()); + painter->setPen(highlightColor.darker()); + painter->drawLine(option.rect.bottomLeft(),option.rect.bottomRight()); + painter->restore(); +} + + } diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreeview.h b/src/plugins/qmldesigner/components/navigator/navigatortreeview.h index a87b6b801a6..2e96f136f24 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreeview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatortreeview.h @@ -35,12 +35,12 @@ namespace QmlDesigner { -void drawSelectionBackground(QPainter *painter, const QStyleOption &option); class NavigatorTreeView : public QTreeView { public: NavigatorTreeView(QWidget *parent = 0); + static void drawSelectionBackground(QPainter *painter, const QStyleOption &option); }; } diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp index 1d28219b1a9..4aa9efbf5a9 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp @@ -34,12 +34,73 @@ #include "gradientmodel.h" #include "qmlanchorbindingproxy.h" +#include + namespace QmlDesigner { -Quick2PropertyEditorView::Quick2PropertyEditorView(QWidget *parent) : - QQuickWidget(parent) +void Quick2PropertyEditorView::execute() { - setResizeMode(QQuickWidget::SizeRootObjectToView); + m_view.setSource(m_source); + + if (!m_source.isEmpty()) { + m_view.setSource(m_source); + connect(&m_view, SIGNAL(statusChanged(QQuickView::Status)), this, SLOT(continueExecute())); + } +} + +Quick2PropertyEditorView::Quick2PropertyEditorView(QWidget *parent) : + QWidget(parent) +{ + m_containerWidget = createWindowContainer(&m_view); + + QVBoxLayout *layout = new QVBoxLayout(this); + setLayout(layout); + layout->addWidget(m_containerWidget); + layout->setMargin(0); + m_view.setResizeMode(QQuickView::SizeRootObjectToView); +} + +QUrl Quick2PropertyEditorView::source() const +{ + return m_source; +} + +void Quick2PropertyEditorView::setSource(const QUrl& url) +{ + m_source = url; + execute(); +} + +QQmlEngine* Quick2PropertyEditorView::engine() +{ + return m_view.engine(); +} + +QQmlContext* Quick2PropertyEditorView::rootContext() +{ + return engine()->rootContext(); +} + +Quick2PropertyEditorView::Status Quick2PropertyEditorView::status() const +{ + return Quick2PropertyEditorView::Status(m_view.status()); +} + + +void Quick2PropertyEditorView::continueExecute() +{ + disconnect(&m_view, SIGNAL(statusChanged(QQuickView::Status)), this, SLOT(continueExecute())); + + if (!m_view.errors().isEmpty()) { + QList errorList = m_view.errors(); + foreach (const QQmlError &error, errorList) { + qWarning() << error; + } + emit statusChanged(status()); + return; + } + + emit statusChanged(status()); } void Quick2PropertyEditorView::registerQmlTypes() diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.h index 0bc541bbf4a..da99157725c 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.h +++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.h @@ -30,19 +30,54 @@ #ifndef QUICK2PROERTYEDITORVIEW_H #define QUICK2PROERTYEDITORVIEW_H -#include +#include +#include +#include +#include +#include +#include +QT_BEGIN_NAMESPACE +class QQmlError; +class QQmlComponent; +QT_END_NAMESPACE namespace QmlDesigner { -class Quick2PropertyEditorView : public QQuickWidget +class Quick2PropertyEditorView : public QWidget { Q_OBJECT + Q_PROPERTY(QUrl source READ source WRITE setSource DESIGNABLE true) public: explicit Quick2PropertyEditorView(QWidget *parent = 0); + QUrl source() const; + void setSource(const QUrl&); + + QQmlEngine* engine(); + QQmlContext* rootContext(); + + enum Status { Null, Ready, Loading, Error }; + Status status() const; + static void registerQmlTypes(); + +signals: + void statusChanged(Quick2PropertyEditorView::Status); + +protected: + void execute(); + +private Q_SLOTS: + void continueExecute(); + +private: + QWidget *m_containerWidget; + QUrl m_source; + QQuickView m_view; + QPointer m_component; + }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp index 0fc88003ef1..9caa3b64540 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp @@ -45,6 +45,7 @@ #include #include +#include #include #include #include @@ -57,15 +58,15 @@ namespace QmlDesigner { int StatesEditorWidget::currentStateInternalId() const { - Q_ASSERT(rootObject()); - Q_ASSERT(rootObject()->property("currentStateInternalId").isValid()); + Q_ASSERT(m_quickView->rootObject()); + Q_ASSERT(m_quickView->rootObject()->property("currentStateInternalId").isValid()); - return rootObject()->property("currentStateInternalId").toInt(); + return m_quickView->rootObject()->property("currentStateInternalId").toInt(); } void StatesEditorWidget::setCurrentStateInternalId(int internalId) { - rootObject()->setProperty("currentStateInternalId", internalId); + m_quickView->rootObject()->setProperty("currentStateInternalId", internalId); } void StatesEditorWidget::setNodeInstanceView(NodeInstanceView *nodeInstanceView) @@ -75,11 +76,12 @@ void StatesEditorWidget::setNodeInstanceView(NodeInstanceView *nodeInstanceView) void StatesEditorWidget::showAddNewStatesButton(bool showAddNewStatesButton) { - rootContext()->setContextProperty("canAddNewStates", showAddNewStatesButton); + m_quickView->rootContext()->setContextProperty("canAddNewStates", showAddNewStatesButton); } StatesEditorWidget::StatesEditorWidget(StatesEditorView *statesEditorView, StatesEditorModel *statesEditorModel) - : QQuickWidget(), + : QWidget(), + m_quickView(new QQuickView()), m_statesEditorView(statesEditorView), m_imageProvider(0), m_qmlSourceUpdateShortcut(0) @@ -87,20 +89,25 @@ StatesEditorWidget::StatesEditorWidget(StatesEditorView *statesEditorView, State m_imageProvider = new Internal::StatesEditorImageProvider; m_imageProvider->setNodeInstanceView(statesEditorView->nodeInstanceView()); - engine()->addImageProvider(QStringLiteral("qmldesigner_stateseditor"), m_imageProvider); - engine()->addImportPath(qmlSourcesPath()); + m_quickView->engine()->addImageProvider(QStringLiteral("qmldesigner_stateseditor"), m_imageProvider); + m_quickView->engine()->addImportPath(qmlSourcesPath()); m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F4), this); connect(m_qmlSourceUpdateShortcut, SIGNAL(activated()), this, SLOT(reloadQmlSource())); - setResizeMode(QQuickWidget::SizeRootObjectToView); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->setSpacing(0); + QWidget *container = createWindowContainer(m_quickView.data()); + layout->addWidget(container); + m_quickView->setResizeMode(QQuickView::SizeRootObjectToView); + container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - rootContext()->setContextProperty(QStringLiteral("statesEditorModel"), statesEditorModel); - rootContext()->setContextProperty(QStringLiteral("highlightColor"), Utils::StyleHelper::notTooBrightHighlightColor()); + m_quickView->rootContext()->setContextProperty(QStringLiteral("statesEditorModel"), statesEditorModel); + m_quickView->rootContext()->setContextProperty(QStringLiteral("highlightColor"), Utils::StyleHelper::notTooBrightHighlightColor()); - rootContext()->setContextProperty("canAddNewStates", true); + m_quickView->rootContext()->setContextProperty("canAddNewStates", true); setWindowTitle(tr("States", "Title of Editor widget")); @@ -120,21 +127,21 @@ void StatesEditorWidget::reloadQmlSource() { QString statesListQmlFilePath = qmlSourcesPath() + QStringLiteral("/StatesList.qml"); QTC_ASSERT(QFileInfo::exists(statesListQmlFilePath), return); - engine()->clearComponentCache(); - setSource(QUrl::fromLocalFile(statesListQmlFilePath)); + m_quickView->engine()->clearComponentCache(); + m_quickView->setSource(QUrl::fromLocalFile(statesListQmlFilePath)); - QTC_ASSERT(rootObject(), return); - connect(rootObject(), SIGNAL(currentStateInternalIdChanged()), m_statesEditorView.data(), SLOT(synchonizeCurrentStateFromWidget())); - connect(rootObject(), SIGNAL(createNewState()), m_statesEditorView.data(), SLOT(createNewState())); - connect(rootObject(), SIGNAL(deleteState(int)), m_statesEditorView.data(), SLOT(removeState(int))); + QTC_ASSERT(m_quickView->rootObject(), return); + connect(m_quickView->rootObject(), SIGNAL(currentStateInternalIdChanged()), m_statesEditorView.data(), SLOT(synchonizeCurrentStateFromWidget())); + connect(m_quickView->rootObject(), SIGNAL(createNewState()), m_statesEditorView.data(), SLOT(createNewState())); + connect(m_quickView->rootObject(), SIGNAL(deleteState(int)), m_statesEditorView.data(), SLOT(removeState(int))); m_statesEditorView.data()->synchonizeCurrentStateFromWidget(); - setFixedHeight(initialSize().height()); + setFixedHeight(m_quickView->initialSize().height()); - connect(rootObject(), SIGNAL(expandedChanged()), this, SLOT(changeHeight())); + connect(m_quickView->rootObject(), SIGNAL(expandedChanged()), this, SLOT(changeHeight())); } void StatesEditorWidget::changeHeight() { - setFixedHeight(rootObject()->height()); + setFixedHeight(m_quickView->rootObject()->height()); } } diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h index ea60fa016dc..8a7967a7847 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h @@ -30,10 +30,11 @@ #ifndef STATESEDITORWIDGET_H #define STATESEDITORWIDGET_H -#include +#include #include QT_BEGIN_NAMESPACE +class QQuickView; class QShortcut; QT_END_NAMESPACE @@ -47,7 +48,7 @@ class NodeInstanceView; namespace Internal { class StatesEditorImageProvider; } -class StatesEditorWidget : public QQuickWidget +class StatesEditorWidget : public QWidget { Q_OBJECT @@ -68,6 +69,7 @@ private slots: void changeHeight(); private: + QPointer m_quickView; QPointer m_statesEditorView; Internal::StatesEditorImageProvider *m_imageProvider; QShortcut *m_qmlSourceUpdateShortcut; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp index dfbaa190640..7fd196af44a 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp @@ -196,9 +196,11 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV m_secondTimer.setInterval(3000); m_thirdTimer.setInterval(3000); - connect(&m_firstTimer, SIGNAL(timeout()), this, SLOT(processFinished())); - connect(&m_secondTimer, SIGNAL(timeout()), this, SLOT(processFinished())); - connect(&m_thirdTimer, SIGNAL(timeout()), this, SLOT(processFinished())); + if (qgetenv("DEBUG_QML_PUPPET").isEmpty()) { + connect(&m_firstTimer, SIGNAL(timeout()), this, SLOT(processFinished())); + connect(&m_secondTimer, SIGNAL(timeout()), this, SLOT(processFinished())); + connect(&m_thirdTimer, SIGNAL(timeout()), this, SLOT(processFinished())); + } } NodeInstanceServerProxy::~NodeInstanceServerProxy() diff --git a/src/plugins/qmldesigner/designercore/instances/puppetbuildprogressdialog.cpp b/src/plugins/qmldesigner/designercore/instances/puppetbuildprogressdialog.cpp index e25a85a9ffe..adf6c5ec7a0 100644 --- a/src/plugins/qmldesigner/designercore/instances/puppetbuildprogressdialog.cpp +++ b/src/plugins/qmldesigner/designercore/instances/puppetbuildprogressdialog.cpp @@ -45,7 +45,7 @@ PuppetBuildProgressDialog::PuppetBuildProgressDialog() : { setWindowFlags(Qt::SplashScreen); ui->setupUi(this); - ui->buildProgressBar->setMaximum(86); + ui->buildProgressBar->setMaximum(85); } PuppetBuildProgressDialog::~PuppetBuildProgressDialog() diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp index 58898bd102c..7e1c937b4eb 100644 --- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp +++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -140,6 +141,14 @@ QProcess *PuppetCreator::puppetProcess(const QString &puppetPath, return puppetProcess; } +static QString idealProcessCount() +{ + int processCount = QThread::idealThreadCount() + 1; + if (processCount < 1) + processCount = 4; + + return QString::number(processCount); +} bool PuppetCreator::build(const QString &qmlPuppetProjectFilePath) const { @@ -164,8 +173,14 @@ bool PuppetCreator::build(const QString &qmlPuppetProjectFilePath) const buildSucceeded = startBuildProcess(buildDirectory.path(), qmakeCommand(), qmakeArguments); if (buildSucceeded) { progressDialog.show(); - buildSucceeded = startBuildProcess(buildDirectory.path(), buildCommand(), QStringList(), &progressDialog); - progressDialog.hide(); + QString buildingCommand = buildCommand(); + QStringList buildArguments; + if (buildingCommand == QStringLiteral("make")) { + buildArguments.append(QStringLiteral("-j")); + buildArguments.append(idealProcessCount()); + } + buildSucceeded = startBuildProcess(buildDirectory.path(), buildingCommand, buildArguments, &progressDialog); + progressDialog.close(); } if (!buildSucceeded) @@ -325,7 +340,7 @@ bool PuppetCreator::startBuildProcess(const QString &buildDirectoryPath, return false; QProcess process; - process.setProcessChannelMode(QProcess::MergedChannels); + process.setProcessChannelMode(QProcess::SeparateChannels); process.setProcessEnvironment(processEnvironment()); process.setWorkingDirectory(buildDirectoryPath); process.start(command, processArguments); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index f993b6d6e18..e1087710a33 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -758,7 +758,9 @@ void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, co foreach (const ImportKey &importKey, filteredPossibleImportKeys) { QString libraryName = importKey.splitPath.join(QLatin1Char('.')); - QString version = QString(QStringLiteral("%1.%2").arg(importKey.majorVersion).arg(importKey.minorVersion)); + QString version = QString(QStringLiteral("%1.%2") + .arg((importKey.majorVersion == LanguageUtils::ComponentVersion::NoVersion) ? 1 : importKey.majorVersion) + .arg((importKey.minorVersion == LanguageUtils::ComponentVersion::NoVersion) ? 0 : importKey.minorVersion)); possibleImports.append(Import::createLibraryImport(libraryName, version)); } @@ -851,7 +853,6 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH if (view()->checkSemanticErrors()) { Check check(doc, m_scopeChain->context()); - check.disableMessage(StaticAnalysis::ErrUnknownComponent); check.disableMessage(StaticAnalysis::ErrPrototypeCycle); check.disableMessage(StaticAnalysis::ErrCouldNotResolvePrototype); check.disableMessage(StaticAnalysis::ErrCouldNotResolvePrototypeOf); @@ -872,8 +873,12 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH //## triggers too often ## check.enableMessage(StaticAnalysis::WarnUndefinedValueForVisualDesigner); foreach (const StaticAnalysis::Message &message, check()) { - if (message.severity == Severity::Error) - errors.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName()))); + if (message.severity == Severity::Error) { + if (message.type == StaticAnalysis::ErrUnknownComponent) + warnings.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName()))); + else + errors.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName()))); + } if (message.severity == Severity::Warning) { if (message.type == StaticAnalysis::WarnAboutQtQuick1InsteadQtQuick2) { errors.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName()))); diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pro b/src/plugins/qmldesigner/qmldesignerplugin.pro index 0e002e3cadf..c2512a171dd 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pro +++ b/src/plugins/qmldesigner/qmldesignerplugin.pro @@ -1,4 +1,3 @@ -QT += quickwidgets QT += widgets-private quick-private quickwidgets-private core-private gui-private #mouse ungrabbing workaround on quickitems CONFIG += exceptions diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp index ff5da4485c0..17ea48be0f5 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp @@ -32,8 +32,6 @@ namespace QmlProfiler { -static const int DefaultRowHeight = 30; - AbstractTimelineModel::AbstractTimelineModel(AbstractTimelineModelPrivate *dd, const QString &name, const QString &label, QmlDebug::Message message, QmlDebug::RangeType rangeType, QObject *parent) : diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.h b/src/plugins/qmlprofiler/abstracttimelinemodel.h index ea0486970a6..2d612e16a59 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.h @@ -101,6 +101,8 @@ signals: void rowHeightChanged(); protected: + static const int DefaultRowHeight = 30; + enum BoxColorProperties { EventHueMultiplier = 25, FractionHueMultiplier = 96, diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.cpp b/src/plugins/qmlprofiler/qmlprofilereventview.cpp index d4bb588478f..b800c57296c 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilereventview.cpp @@ -92,18 +92,25 @@ public: virtual bool operator<(const QStandardItem &other) const { - if (data().type() == QVariant::String) { - // first column - if (column() == 0) { - return data(FilenameRole).toString() == other.data(FilenameRole).toString() ? - data(LineRole).toInt() < other.data(LineRole).toInt() : - data(FilenameRole).toString() < other.data(FilenameRole).toString(); - } else { - return data().toString().toLower() < other.data().toString().toLower(); - } - } + if (column() == 0) { + // first column is special + int filenameDiff = QUrl(data(FilenameRole).toString()).fileName().compare( + QUrl(other.data(FilenameRole).toString()).fileName(), Qt::CaseInsensitive); + if (filenameDiff != 0) + return filenameDiff < 0; - return data().toDouble() < other.data().toDouble(); + return data(LineRole).toInt() == other.data(LineRole).toInt() ? + data(ColumnRole).toInt() < other.data(ColumnRole).toInt() : + data(LineRole).toInt() < other.data(LineRole).toInt(); + + } else if (data(SortRole).type() == QVariant::String) { + // Strings should be case-insensitive compared + return data(SortRole).toString().compare(other.data(SortRole).toString(), + Qt::CaseInsensitive) < 0; + } else { + // For everything else the standard comparison should be OK + return QStandardItem::operator<(other); + } } }; @@ -395,6 +402,7 @@ QmlProfilerEventsMainView::QmlProfilerEventsMainView(QWidget *parent, setSortingEnabled(false); d->m_model = new QStandardItemModel(this); + d->m_model->setSortRole(SortRole); setModel(d->m_model); connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(jumpToItem(QModelIndex))); @@ -851,7 +859,9 @@ QmlProfilerEventRelativesView::QmlProfilerEventRelativesView(QmlProfilerModelMan Q_UNUSED(modelManager); setSortingEnabled(false); d->modelProxy = modelProxy; - setModel(new QStandardItemModel(this)); + QStandardItemModel *model = new QStandardItemModel(this); + model->setSortRole(SortRole); + setModel(model); setRootIsDecorated(false); updateHeader(); @@ -905,8 +915,13 @@ void QmlProfilerEventRelativesView::rebuildTree( type.data); newRow.at(0)->setData(QVariant(typeIndex), EventTypeIndexRole); + newRow.at(0)->setData(QVariant(type.location.filename),FilenameRole); + newRow.at(0)->setData(QVariant(type.location.line),LineRole); + newRow.at(0)->setData(QVariant(type.location.column),ColumnRole); + newRow.at(1)->setData(QVariant(QmlProfilerEventsMainView::nameForType(type.rangeType))); newRow.at(2)->setData(QVariant(event.duration)); newRow.at(3)->setData(QVariant(event.calls)); + newRow.at(4)->setData(QVariant(type.data)); if (event.isBindingLoop) { foreach (QStandardItem *item, newRow) { diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.h b/src/plugins/qmlprofiler/qmlprofilereventview.h index 95651d9b6d6..86ef4400d71 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.h +++ b/src/plugins/qmlprofiler/qmlprofilereventview.h @@ -48,11 +48,12 @@ class QmlProfilerEventChildrenView; class QmlProfilerEventRelativesView; enum ItemRole { - EventTypeIndexRole = Qt::UserRole+1, - FilenameRole = Qt::UserRole+2, - LineRole = Qt::UserRole+3, - ColumnRole = Qt::UserRole+4, - EventIdRole = Qt::UserRole+5 + SortRole = Qt::UserRole + 1, // Sort by data, not by displayed string + EventTypeIndexRole, + FilenameRole, + LineRole, + ColumnRole, + EventIdRole }; class QmlProfilerEventsWidget : public QWidget diff --git a/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp b/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp index 233a3d7c2d5..cc6b1d8296c 100644 --- a/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp @@ -54,7 +54,7 @@ public: int maxGuiThreadAnimations; int maxRenderThreadAnimations; - bool seenForeignPaintEvent; + int rowFromThreadId(QmlDebug::AnimationThread threadId) const; private: Q_DECLARE_PUBLIC(PaintEventsModelProxy) @@ -62,11 +62,10 @@ private: PaintEventsModelProxy::PaintEventsModelProxy(QObject *parent) : AbstractTimelineModel(new PaintEventsModelProxyPrivate, - QLatin1String("PaintEventsModelProxy"), tr("Painting"), + QLatin1String("PaintEventsModelProxy"), tr("Animations"), QmlDebug::Event, QmlDebug::MaximumRangeType, parent) { Q_D(PaintEventsModelProxy); - d->seenForeignPaintEvent = false; d->maxGuiThreadAnimations = d->maxRenderThreadAnimations = 0; } @@ -77,7 +76,6 @@ void PaintEventsModelProxy::clear() d->clear(); d->maxGuiThreadAnimations = d->maxRenderThreadAnimations = 0; d->expanded = false; - d->seenForeignPaintEvent = false; d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1); } @@ -104,11 +102,8 @@ void PaintEventsModelProxy::loadData() foreach (const QmlProfilerDataModel::QmlEventData &event, referenceList) { const QmlProfilerDataModel::QmlEventTypeData &type = typeList[event.typeIndex]; - if (!eventAccepted(type)) { - if (type.rangeType == QmlDebug::Painting) - d->seenForeignPaintEvent = true; + if (!eventAccepted(type)) continue; - } lastEvent.threadId = (QmlDebug::AnimationThread)event.numericData3; @@ -155,16 +150,21 @@ int PaintEventsModelProxy::rowCount() const { Q_D(const PaintEventsModelProxy); if (isEmpty()) - return d->seenForeignPaintEvent ? 0 : 1; + return 1; else return (d->maxGuiThreadAnimations == 0 || d->maxRenderThreadAnimations == 0) ? 2 : 3; } +int PaintEventsModelProxy::PaintEventsModelProxyPrivate::rowFromThreadId( + QmlDebug::AnimationThread threadId) const +{ + return (threadId == QmlDebug::GuiThread || maxGuiThreadAnimations == 0) ? 1 : 2; +} + int PaintEventsModelProxy::getEventRow(int index) const { Q_D(const PaintEventsModelProxy); - QmlDebug::AnimationThread threadId = d->range(index).threadId; - return (threadId == QmlDebug::GuiThread || d->maxGuiThreadAnimations == 0) ? 1 : 2; + return d->rowFromThreadId(d->range(index).threadId); } int PaintEventsModelProxy::rowMaxValue(int rowNumber) const @@ -202,8 +202,15 @@ float PaintEventsModelProxy::getHeight(int index) const { Q_D(const PaintEventsModelProxy); const PaintEventsModelProxyPrivate::Range &range = d->range(index); - return (float)range.animationcount / (float)(range.threadId == QmlDebug::GuiThread ? - d->maxGuiThreadAnimations : d->maxRenderThreadAnimations); + + // Add some height to the events if we're far from the scale threshold of 2 * DefaultRowHeight. + // Like that you can see the smaller events more easily. + int scaleThreshold = 2 * DefaultRowHeight - rowHeight(d->rowFromThreadId(range.threadId)); + float boost = scaleThreshold > 0 ? (0.15 * scaleThreshold / DefaultRowHeight) : 0; + + return boost + (1.0 - boost) * (float)range.animationcount / + (float)(range.threadId == QmlDebug::GuiThread ? d->maxGuiThreadAnimations : + d->maxRenderThreadAnimations); } const QVariantList PaintEventsModelProxy::getLabels() const diff --git a/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp b/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp index 68e6d8e1849..63e033be015 100644 --- a/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp @@ -371,7 +371,7 @@ int RangeTimelineModel::getEventIdForLocation(const QString &filename, int line, // if this is called from v8 view, we don't have the column number, it will be -1 const QVector &types = d->modelManager->qmlModel()->getEventTypes(); - for (int i = 0; i < d->expandedRowTypes.size(); ++i) { + for (int i = 1; i < d->expandedRowTypes.size(); ++i) { int typeId = d->expandedRowTypes[i]; const QmlProfilerDataModel::QmlEventTypeData &eventData = types[typeId]; if (eventData.location.filename == filename && diff --git a/src/plugins/qmlprofiler/qv8profilereventview.cpp b/src/plugins/qmlprofiler/qv8profilereventview.cpp index 319d007a7d1..cd8197fb9d5 100644 --- a/src/plugins/qmlprofiler/qv8profilereventview.cpp +++ b/src/plugins/qmlprofiler/qv8profilereventview.cpp @@ -58,11 +58,10 @@ namespace QmlProfiler { namespace Internal { enum ItemRole { - EventHashStrRole = Qt::UserRole+1, - FilenameRole = Qt::UserRole+2, - LineRole = Qt::UserRole+3, - ColumnRole = Qt::UserRole+4, - EventIdRole = Qt::UserRole+5 + SortRole = Qt::UserRole + 1, // Sort by data, not by displayed text + FilenameRole, + LineRole, + EventIdRole }; //////////////////////////////////////////////////////////////////////////////////// @@ -70,25 +69,27 @@ enum ItemRole { //////////////////////////////////////////////////////////////////////////////////// -class EventsViewItem : public QStandardItem +class V8ViewItem : public QStandardItem { public: - EventsViewItem(const QString &text) : QStandardItem(text) {} + V8ViewItem(const QString &text) : QStandardItem(text) {} virtual bool operator<(const QStandardItem &other) const { - if (data().type() == QVariant::String) { - // first column - if (column() == 0) { - return data(FilenameRole).toString() == other.data(FilenameRole).toString() ? - data(LineRole).toInt() < other.data(LineRole).toInt() : - data(FilenameRole).toString() < other.data(FilenameRole).toString(); - } else { - return data().toString().toLower() < other.data().toString().toLower(); - } + // first column is special + if (column() == 0) { + int filenameDiff = QUrl(data(FilenameRole).toString()).fileName().compare( + QUrl(other.data(FilenameRole).toString()).fileName(), Qt::CaseInsensitive); + return filenameDiff != 0 ? filenameDiff < 0 : + data(LineRole).toInt() < other.data(LineRole).toInt(); + } else if (data(SortRole).type() == QVariant::String) { + // Strings should be case-insensitive compared + return data(SortRole).toString().compare(other.data(SortRole).toString(), + Qt::CaseInsensitive) < 0; + } else { + // For everything else the standard comparison should be OK + return QStandardItem::operator<(other); } - - return data().toDouble() < other.data().toDouble(); } }; @@ -290,6 +291,7 @@ QV8ProfilerEventsMainView::QV8ProfilerEventsMainView(QWidget *parent, setSortingEnabled(false); d->m_model = new QStandardItemModel(this); + d->m_model->setSortRole(SortRole); setModel(d->m_model); connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(jumpToItem(QModelIndex))); @@ -436,30 +438,30 @@ void QV8ProfilerEventsMainView::QV8ProfilerEventsMainViewPrivate::buildV8ModelFr QList newRow; if (m_fieldShown[Name]) - newRow << new EventsViewItem(v8event->displayName); + newRow << new V8ViewItem(v8event->displayName); if (m_fieldShown[TimeInPercent]) { - newRow << new EventsViewItem(QString::number(v8event->totalPercent,'f',2)+QLatin1String(" %")); + newRow << new V8ViewItem(QString::number(v8event->totalPercent,'f',2)+QLatin1String(" %")); newRow.last()->setData(QVariant(v8event->totalPercent)); } if (m_fieldShown[TotalTime]) { - newRow << new EventsViewItem(QmlProfilerBaseModel::formatTime(v8event->totalTime)); + newRow << new V8ViewItem(QmlProfilerBaseModel::formatTime(v8event->totalTime)); newRow.last()->setData(QVariant(v8event->totalTime)); } if (m_fieldShown[SelfTimeInPercent]) { - newRow << new EventsViewItem(QString::number(v8event->SelfTimeInPercent,'f',2)+QLatin1String(" %")); + newRow << new V8ViewItem(QString::number(v8event->SelfTimeInPercent,'f',2)+QLatin1String(" %")); newRow.last()->setData(QVariant(v8event->SelfTimeInPercent)); } if (m_fieldShown[SelfTime]) { - newRow << new EventsViewItem(QmlProfilerBaseModel::formatTime(v8event->selfTime)); + newRow << new V8ViewItem(QmlProfilerBaseModel::formatTime(v8event->selfTime)); newRow.last()->setData(QVariant(v8event->selfTime)); } if (m_fieldShown[Details]) { - newRow << new EventsViewItem(v8event->functionName); + newRow << new V8ViewItem(v8event->functionName); newRow.last()->setData(QVariant(v8event->functionName)); } @@ -470,10 +472,8 @@ void QV8ProfilerEventsMainView::QV8ProfilerEventsMainViewPrivate::buildV8ModelFr // metadata QStandardItem *firstItem = newRow.at(0); - firstItem->setData(QString::fromLatin1("%1:%2").arg(v8event->filename, QString::number(v8event->line)), EventHashStrRole); firstItem->setData(QVariant(v8event->filename), FilenameRole); firstItem->setData(QVariant(v8event->line), LineRole); - firstItem->setData(QVariant(-1),ColumnRole); // v8 events have no column info firstItem->setData(QVariant(v8event->eventId), EventIdRole); // append @@ -506,10 +506,9 @@ void QV8ProfilerEventsMainView::jumpToItem(const QModelIndex &index) // show in editor int line = infoItem->data(LineRole).toInt(); - int column = infoItem->data(ColumnRole).toInt(); QString fileName = infoItem->data(FilenameRole).toString(); if (line!=-1 && !fileName.isEmpty()) - emit gotoSourceLocation(fileName, line, column); + emit gotoSourceLocation(fileName, line, -1); // show in callers/callees subwindow emit eventSelected(infoItem->data(EventIdRole).toInt()); @@ -627,6 +626,7 @@ QV8ProfilerEventRelativesView::QV8ProfilerEventRelativesView(QV8ProfilerDataMode , m_v8Model(model) , m_model(new QStandardItemModel(this)) { + m_model->setSortRole(SortRole); setModel(m_model); updateHeader(); @@ -666,11 +666,15 @@ void QV8ProfilerEventRelativesView::rebuildTree(QList newRow; - newRow << new EventsViewItem(event->reference->displayName); - newRow << new EventsViewItem(QmlProfilerBaseModel::formatTime(event->totalTime)); - newRow << new EventsViewItem(event->reference->functionName); + newRow << new V8ViewItem(event->reference->displayName); + newRow << new V8ViewItem(QmlProfilerBaseModel::formatTime(event->totalTime)); + newRow << new V8ViewItem(event->reference->functionName); + newRow.at(0)->setData(QVariant(event->reference->eventId), EventIdRole); + newRow.at(0)->setData(QVariant(event->reference->filename), FilenameRole); + newRow.at(0)->setData(QVariant(event->reference->line), LineRole); newRow.at(1)->setData(QVariant(event->totalTime)); + newRow.at(2)->setData(QVariant(event->reference->functionName)); foreach (QStandardItem *item, newRow) item->setEditable(false); diff --git a/src/plugins/qmlprofiler/sortedtimelinemodel.cpp b/src/plugins/qmlprofiler/sortedtimelinemodel.cpp index ae8f8e7641d..9453b636946 100644 --- a/src/plugins/qmlprofiler/sortedtimelinemodel.cpp +++ b/src/plugins/qmlprofiler/sortedtimelinemodel.cpp @@ -31,8 +31,14 @@ \class QmlProfiler::SortedTimelineModel \brief Sorted model for timeline data - The SortedTimelineModel lets you keep any kind of range data sorted by - both start and end times, so that visible ranges can easily be computed. + The SortedTimelineModel lets you keep range data sorted by both start and end times, so that + visible ranges can easily be computed. The only precondition for that to work is that the ranges + must be perfectly nested. A "parent" range of a range R is defined as a range for which the + start time is smaller than R's start time and the end time is greater than R's end time. A set + of ranges is perfectly nested if all parent ranges of any given range have a common parent + range. Mind that you can always make that happen by defining a range that spans the whole + available time span. That, however, will make any code that uses firstStartTime() and + lastEndTime() for selecting subsets of the model always select all of it. */ /*! diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index 941b87ede0d..73d8ea6bf69 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -46,12 +46,177 @@ #include #include -using namespace TextEditor; -using namespace TextEditor::Internal; +namespace TextEditor { +namespace Internal { -TextEditorActionHandler::TextEditorActionHandler(QObject *parent, Core::Id contextId, - uint optionalActions) - : QObject(parent), +class TextEditorActionHandlerPrivate : public QObject +{ + Q_OBJECT + +public: + TextEditorActionHandlerPrivate(TextEditorActionHandler *parent, + Core::Id contextId, + uint optionalActions); + + QAction *registerAction(Core::Id id, + const char *slot, + bool scriptable = false, + const QString &title = QString(), + const QKeySequence &keySequence = QKeySequence(), + const char *menueGroup = 0, + Core::ActionContainer *container = 0); + + void createActions(); + +public slots: + void updateActions(); + void updateRedoAction(); + void updateUndoAction(); + void updateCopyAction(); + + void undoAction(); + void redoAction(); + void copyAction(); + void cutAction(); + void pasteAction(); + void circularPasteAction(); + void switchUtf8bomAction(); + void selectAllAction(); + void gotoAction(); + void printAction(); + void formatAction(); + void rewrapParagraphAction(); + void setVisualizeWhitespace(bool); + void cleanWhitespace(); + void setTextWrapping(bool); + void unCommentSelection(); + void unfoldAll(); + void fold(); + void unfold(); + void cutLine(); + void copyLine(); + void deleteLine(); + void deleteEndOfWord(); + void deleteEndOfWordCamelCase(); + void deleteStartOfWord(); + void deleteStartOfWordCamelCase(); + void selectEncoding(); + void increaseFontSize(); + void decreaseFontSize(); + void resetFontSize(); + void gotoBlockStart(); + void gotoBlockEnd(); + void gotoBlockStartWithSelection(); + void gotoBlockEndWithSelection(); + void selectBlockUp(); + void selectBlockDown(); + void viewPageUp(); + void viewPageDown(); + void viewLineUp(); + void viewLineDown(); + void moveLineUp(); + void moveLineDown(); + void copyLineUp(); + void copyLineDown(); + void joinLines(); + void insertLineAbove(); + void insertLineBelow(); + void uppercaseSelection(); + void lowercaseSelection(); + void updateCurrentEditor(Core::IEditor *editor); + void indent(); + void unindent(); + void openLinkUnderCursor(); + void openLinkUnderCursorInNextSplit(); + + void gotoLineStart(); + void gotoLineStartWithSelection(); + void gotoLineEnd(); + void gotoLineEndWithSelection(); + void gotoNextLine(); + void gotoNextLineWithSelection(); + void gotoPreviousLine(); + void gotoPreviousLineWithSelection(); + void gotoPreviousCharacter(); + void gotoPreviousCharacterWithSelection(); + void gotoNextCharacter(); + void gotoNextCharacterWithSelection(); + void gotoPreviousWord(); + void gotoPreviousWordWithSelection(); + void gotoNextWord(); + void gotoNextWordWithSelection(); + void gotoPreviousWordCamelCase(); + void gotoPreviousWordCamelCaseWithSelection(); + void gotoNextWordCamelCase(); + void gotoNextWordCamelCaseWithSelection(); + +public: + TextEditorActionHandler *q; + QAction *m_undoAction; + QAction *m_redoAction; + QAction *m_copyAction; + QAction *m_cutAction; + QAction *m_pasteAction; + QAction *m_circularPasteAction; + QAction *m_switchUtf8bomAction; + QAction *m_selectAllAction; + QAction *m_gotoAction; + QAction *m_printAction; + QAction *m_formatAction; + QAction *m_rewrapParagraphAction; + QAction *m_visualizeWhitespaceAction; + QAction *m_cleanWhitespaceAction; + QAction *m_textWrappingAction; + QAction *m_unCommentSelectionAction; + QAction *m_unfoldAllAction; + QAction *m_foldAction; + QAction *m_unfoldAction; + QAction *m_cutLineAction; + QAction *m_copyLineAction; + QAction *m_deleteLineAction; + QAction *m_deleteEndOfWordAction; + QAction *m_deleteEndOfWordCamelCaseAction; + QAction *m_deleteStartOfWordAction; + QAction *m_deleteStartOfWordCamelCaseAction; + QAction *m_selectEncodingAction; + QAction *m_increaseFontSizeAction; + QAction *m_decreaseFontSizeAction; + QAction *m_resetFontSizeAction; + QAction *m_gotoBlockStartAction; + QAction *m_gotoBlockEndAction; + QAction *m_gotoBlockStartWithSelectionAction; + QAction *m_gotoBlockEndWithSelectionAction; + QAction *m_selectBlockUpAction; + QAction *m_selectBlockDownAction; + QAction *m_viewPageUpAction; + QAction *m_viewPageDownAction; + QAction *m_viewLineUpAction; + QAction *m_viewLineDownAction; + QAction *m_moveLineUpAction; + QAction *m_moveLineDownAction; + QAction *m_copyLineUpAction; + QAction *m_copyLineDownAction; + QAction *m_joinLinesAction; + QAction *m_insertLineAboveAction; + QAction *m_insertLineBelowAction; + QAction *m_upperCaseSelectionAction; + QAction *m_lowerCaseSelectionAction; + QAction *m_indentAction; + QAction *m_unindentAction; + QAction *m_followSymbolAction; + QAction *m_followSymbolInNextSplitAction; + QAction *m_jumpToFileAction; + QAction *m_jumpToFileInNextSplitAction; + QList m_modifyingActions; + + uint m_optionalActions; + QPointer m_currentEditorWidget; + Core::Id m_contextId; +}; + +TextEditorActionHandlerPrivate::TextEditorActionHandlerPrivate + (TextEditorActionHandler *parent, Core::Id contextId, uint optionalActions) + : q(parent), m_undoAction(0), m_redoAction(0), m_copyAction(0), @@ -115,11 +280,7 @@ TextEditorActionHandler::TextEditorActionHandler(QObject *parent, Core::Id conte this, SLOT(updateCurrentEditor(Core::IEditor*))); } -TextEditorActionHandler::~TextEditorActionHandler() -{ -} - -void TextEditorActionHandler::createActions() +void TextEditorActionHandlerPrivate::createActions() { using namespace Core::Constants; using namespace TextEditor::Constants; @@ -375,20 +536,20 @@ void TextEditorActionHandler::createActions() m_modifyingActions << m_unindentAction; // set enabled state of optional actions - m_followSymbolAction->setEnabled(m_optionalActions & FollowSymbolUnderCursor); - m_followSymbolInNextSplitAction->setEnabled(m_optionalActions & FollowSymbolUnderCursor); - m_jumpToFileAction->setEnabled(m_optionalActions & JumpToFileUnderCursor); - m_jumpToFileInNextSplitAction->setEnabled(m_optionalActions & JumpToFileUnderCursor); - m_unfoldAllAction->setEnabled(m_optionalActions & UnCollapseAll); + m_followSymbolAction->setEnabled(m_optionalActions & TextEditorActionHandler::FollowSymbolUnderCursor); + m_followSymbolInNextSplitAction->setEnabled(m_optionalActions & TextEditorActionHandler::FollowSymbolUnderCursor); + m_jumpToFileAction->setEnabled(m_optionalActions & TextEditorActionHandler::JumpToFileUnderCursor); + m_jumpToFileInNextSplitAction->setEnabled(m_optionalActions & TextEditorActionHandler::JumpToFileUnderCursor); + m_unfoldAllAction->setEnabled(m_optionalActions & TextEditorActionHandler::UnCollapseAll); } -QAction *TextEditorActionHandler::registerAction(Core::Id id, - const char *slot, - bool scriptable, - const QString &title, - const QKeySequence &keySequence, - const char *menueGroup, - Core::ActionContainer *container) +QAction *TextEditorActionHandlerPrivate::registerAction(Core::Id id, + const char *slot, + bool scriptable, + const QString &title, + const QKeySequence &keySequence, + const char *menueGroup, + Core::ActionContainer *container) { QAction *result = new QAction(title, this); Core::Command *command = Core::ActionManager::registerAction(result, id, Core::Context(m_contextId), scriptable); @@ -402,14 +563,14 @@ QAction *TextEditorActionHandler::registerAction(Core::Id id, return result; } -void TextEditorActionHandler::updateActions() +void TextEditorActionHandlerPrivate::updateActions() { QTC_ASSERT(m_currentEditorWidget, return); bool isWritable = !m_currentEditorWidget->isReadOnly(); foreach (QAction *a, m_modifyingActions) a->setEnabled(isWritable); - m_formatAction->setEnabled((m_optionalActions & Format) && isWritable); - m_unCommentSelectionAction->setEnabled((m_optionalActions & UnCommentSelection) && isWritable); + m_formatAction->setEnabled((m_optionalActions & TextEditorActionHandler::Format) && isWritable); + m_unCommentSelectionAction->setEnabled((m_optionalActions & TextEditorActionHandler::UnCommentSelection) && isWritable); m_visualizeWhitespaceAction->setChecked(m_currentEditorWidget->displaySettings().m_visualizeWhitespace); m_textWrappingAction->setChecked(m_currentEditorWidget->displaySettings().m_textWrapping); @@ -418,19 +579,19 @@ void TextEditorActionHandler::updateActions() updateCopyAction(); } -void TextEditorActionHandler::updateRedoAction() +void TextEditorActionHandlerPrivate::updateRedoAction() { QTC_ASSERT(m_currentEditorWidget, return); m_redoAction->setEnabled(m_currentEditorWidget->document()->isRedoAvailable()); } -void TextEditorActionHandler::updateUndoAction() +void TextEditorActionHandlerPrivate::updateUndoAction() { QTC_ASSERT(m_currentEditorWidget, return); m_undoAction->setEnabled(m_currentEditorWidget->document()->isUndoAvailable()); } -void TextEditorActionHandler::updateCopyAction() +void TextEditorActionHandlerPrivate::updateCopyAction() { QTC_ASSERT(m_currentEditorWidget, return); const bool hasCopyableText = m_currentEditorWidget->textCursor().hasSelection(); @@ -440,7 +601,7 @@ void TextEditorActionHandler::updateCopyAction() m_copyAction->setEnabled(hasCopyableText); } -void TextEditorActionHandler::gotoAction() +void TextEditorActionHandlerPrivate::gotoAction() { QString locatorString = TextEditorPlugin::lineNumberFilter()->shortcutString(); locatorString += QLatin1Char(' '); @@ -449,13 +610,13 @@ void TextEditorActionHandler::gotoAction() Core::LocatorManager::show(locatorString, selectionStart, locatorString.size() - selectionStart); } -void TextEditorActionHandler::printAction() +void TextEditorActionHandlerPrivate::printAction() { if (m_currentEditorWidget) m_currentEditorWidget->print(Core::ICore::printer()); } -void TextEditorActionHandler::setVisualizeWhitespace(bool checked) +void TextEditorActionHandlerPrivate::setVisualizeWhitespace(bool checked) { if (m_currentEditorWidget) { DisplaySettings ds = m_currentEditorWidget->displaySettings(); @@ -464,7 +625,7 @@ void TextEditorActionHandler::setVisualizeWhitespace(bool checked) } } -void TextEditorActionHandler::setTextWrapping(bool checked) +void TextEditorActionHandlerPrivate::setTextWrapping(bool checked) { if (m_currentEditorWidget) { DisplaySettings ds = m_currentEditorWidget->displaySettings(); @@ -473,12 +634,12 @@ void TextEditorActionHandler::setTextWrapping(bool checked) } } -#define FUNCTION(funcname) void TextEditorActionHandler::funcname ()\ +#define FUNCTION(funcname) void TextEditorActionHandlerPrivate::funcname ()\ {\ if (m_currentEditorWidget)\ m_currentEditorWidget->funcname ();\ } -#define FUNCTION2(funcname, funcname2) void TextEditorActionHandler::funcname ()\ +#define FUNCTION2(funcname, funcname2) void TextEditorActionHandlerPrivate::funcname ()\ {\ if (m_currentEditorWidget)\ m_currentEditorWidget->funcname2 ();\ @@ -557,12 +718,7 @@ FUNCTION(gotoNextWordCamelCase) FUNCTION(gotoNextWordCamelCaseWithSelection) -BaseTextEditorWidget *TextEditorActionHandler::resolveTextEditorWidget(Core::IEditor *editor) const -{ - return qobject_cast(editor->widget()); -} - -void TextEditorActionHandler::updateCurrentEditor(Core::IEditor *editor) +void TextEditorActionHandlerPrivate::updateCurrentEditor(Core::IEditor *editor) { if (m_currentEditorWidget) m_currentEditorWidget->disconnect(this); @@ -573,7 +729,7 @@ void TextEditorActionHandler::updateCurrentEditor(Core::IEditor *editor) if (!editor || !editor->context().contains(m_contextId)) return; - BaseTextEditorWidget *editorWidget = resolveTextEditorWidget(editor); + BaseTextEditorWidget *editorWidget = q->resolveTextEditorWidget(editor); QTC_ASSERT(editorWidget, return); // editor has our context id, so shouldn't happen m_currentEditorWidget = editorWidget; connect(m_currentEditorWidget, SIGNAL(undoAvailable(bool)), this, SLOT(updateUndoAction())); @@ -582,3 +738,24 @@ void TextEditorActionHandler::updateCurrentEditor(Core::IEditor *editor) connect(m_currentEditorWidget, SIGNAL(readOnlyChanged()), this, SLOT(updateActions())); updateActions(); } + +} // namespace Internal + +TextEditorActionHandler::TextEditorActionHandler(QObject *parent, Core::Id contextId, uint optionalActions) + : QObject(parent), d(new Internal::TextEditorActionHandlerPrivate(this, contextId, optionalActions)) +{ +} + +TextEditorActionHandler::~TextEditorActionHandler() +{ + delete d; +} + +BaseTextEditorWidget *TextEditorActionHandler::resolveTextEditorWidget(Core::IEditor *editor) const +{ + return qobject_cast(editor->widget()); +} + +} // namespace TextEditor + +#include "texteditoractionhandler.moc" diff --git a/src/plugins/texteditor/texteditoractionhandler.h b/src/plugins/texteditor/texteditoractionhandler.h index 292eafe0686..3006faf455f 100644 --- a/src/plugins/texteditor/texteditoractionhandler.h +++ b/src/plugins/texteditor/texteditoractionhandler.h @@ -32,23 +32,17 @@ #include "texteditor_global.h" -#include +#include #include -#include -#include -QT_FORWARD_DECLARE_CLASS(QAction) - -namespace Core { -class ICore; -class IEditor; -class ActionContainer; -} +namespace Core { class IEditor; } namespace TextEditor { class BaseTextEditorWidget; +namespace Internal { class TextEditorActionHandlerPrivate; } + // Redirects slots from global actions to the respective editor. class TEXTEDITOR_EXPORT TextEditorActionHandler : public QObject @@ -72,160 +66,8 @@ protected: virtual BaseTextEditorWidget *resolveTextEditorWidget(Core::IEditor *editor) const; private: - QAction *registerAction(Core::Id id, - const char *slot, - bool scriptable = false, - const QString &title = QString(), - const QKeySequence &keySequence = QKeySequence(), - const char *menueGroup = 0, - Core::ActionContainer *container = 0); - - void createActions(); - -private slots: - void updateActions(); - void updateRedoAction(); - void updateUndoAction(); - void updateCopyAction(); - - void undoAction(); - void redoAction(); - void copyAction(); - void cutAction(); - void pasteAction(); - void circularPasteAction(); - void switchUtf8bomAction(); - void selectAllAction(); - void gotoAction(); - void printAction(); - void formatAction(); - void rewrapParagraphAction(); - void setVisualizeWhitespace(bool); - void cleanWhitespace(); - void setTextWrapping(bool); - void unCommentSelection(); - void unfoldAll(); - void fold(); - void unfold(); - void cutLine(); - void copyLine(); - void deleteLine(); - void deleteEndOfWord(); - void deleteEndOfWordCamelCase(); - void deleteStartOfWord(); - void deleteStartOfWordCamelCase(); - void selectEncoding(); - void increaseFontSize(); - void decreaseFontSize(); - void resetFontSize(); - void gotoBlockStart(); - void gotoBlockEnd(); - void gotoBlockStartWithSelection(); - void gotoBlockEndWithSelection(); - void selectBlockUp(); - void selectBlockDown(); - void viewPageUp(); - void viewPageDown(); - void viewLineUp(); - void viewLineDown(); - void moveLineUp(); - void moveLineDown(); - void copyLineUp(); - void copyLineDown(); - void joinLines(); - void insertLineAbove(); - void insertLineBelow(); - void uppercaseSelection(); - void lowercaseSelection(); - void updateCurrentEditor(Core::IEditor *editor); - void indent(); - void unindent(); - void openLinkUnderCursor(); - void openLinkUnderCursorInNextSplit(); - - void gotoLineStart(); - void gotoLineStartWithSelection(); - void gotoLineEnd(); - void gotoLineEndWithSelection(); - void gotoNextLine(); - void gotoNextLineWithSelection(); - void gotoPreviousLine(); - void gotoPreviousLineWithSelection(); - void gotoPreviousCharacter(); - void gotoPreviousCharacterWithSelection(); - void gotoNextCharacter(); - void gotoNextCharacterWithSelection(); - void gotoPreviousWord(); - void gotoPreviousWordWithSelection(); - void gotoNextWord(); - void gotoNextWordWithSelection(); - void gotoPreviousWordCamelCase(); - void gotoPreviousWordCamelCaseWithSelection(); - void gotoNextWordCamelCase(); - void gotoNextWordCamelCaseWithSelection(); - - -private: - QAction *m_undoAction; - QAction *m_redoAction; - QAction *m_copyAction; - QAction *m_cutAction; - QAction *m_pasteAction; - QAction *m_circularPasteAction; - QAction *m_switchUtf8bomAction; - QAction *m_selectAllAction; - QAction *m_gotoAction; - QAction *m_printAction; - QAction *m_formatAction; - QAction *m_rewrapParagraphAction; - QAction *m_visualizeWhitespaceAction; - QAction *m_cleanWhitespaceAction; - QAction *m_textWrappingAction; - QAction *m_unCommentSelectionAction; - QAction *m_unfoldAllAction; - QAction *m_foldAction; - QAction *m_unfoldAction; - QAction *m_cutLineAction; - QAction *m_copyLineAction; - QAction *m_deleteLineAction; - QAction *m_deleteEndOfWordAction; - QAction *m_deleteEndOfWordCamelCaseAction; - QAction *m_deleteStartOfWordAction; - QAction *m_deleteStartOfWordCamelCaseAction; - QAction *m_selectEncodingAction; - QAction *m_increaseFontSizeAction; - QAction *m_decreaseFontSizeAction; - QAction *m_resetFontSizeAction; - QAction *m_gotoBlockStartAction; - QAction *m_gotoBlockEndAction; - QAction *m_gotoBlockStartWithSelectionAction; - QAction *m_gotoBlockEndWithSelectionAction; - QAction *m_selectBlockUpAction; - QAction *m_selectBlockDownAction; - QAction *m_viewPageUpAction; - QAction *m_viewPageDownAction; - QAction *m_viewLineUpAction; - QAction *m_viewLineDownAction; - QAction *m_moveLineUpAction; - QAction *m_moveLineDownAction; - QAction *m_copyLineUpAction; - QAction *m_copyLineDownAction; - QAction *m_joinLinesAction; - QAction *m_insertLineAboveAction; - QAction *m_insertLineBelowAction; - QAction *m_upperCaseSelectionAction; - QAction *m_lowerCaseSelectionAction; - QAction *m_indentAction; - QAction *m_unindentAction; - QAction *m_followSymbolAction; - QAction *m_followSymbolInNextSplitAction; - QAction *m_jumpToFileAction; - QAction *m_jumpToFileInNextSplitAction; - QList m_modifyingActions; - - uint m_optionalActions; - QPointer m_currentEditorWidget; - Core::Id m_contextId; + friend class Internal::TextEditorActionHandlerPrivate; + Internal::TextEditorActionHandlerPrivate *d; }; } // namespace TextEditor diff --git a/src/plugins/todo/cpptodoitemsscanner.cpp b/src/plugins/todo/cpptodoitemsscanner.cpp index f4f9e7b4bd0..5ff7d14907f 100644 --- a/src/plugins/todo/cpptodoitemsscanner.cpp +++ b/src/plugins/todo/cpptodoitemsscanner.cpp @@ -45,17 +45,6 @@ CppTodoItemsScanner::CppTodoItemsScanner(const KeywordList &keywordList, QObject SLOT(documentUpdated(CPlusPlus::Document::Ptr)), Qt::DirectConnection); } -bool CppTodoItemsScanner::shouldProcessFile(const QString &fileName) -{ - CppTools::CppModelManagerInterface *modelManager = CppTools::CppModelManagerInterface::instance(); - - foreach (const CppTools::CppModelManagerInterface::ProjectInfo &info, modelManager->projectInfos()) - if (info.project().data()->files(ProjectExplorer::Project::ExcludeGeneratedFiles).contains(fileName)) - return true; - - return false; -} - void CppTodoItemsScanner::keywordListChanged() { // We need to rescan everything known to the code model @@ -72,7 +61,8 @@ void CppTodoItemsScanner::keywordListChanged() void CppTodoItemsScanner::documentUpdated(CPlusPlus::Document::Ptr doc) { - if (shouldProcessFile(doc->fileName())) + CppTools::CppModelManagerInterface *modelManager = CppTools::CppModelManagerInterface::instance(); + if (!modelManager->projectPart(doc->fileName()).isEmpty()) processDocument(doc); } diff --git a/src/plugins/todo/cpptodoitemsscanner.h b/src/plugins/todo/cpptodoitemsscanner.h index aba7414b758..78a7d9158d0 100644 --- a/src/plugins/todo/cpptodoitemsscanner.h +++ b/src/plugins/todo/cpptodoitemsscanner.h @@ -46,7 +46,6 @@ public: explicit CppTodoItemsScanner(const KeywordList &keywordList, QObject *parent = 0); protected: - bool shouldProcessFile(const QString &fileName); void keywordListChanged(); private slots: diff --git a/src/plugins/todo/qmljstodoitemsscanner.cpp b/src/plugins/todo/qmljstodoitemsscanner.cpp index 08a10d03f47..209d5713a1d 100644 --- a/src/plugins/todo/qmljstodoitemsscanner.cpp +++ b/src/plugins/todo/qmljstodoitemsscanner.cpp @@ -62,7 +62,7 @@ void QmlJsTodoItemsScanner::keywordListChanged() QStringList filesToBeUpdated; foreach (const QmlJS::ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos()) - filesToBeUpdated << info.project->files(ProjectExplorer::Project::ExcludeGeneratedFiles); + filesToBeUpdated << info.sourceFiles; modelManager->updateSourceFiles(filesToBeUpdated, false); } diff --git a/src/plugins/valgrind/callgrind/callgrindcontroller.cpp b/src/plugins/valgrind/callgrind/callgrindcontroller.cpp index 04c7d59c52b..535931aa9f4 100644 --- a/src/plugins/valgrind/callgrind/callgrindcontroller.cpp +++ b/src/plugins/valgrind/callgrind/callgrindcontroller.cpp @@ -155,7 +155,7 @@ void CallgrindController::processFinished(int rc, QProcess::ExitStatus status) QTC_ASSERT(m_process, return); const QString error = m_process->errorString(); - delete m_process; + m_process->deleteLater(); // Called directly from finished() signal in m_process m_process = 0; if (rc != 0 || status != QProcess::NormalExit) { diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index f323b46ce2e..99bb3ab4c94 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -84,7 +84,7 @@ bool ValgrindRunControl::startEngine() const AnalyzerStartParameters &sp = startParameters(); #if VALGRIND_DEBUG_OUTPUT - emit outputReceived(tr("Valgrind options: %1").arg(toolArguments().join(QLatin1Char(' '))), DebugFormat); + emit outputReceived(tr("Valgrind options: %1").arg(toolArguments().join(QLatin1String(" "))), DebugFormat); emit outputReceived(tr("Working directory: %1").arg(sp.workingDirectory), DebugFormat); emit outputReceived(tr("Command line arguments: %1").arg(sp.debuggeeArgs), DebugFormat); #endif diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index 1c13198007d..0616329a0eb 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -1378,8 +1378,7 @@ QString VcsBaseEditorWidget::findDiffFile(const QString &f) const if (sourceFileInfo.isFile()) return sourceFileInfo.absoluteFilePath(); - QString topLevel; - Core::VcsManager::findVersionControlForDirectory(sourceDir, &topLevel); // + const QString topLevel = Core::VcsManager::findTopLevelForDirectory(sourceDir); if (topLevel.isEmpty()) return QString(); diff --git a/src/plugins/vcsbase/vcsplugin.cpp b/src/plugins/vcsbase/vcsplugin.cpp index 1ea2bf04f10..ca604bb6541 100644 --- a/src/plugins/vcsbase/vcsplugin.cpp +++ b/src/plugins/vcsbase/vcsplugin.cpp @@ -108,10 +108,9 @@ bool VcsPlugin::initialize(const QStringList &arguments, QString *errorMessage) VariableManager::registerVariable(Constants::VAR_VCS_TOPLEVELPATH, tr("The top level path to the repository the current project is in."), []() -> QString { - QString topLevel; if (Project *project = ProjectExplorerPlugin::currentProject()) - VcsManager::findVersionControlForDirectory(project->projectDirectory().toString(), &topLevel); - return topLevel; + return VcsManager::findTopLevelForDirectory(project->projectDirectory().toString()); + return QString(); }); return true; diff --git a/src/plugins/winrt/winrtpackagedeploymentstep.cpp b/src/plugins/winrt/winrtpackagedeploymentstep.cpp index 895dd925ed8..409719d492a 100644 --- a/src/plugins/winrt/winrtpackagedeploymentstep.cpp +++ b/src/plugins/winrt/winrtpackagedeploymentstep.cpp @@ -137,21 +137,28 @@ bool WinRtPackageDeploymentStep::processSucceeded(int exitCode, QProcess::ExitSt // if there are no INSTALLS set we just deploy the files from windeployqt, the manifest // and the icons referenced in there and the actual build target + QString baseDir; if (targetInstallationPath.isEmpty()) { targetPath += QLatin1String(".exe"); m_mappingFileContent += QLatin1Char('"') + QDir::toNativeSeparators(targetPath) + QLatin1String("\" \"") + QDir::toNativeSeparators(m_executablePathInManifest) + QLatin1String("\"\n"); + baseDir = targetDir; } else { - targetInstallationPath = targetInstallationPath.left(targetInstallationPath.lastIndexOf(QLatin1Char('/')) + 1); - for (int i = 0; i < installableFilesList.length(); ++i) { - QPair pair = installableFilesList.at(i); - // For the mapping file we need the remote paths relative to the application's executable - const QString relativeRemotePath = QDir(targetInstallationPath).relativeFilePath(pair.second); - m_mappingFileContent += QLatin1Char('"') + QDir::toNativeSeparators(pair.first) - + QLatin1String("\" \"") + QDir::toNativeSeparators(relativeRemotePath) - + QLatin1String("\"\n"); - } + baseDir = targetInstallationPath.left(targetInstallationPath.lastIndexOf(QLatin1Char('/')) + 1); + } + + typedef QPair QStringPair; + foreach (const QStringPair &pair, installableFilesList) { + // For the mapping file we need the remote paths relative to the application's executable + QString relativeRemotePath; + if (QDir(pair.second).isRelative()) + relativeRemotePath = pair.second; + else + relativeRemotePath = QDir(baseDir).relativeFilePath(pair.second); + m_mappingFileContent += QLatin1Char('"') + QDir::toNativeSeparators(pair.first) + + QLatin1String("\" \"") + QDir::toNativeSeparators(relativeRemotePath) + + QLatin1String("\"\n"); } const QString mappingFilePath = targetDir + m_manifestFileName + QLatin1String(".map"); diff --git a/src/shared/qbs b/src/shared/qbs index 5e77a9d1927..c653f6ab0d0 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 5e77a9d1927ec4f3ab405824a92d48930d48c487 +Subproject commit c653f6ab0d04a39298f9b4365528372dee5b302a diff --git a/src/tools/3rdparty/iossim/iphonesimulator.mm b/src/tools/3rdparty/iossim/iphonesimulator.mm index ccb46614478..40425775d9b 100644 --- a/src/tools/3rdparty/iossim/iphonesimulator.mm +++ b/src/tools/3rdparty/iossim/iphonesimulator.mm @@ -516,7 +516,7 @@ NSString* FindDeveloperDir() { NSString *stdoutPath = nil; NSString *stderrPath = nil; NSString *xctest = nil; - NSTimeInterval timeout = 30; + NSTimeInterval timeout = 60; NSMutableDictionary *environment = [NSMutableDictionary dictionary]; int i = argOffset; diff --git a/src/tools/3rdparty/iossim_1_8_2/iphonesimulator.mm b/src/tools/3rdparty/iossim_1_8_2/iphonesimulator.mm index b06b54276d5..141393ea03f 100644 --- a/src/tools/3rdparty/iossim_1_8_2/iphonesimulator.mm +++ b/src/tools/3rdparty/iossim_1_8_2/iphonesimulator.mm @@ -425,7 +425,7 @@ NSString *deviceIpadRetina = @"iPad (Retina)"; NSString *uuid = nil; NSString *stdoutPath = nil; NSString *stderrPath = nil; - NSTimeInterval timeout = 30; + NSTimeInterval timeout = 60; NSMutableDictionary *environment = [NSMutableDictionary dictionary]; int i = argOffset; diff --git a/src/tools/sdktool/adddeviceoperation.cpp b/src/tools/sdktool/adddeviceoperation.cpp index a98a8e578e4..ee3b1c70879 100644 --- a/src/tools/sdktool/adddeviceoperation.cpp +++ b/src/tools/sdktool/adddeviceoperation.cpp @@ -82,7 +82,7 @@ QString AddDeviceOperation::argumentsHelpText() const bool AddDeviceOperation::setArguments(const QStringList &args) { m_authentication = -1; - m_origin = -1; + m_origin = 1; m_sshPort = 0; m_timeout = 5; m_type = -1; diff --git a/src/tools/sdktool/addkitoperation.cpp b/src/tools/sdktool/addkitoperation.cpp index 1aab466b356..6f18d1730a0 100644 --- a/src/tools/sdktool/addkitoperation.cpp +++ b/src/tools/sdktool/addkitoperation.cpp @@ -54,7 +54,7 @@ const char DEFAULT[] = "Profile.Default"; const char ID[] = "PE.Profile.Id"; const char DISPLAYNAME[] = "PE.Profile.Name"; const char ICON[] = "PE.Profile.Icon"; -const char AUTODETECTED[] = "PE.Profile.Autodetected"; +const char AUTODETECTED[] = "PE.Profile.AutoDetected"; const char SDK[] = "PE.Profile.SDK"; const char DATA[] = "PE.Profile.Data"; diff --git a/src/tools/sdktool/operation.cpp b/src/tools/sdktool/operation.cpp index 4d9c94598ae..5c068bbddd4 100644 --- a/src/tools/sdktool/operation.cpp +++ b/src/tools/sdktool/operation.cpp @@ -122,7 +122,7 @@ bool Operation::save(const QVariantMap &map, const QString &file) const Utils::FileName dirName = path.parentDir(); QDir dir(dirName.toString()); - if (!dir.exists() && !dir.mkpath(dirName.toString())) { + if (!dir.exists() && !dir.mkpath(QLatin1String("."))) { std::cerr << "Error: Could not create directory " << qPrintable(dirName.toString()) << "." << std::endl; return false; diff --git a/src/tools/sdktool/settings.cpp b/src/tools/sdktool/settings.cpp index 06c180cdca4..fab28a88d86 100644 --- a/src/tools/sdktool/settings.cpp +++ b/src/tools/sdktool/settings.cpp @@ -67,8 +67,6 @@ Utils::FileName Settings::getPath(const QString &file) result.appendPath(QLatin1String("qtversion")); else if (file == QLatin1String("toolchains") || file == QLatin1String("toolChains")) result.appendPath(QLatin1String("toolchains")); - else if (file == QLatin1String("toolchains") || file == QLatin1String("toolChains")) - result.appendPath(QLatin1String("toolchains")); else if (file == QLatin1String("devices")) result.appendPath(QLatin1String("devices")); else if (file == QLatin1String("android")) diff --git a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp index c31c69178f4..07cd07eb42e 100644 --- a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp +++ b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp @@ -125,6 +125,7 @@ public: // Preprocess source Environment env; Preprocessor preprocess(0, &env); + preprocess.setKeepComments(true); const QByteArray preprocessedSource = preprocess.run(filePath, source); document->setUtf8Source(preprocessedSource); @@ -1687,6 +1688,26 @@ void tst_CheckSymbols::test_checksymbols_data() << Use(9, 1, 5, Highlighting::TypeUse) << Use(9, 1, 5, Highlighting::TypeUse) << Use(9, 9, 5, Highlighting::TypeUse)); + +#define UC_U10302_4TIMES UC_U10302 UC_U10302 UC_U10302 UC_U10302 +#define UC_U10302_12TIMES UC_U10302_4TIMES UC_U10302_4TIMES UC_U10302_4TIMES + QTest::newRow("unicodeComments1") + << _("#define NULL 0\n" + "\n" + "// " UC_U10302_12TIMES "\n" + "// " UC_U10302_12TIMES "\n" + "\n" + "class Foo {\n" + "double f(bool b = NULL);\n" + "Foo *x;\n" + "};\n") + << (UseList() + << Use(6, 7, 3, CppHighlightingSupport::TypeUse) + << Use(7, 8, 1, CppHighlightingSupport::FunctionUse) + << Use(8, 1, 3, CppHighlightingSupport::TypeUse) + << Use(8, 6, 1, CppHighlightingSupport::FieldUse)); +#undef UC_U10302_12TIMES +#undef UC_U10302_4TIMES } void tst_CheckSymbols::test_checksymbols_macroUses() diff --git a/tests/auto/cplusplus/cxx11/data/lambda.2.cpp b/tests/auto/cplusplus/cxx11/data/lambda.2.cpp new file mode 100644 index 00000000000..f638616a160 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/lambda.2.cpp @@ -0,0 +1,6 @@ +void f() +{ + func([]() -> int { return 42; }); + func([]() -> int { return 42; }); +} + diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp index 69dbac85f85..1bb998b2e39 100644 --- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp +++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp @@ -157,6 +157,7 @@ void tst_cxx11::parse_data() QTest::newRow("declType.1") << "declType.1.cpp" << ""; QTest::newRow("threadLocal.1") << "threadLocal.1.cpp" << ""; QTest::newRow("trailingtypespec.1") << "trailingtypespec.1.cpp" << ""; + QTest::newRow("lambda.2") << "lambda.2.cpp" << ""; } void tst_cxx11::parse() diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 15e75b36f91..e3b79fd1c60 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1198,7 +1198,7 @@ void tst_Dumpers::dumper() << QString::fromUtf8(m_debuggerBinary) << t->buildPath + QLatin1String("/doit") << QString::fromUtf8(expanded); - //qDebug() << exe.constData() << ' ' << qPrintable(args.join(QLatin1Char(' '))); + //qDebug() << exe.constData() << ' ' << qPrintable(args.join(QLatin1String(" "))); } t->input = cmds; diff --git a/tests/auto/extensionsystem/pluginspec/testspecs/spec2.xml b/tests/auto/extensionsystem/pluginspec/testspecs/spec2.xml index 454f58cb755..24d272902a7 100644 --- a/tests/auto/extensionsystem/pluginspec/testspecs/spec2.xml +++ b/tests/auto/extensionsystem/pluginspec/testspecs/spec2.xml @@ -1,2 +1,2 @@ - + diff --git a/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp b/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp index dcb1e67b168..8318a6bea6a 100644 --- a/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp +++ b/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp @@ -74,6 +74,7 @@ void tst_PluginSpec::read() QCOMPARE(spec.name, QString("test")); QCOMPARE(spec.version, QString("1.0.1")); QCOMPARE(spec.compatVersion, QString("1.0.0")); + QCOMPARE(spec.required, false); QCOMPARE(spec.experimental, false); QCOMPARE(spec.enabledInSettings, true); QCOMPARE(spec.vendor, QString("Digia Plc")); @@ -90,9 +91,11 @@ void tst_PluginSpec::read() QCOMPARE(spec.dependencies, QList() << dep1 << dep2); // test missing compatVersion behavior + // and 'required' attribute QVERIFY(spec.read("testspecs/spec2.xml")); QCOMPARE(spec.version, QString("3.1.4_10")); QCOMPARE(spec.compatVersion, QString("3.1.4_10")); + QCOMPARE(spec.required, true); } void tst_PluginSpec::readError() diff --git a/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt48.tsv b/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt48.tsv index f343052ac2d..443e686825b 100644 --- a/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt48.tsv +++ b/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt48.tsv @@ -4,5 +4,5 @@ "main.qml:1" "Create" "1" "main.qml" "main.qml:1" "Compile" "1" "main.qml" "main.qml:31" "Binding" "1" "text: qsTr(""Hello World"")" -"" "Binding" "2" "" +"" "Binding" "2" "Source code not available" "main.qml:11" "Binding" "3" "running: runCount < 2" diff --git a/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt50.tsv b/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt50.tsv index 7f1b3ab4f7e..c9027ef163e 100644 --- a/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt50.tsv +++ b/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt50.tsv @@ -4,5 +4,5 @@ "main.qml:12" "Signal" "2" "triggered(): { runCount += 1; var i; for (i = 1; i < 2500; ++i) { var j = i * i; console.log(j); } }" "main.qml:1" "Compile" "1" "main.qml" "main.qml:31" "Binding" "1" "text: qsTr(""Hello World"")" -"" "Binding" "2" "" +"" "Binding" "2" "Source code not available" "main.qml:11" "Binding" "3" "running: runCount < 2" diff --git a/tests/system/suite_qtquick/tst_qml_outline/test.py b/tests/system/suite_qtquick/tst_qml_outline/test.py index 879e05e3089..f73e3a7086d 100644 --- a/tests/system/suite_qtquick/tst_qml_outline/test.py +++ b/tests/system/suite_qtquick/tst_qml_outline/test.py @@ -63,8 +63,7 @@ def buildTreeFromOutline(): global outline model = waitForObject(outline).model() waitFor("model.rowCount() > 0") - if platform.system() == 'Darwin': - snooze(1) # if model updates delayed processChildren() results in AUT crash + snooze(1) # if model updates delayed processChildren() results in AUT crash return processChildren(model, QModelIndex(), 0) def processChildren(model, startIndex, level):