diff --git a/dist/changes-3.5.0.md b/dist/changes-3.5.0.md index f2424ffb103..bd15c164f29 100644 --- a/dist/changes-3.5.0.md +++ b/dist/changes-3.5.0.md @@ -79,8 +79,10 @@ QML Profiler C++ Support * Added separate icon for structs +* Added support for setting the access specifier of an extracted function (QTCREATORBUG-12127) * Fixed *Convert to Stack Variable* refactoring action for empty initializer lists (QTCREATORBUG-14279) +* Fixed misplaced newlines of refactoring actions (QTCREATORBUG-13872) * Fixed expanding items in class view with double-click (QTCREATORBUG-2536) * Fixed code folding issues after missing closing braces @@ -93,10 +95,7 @@ C++ Support * Partially fixed STL containers (QTCREATORBUG-8937, QTCREATORBUG-8922) * GCC implementation of `std::map`, `std::unique_ptr` (and other pointer wrappers) and `std::vector` are known to work - * Known limitations: - * MSVC implementation is not supported - * types that contain a typedef for `pointer` are not supported - (For example: `std::unique_ptr`) + * MSVC implementation is not supported QML Support @@ -119,6 +118,10 @@ Todo * Added option to excluding file patterns from parsing +Beautifier + +* Added option to format only selected lines with Uncrustify (`--frag`) + Platform Specific Windows diff --git a/dist/installer/ifw/config/config-linux.xml.in b/dist/installer/ifw/config/config-linux.xml.in index ecc965eec00..21cd64a425b 100644 --- a/dist/installer/ifw/config/config-linux.xml.in +++ b/dist/installer/ifw/config/config-linux.xml.in @@ -8,7 +8,8 @@ logo.png watermark.png - QtCreatorUninstaller + 520 + QtCreatorUninstaller @homeDir@/qtcreator-{version} /opt/qtcreator-{version} diff --git a/dist/installer/ifw/config/config-mac.xml.in b/dist/installer/ifw/config/config-mac.xml.in index 72bdd23dedc..e3ecc20ed92 100644 --- a/dist/installer/ifw/config/config-mac.xml.in +++ b/dist/installer/ifw/config/config-mac.xml.in @@ -8,7 +8,8 @@ logo.png background.png - Uninstall Qt Creator + 560 + Uninstall Qt Creator @homeDir@/Applications/Qt Creator {version} true diff --git a/dist/installer/ifw/config/config-windows.xml.in b/dist/installer/ifw/config/config-windows.xml.in index fce2db2a021..33c29dd5941 100644 --- a/dist/installer/ifw/config/config-windows.xml.in +++ b/dist/installer/ifw/config/config-windows.xml.in @@ -8,7 +8,8 @@ logo.png watermark.png - QtCreatorUninst + 560 + QtCreatorUninst @rootDir@/Qt/qtcreator-{version} diff --git a/doc/api/coding-style.qdoc b/doc/api/coding-style.qdoc index a8498b68bf2..8605afab185 100644 --- a/doc/api/coding-style.qdoc +++ b/doc/api/coding-style.qdoc @@ -50,7 +50,7 @@ \l{Patterns and Practices}. \li Document interfaces. Right now we use qdoc, but changing to doxygen is being considered. - \endlist + \endlist \section1 Submitting Code @@ -561,14 +561,15 @@ void someFunction() { ... } - } // namespace MyPlugin - \endcode + } // namespace MyPlugin + \endcode \li As an exception, if there is only a single class declaration inside the namespace, all can go on a single line: - \code - namespace MyPlugin { class MyClass; } - \endcode + + \code + namespace MyPlugin { class MyClass; } + \endcode \li Do not use using-directives in header files. @@ -1181,25 +1182,25 @@ your class. \li To improve code readability, always check whether a preprocessor - variable is defined before probing its value (\c{-Wundef}). + variable is defined before probing its value (\c {-Wundef}). \code - #if defined(Foo) && Foo == 0 + #if defined(Foo) && Foo == 0 -NOT- - #if Foo == 0 + #if Foo == 0 - -NOT- + -NOT- - #if Foo - 0 == 0 - \endcode + #if Foo - 0 == 0 + \endcode - \li When checking for a preprocessor define using the \c{defined} + \li When checking for a preprocessor define using the \c {defined} operator, always include the variable name in parentheses. \code - #if defined(Foo) + #if defined(Foo) -NOT- diff --git a/doc/api/creating-plugins.qdoc b/doc/api/creating-plugins.qdoc index 41b4ce8a3d8..aaa9a009a06 100644 --- a/doc/api/creating-plugins.qdoc +++ b/doc/api/creating-plugins.qdoc @@ -20,46 +20,50 @@ \page creating-plugins.html \title Creating Plugins - At its very core, \QC consists of a plugin loader that loads - and runs a set of plugins, which then actually provide the functionality - that you know from \QC the IDE. So, even the main application window - and menus are all provided by plugins. Plugins can use different means - to provide other plugins access to their functionality and to allow them - to extend certain aspects of the application. + At its very core, \QC consists of a plugin loader that loads and runs a set + of plugins, which then actually provide the functionality that you know from + \QC the IDE. So, even the main application window and menus are all provided + by plugins. Plugins can use different means to provide other plugins access + to their functionality and to allow them to extend certain aspects of the + application. - For example the "Core" plugin, which is the very basic plugin that must be + For example the \c Core plugin, which is the very basic plugin that must be present for \QC to run at all, provides the main window itself, and API for adding menu items, modes, editor types, navigation panels and many other things. - The "TextEditor" plugin provides a framework and base implementation for - different text editors with highlighting, completion and folding, that - is then used by other plugins to add more specialized text editor types - to \QC, like for editing C/C++ or .pro files. + + The \c TextEditor plugin provides a framework and base implementation for + different text editors with highlighting, completion and folding, that is + then used by other plugins to add more specialized text editor types to \QC, + like for editing C/C++ or \c {.pro} files. After reading this guide you will know what a basic plugin consists of, how to write a plugin specification file, what the lifecycle of a plugin is, - what the general principles for extending existing plugins' - functionality and providing interfaces for other plugins are, and will - be able to write your first plugin. + what the general principles for extending existing plugins' functionality + and providing interfaces for other plugins are, and will be able to write + your first plugin. \section1 Basics + \list - \li \l{Getting and Building Qt Creator} - \li \l{Creating Your First Plugin} - \li \l{Plugin Meta Data} - \li \l{Plugin Life Cycle} + \li \l{Getting and Building Qt Creator} + \li \l{Creating Your First Plugin} + \li \l{Plugin Meta Data} + \li \l{Plugin Life Cycle} \endlist \section1 Design Principles + \list - \li \l{The Plugin Manager, the Object Pool, and Registered Objects} - \li \l{Aggregations} - \li \l{Extending and Providing Interfaces} + \li \l{The Plugin Manager, the Object Pool, and Registered Objects} + \li \l{Aggregations} + \li \l{Extending and Providing Interfaces} \endlist \section1 Creating 3rd-Party Plugins + \list - \li \l{A Note on Binary Compatibility} - \li \l{Creating User-Installable Plugins} + \li \l{A Note on Binary Compatibility} + \li \l{Creating User-Installable Plugins} \endlist */ diff --git a/doc/api/first-plugin.qdoc b/doc/api/first-plugin.qdoc index 2684271b48d..995f15a51b6 100644 --- a/doc/api/first-plugin.qdoc +++ b/doc/api/first-plugin.qdoc @@ -21,28 +21,29 @@ \title Creating Your First Plugin This section describes how to create a \QC plugin by using the plugin - template provided by \QC, and get the first impression of what - a plugin consists of and what its general structure is. + template provided by \QC, and get the first impression of what a plugin + consists of and what its general structure is. \section1 Creating a Plugin Project - \QC comes with a wizard for \QC plugins, that creates a - runable, \e minimal plugin for you. We strongly suggest that you - use two different \QC instances for developing and testing - your plugin with. Otherwise your plugin will also be loaded in your - development environment, which can make that unstable while your - plugin is still unstable. You can just create a copy of your \QC - build and use one for actually developing, and the other for testing - your plugin with. + \QC comes with a wizard for \QC plugins, that creates a runable, \e minimal + plugin for you. We strongly suggest that you use two different \QC instances + for developing and testing your plugin with. Otherwise your plugin will also + be loaded in your development environment, which can make that unstable + while your plugin is still unstable. You can just create a copy of your \QC + build and use one for actually developing, and the other for testing your + plugin with. - You need to make sure that you use the same \QC version that you want - to develop for to create the plugin. Because of the - \l{Binary and Source Compatibility} rules of \QC, the \QC plugin wizard - creates a plugin that might only compile and run with the same \QC - version that it was created with. + You need to make sure that you use the same \QC version that you want to + develop for to create the plugin. Because of the \l{Binary and Source + Compatibility} rules of \QC, the \QC plugin wizard creates a plugin that + might only compile and run with the same \QC version that it was created + with. \list 1 - \li Select \uicontrol{File > New File or Project > Library > Qt Creator Plugin > Choose}. + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol Library > \uicontrol {Qt Creator Plugin} > + \uicontrol Choose. \image firstplugin-wizard.png "Choose the \QC Plugin Wizard" @@ -50,67 +51,75 @@ \image firstplugin-nameandpath.png "Choose Name and Place of the Project" - \li Give your project a name and specify in which path - this project will be created. The actual plugin's name can be different - from the project name. You will choose that name later in the wizard. + \li Give your project a name and specify in which path this project will + be created. The actual plugin's name can be different from the + project name. You will choose that name later in the wizard. Continue to the next page. - The \uicontrol{Kit Selection} dialog opens. + The \uicontrol {Kit Selection} dialog opens. \image firstplugin-kitselection.png "Choose the kit to build and run your project with" - \li Select the \l{glossary-buildandrun-kit}{kit} to build and run your project with. - For a \QC plugin this needs to be a kit with \uicontrol{Desktop} device type, - and a Qt version that is compatible with the Qt version that your - \QC was built with (in the best case the exact same build). - If you use an incompatible Qt version to build your plugin, you - will get errors while \QC tries to load your plugin. - Continue to the next page. + \li Select the \l{glossary-buildandrun-kit}{kit} to build and run your + project with. For a \QC plugin this needs to be a kit with + \uicontrol Desktop device type, and a Qt version that is compatible + with the Qt version that your \QC was built with (in the best case + the exact same build). If you use an incompatible Qt version to + build your plugin, you will get errors while \QC tries to load your + plugin. Continue to the next page. - The \uicontrol{Plugin Information} dialog opens. + The \uicontrol {Plugin Information} dialog opens. \image firstplugin-pluginsetup.png "Specify Your Plugin Details" - \li In the \uicontrol{Plugin name} field, type \uicontrol{Example}. The name of the plugin - is used as its identifier, and also is the base for the file names and - classes in the code. + \li In the \uicontrol {Plugin name} field, type \uicontrol Example. The + name of the plugin is used as its identifier, and also is the base + for the file names and classes in the code. \li The values of the following fields are mainly informational, and are shown in the detailed view in \QC's plugin overview - (\uicontrol{Help > About Plugins}, or \uicontrol{Qt Creator > About Plugins} - on Mac). + (\uicontrol Help > \uicontrol {About Plugins}, or + \uicontrol {Qt Creator} > \uicontrol {About Plugins} on Mac). \list - \li \uicontrol{Vendor name} is a short one-word name of the company - or organization that created the plugin. This is also used for - the path name where the plugin will be deployed to. - \li \uicontrol{Copyright} is a one-line, short copyright string. - \li \uicontrol{License} is a multi-line license text (but shouldn't be pages over pages long, - since the interface doesn't allow nice reading of long texts). - \li \uicontrol{Description} is a relatively short, but - possibly multi-line description of what the plugin does. - \li \uicontrol{URL} is a website where the user can find more - information about the plugin and/or organization providing it. + \li \uicontrol {Vendor name} is a short one-word name of the + company or organization that created the plugin. This is + also used for the path name where the plugin will be + deployed to. + + \li \uicontrol Copyright is a one-line, short copyright string. + + \li \uicontrol License is a multi-line license text (but + shouldn't be pages over pages long, since the interface + doesn't allow nice reading of long texts). + + \li \uicontrol{Description} is a relatively short, but possibly + multi-line description of what the plugin does. + + \li \uicontrol URL is a website where the user can find more + information about the plugin and/or organization providing + it. \endlist - \li Set the \uicontrol{Qt Creator sources} and \uicontrol{Qt Creator build} fields to - the source and build directory of the \QC - instance you want to use to test your plugin with, respectively. - If you don't do that correctly you will get compile errors for your - plugin, and your plugin might not show up in \QC at all. + \li Set the \uicontrol {Qt Creator sources} and + \uicontrol{Qt Creator build} fields to the source and build + directory of the \QC instance you want to use to test your plugin + with, respectively. If you don't do that correctly you will get + compile errors for your plugin, and your plugin might not show up in + \QC at all. - \li In the \uicontrol{Deploy into} list, select \uicontrol{Qt Creator build}. This sets - your .pro file up to deploy your plugin directly into your \QC build's - plugin directory (requires you to have write permissions there). - The other option, \uicontrol{Local user settings}, sets your .pro file up to - deploy your plugin into \QC's user plugin path - (for example \c{~/.config/QtProject/qtcreator/plugins} on Unix systems). - We choose \uicontrol{Qt Creator build} because we use a self-compiled + \li In the \uicontrol {Deploy into} list, select + \uicontrol {Qt Creator build}. This sets your \c {.pro} file up to + deploy your plugin directly into your \QC build's plugin directory + (requires you to have write permissions there). The other option, + \uicontrol {Local user settings}, sets your \c {.pro} file up to + deploy your plugin into \QC's user plugin path (for example + \c {~/.config/QtProject/qtcreator/plugins} on Unix systems). We + choose \uicontrol {Qt Creator build} because we use a self-compiled \QC, and want the plugin to be only loaded by that \QC - instance. - Continue to the next page. + instance. Continue to the next page. - The \uicontrol{Project Management} dialog opens. + The \uicontrol {Project Management} dialog opens. \image firstplugin-summary.png "Summary of Created Files" @@ -121,65 +130,74 @@ \section1 Building and Running the Plugin - If you passed the correct \QC source and build paths in the project - wizard, your plugin should just build fine when pressing the build button. - When you try to run your project, \QC will ask you for the executable to run and - you are presented the following dialog: + If you passed the correct \QC source and build paths in the project wizard, + your plugin should just build fine when pressing the build button. When you + try to run your project, \QC will ask you for the executable to run and you + are presented the following dialog: \image firstplugin-runsettings.png "Specify the Executable to Run" - Select the path to the \QC executable from the build that you specified - in the \uicontrol{Qt Creator build} setting in the project wizard and click \uicontrol OK. - \QC starts up, and you can verify that your plugin successfully loaded - by looking for a menu entry \uicontrol{Tools > Example} and by looking for - the plugin in the \uicontrol{About Plugins} dialog. + Select the path to the \QC executable from the build that you specified in + the \uicontrol {Qt Creator build} setting in the project wizard and click + \uicontrol OK. \QC starts up, and you can verify that your plugin + successfully loaded by looking for a menu entry \uicontrol Tools > + \uicontrol Example and by looking for the plugin in the + \uicontrol {About Plugins} dialog. \image firstplugin-menuitem.png "Menu Registered by the Plugin" \section1 File Structure - The plugin wizard creates a set of basic files that a plugin needs or should have. - We will have a look at some of them in detail in the following sections, here is a short - overview: + The plugin wizard creates a set of basic files that a plugin needs or should + have. We will have a look at some of them in detail in the following + sections, here is a short overview: \table \header \li File + \li Role \row - \li \c{Example.json.in} - \li Plugin meta data template. QMake creates an \c{Example.json} + \li \c {Example.json.in} + + \li Plugin meta data template. QMake creates an \c {Example.json} from this file, which is compiled into the plugin as meta data. The meta data is read by \QC to find out about the plugin. \row - \li \c{example.pro} + \li \c {example.pro} + \li Project file, used by QMake to generate a Makefile that then is used to build the plugin. \row - \li \c{example_global.h} + \li \c {example_global.h} + \li Contains macro definitions that are useful when this plugin should export symbols to other plugins. \row - \li \c{exampleconstants.h} + \li \c {exampleconstants.h} + \li Header defining constants used by the plugin code. \row \li \c{exampleplugin.h/.cpp} + \li C++ header and source files that define the plugin class that will be - instanciated and run by \QC's plugin manager. + instanciated and run by \QC's plugin manager. \endtable \section1 qmake Project - The qmake project file \c{example.pro} defines how your plugin should be compiled. - \QC plugins need to have a specific setup there, in addition to telling qmake - which files need to be compiled (or handled by \c moc or \c uic). - Let us have a look at what the project wizard generated for you in detail. + The qmake project file \c {example.pro} defines how your plugin should be + compiled. \QC plugins need to have a specific setup there, in addition to + telling qmake which files need to be compiled (or handled by \c moc or + \c uic). Let us have a look at what the project wizard generated for you in + detail. \snippet exampleplugin/example.pro 1 - The first section of the .pro file lets the compiler pass an \c EXAMPLE_LIBRARY define to the - compiled code, which is used in the \c{example_global.h} header, but is not really of interest - for now. You should not need to change that section of the .pro file. + The first section of the .pro file lets the compiler pass an + \c EXAMPLE_LIBRARY define to the compiled code, which is used in the + \c {example_global.h} header, but is not really of interest for now. You + should not need to change that section of the \c {.pro} file. \snippet exampleplugin/example.pro 2 @@ -189,106 +207,111 @@ \snippet exampleplugin/example.pro 3 - To compile and deploy your plugin, the project needs access to the \QC sources and - build. This section contains the logic that looks for the information about - the location of the sources and build in the \c{QTC_SOURCE} and \c{QTC_BUILD} - environment variables. If these are not defined, it uses the defaults you - set in the project wizard. + To compile and deploy your plugin, the project needs access to the \QC + sources and build. This section contains the logic that looks for the + information about the location of the sources and build in the + \c {QTC_SOURCE} and \c {QTC_BUILD} environment variables. If these are not + defined, it uses the defaults you set in the project wizard. So, if someone else opens your plugin project on their machine, they do not - need to edit the .pro file, but instead they should set the \c{QTC_SOURCE} and - \c{QTC_BUILD} environment variables correctly for the plugin's build environment. + need to edit the .pro file, but instead they should set the \c {QTC_SOURCE} + and \c {QTC_BUILD} environment variables correctly for the plugin's build + environment. - You should not need to change this section, except perhaps to adapt the defaults. + You should not need to change this section, except perhaps to adapt the + defaults. \snippet exampleplugin/example.pro 4 - \QC plugins can either be installed into the \QC installation's plugin directory - (requires write access there), or to a user specific plugin directory. - The \c USE_USER_DESTDIR switch in the .pro file defines which method is used for building - the plugin (which is independent from what you can later use for distributing your - plugin to other users). + \QC plugins can either be installed into the \QC installation's plugin + directory (requires write access there), or to a user specific plugin + directory. The \c USE_USER_DESTDIR switch in the .pro file defines which + method is used for building the plugin (which is independent from what you + can later use for distributing your plugin to other users). \snippet exampleplugin/example.pro 5 - This section defines the name and dependencies of your plugin. - The \c{QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name of the - dynamic library that is created for it. The \c{QTC_LIB_DEPENDS} variable is a list of - library names of the \QC utility libraries that your plugin depends on. - Typical values would be \c{aggregation}, \c{extensionsystem} and \c{utils}. - The \c{QTC_PLUGIN_DEPENDS} variable defines the \QC plugins that your plugin depends on. - Almost all \QC plugins will depend on the \c{coreplugin}. The \c{QTC_PLUGIN_RECOMMENDS} - variable defines the \QC plugins that your plugin optionally depends on. For more information, - see \l{Optional Dependencies}. + This section defines the name and dependencies of your plugin. The + \c {QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name + of the dynamic library that is created for it. The \c {QTC_LIB_DEPENDS} + variable is a list of library names of the \QC utility libraries that your + plugin depends on. Typical values would be \c aggregation, + \c extensionsystem and \c utils. The \c {QTC_PLUGIN_DEPENDS} variable + defines the \QC plugins that your plugin depends on. Almost all \QC plugins + will depend on the \c coreplugin. The \c {QTC_PLUGIN_RECOMMENDS} variable + defines the \QC plugins that your plugin optionally depends on. For more + information, see \l{Optional Dependencies}. \snippet exampleplugin/example.pro 6 - The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin that is suitable - for use in \QC, by using the information you gave above. + The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin + that is suitable for use in \QC, by using the information you gave above. - For more information about qmake, and writing .pro files in general, + For more information about qmake, and writing \c {.pro} files in general, see the \l{qmake Manual}. \section1 Plugin Meta Data Template - The .json file is a JSON file that contains information that is needed by - the plugin manager to find your plugin and resolve its dependencies before actually - loading your plugin's library file. We will only have a short look at it here. - For more information, see \l{Plugin Meta Data}. + The \c {.json} file is a JSON file that contains information that is needed + by the plugin manager to find your plugin and resolve its dependencies + before actually loading your plugin's library file. We will only have a + short look at it here. For more information, see \l{Plugin Meta Data}. The wizard doesn't actually create a .json file directly, but instead a - .json.in file. qmake uses this to generate the actual plugin .json meta data - file, replacing variables like \c{QTCREATOR_VERSION} with their actual values. - Therefore you need to escape all backslashes and quotes in the .json.in file - (i.e. you need to write \c{\\} to get a backslash and \c{\"} to get a quote - in the generated plugin JSON meta data). + \c {.json.in} file. qmake uses this to generate the actual plugin .json + meta data file, replacing variables like \c {QTCREATOR_VERSION} with their + actual values. Therefore you need to escape all backslashes and quotes in + the \c {.json.in} file (i.e. you need to write \c {\} to get a backslash + and \c{\"} to get a quote in the generated plugin JSON meta data). \snippet exampleplugin/Example.json.in 1 - The first items in the meta data that is created by the wizard - define the name of your plugin, its version, and with what version of this plugin - the current version is binary compatible with. + The first items in the meta data that is created by the wizard define the + name of your plugin, its version, and with what version of this plugin the + current version is binary compatible with. \snippet exampleplugin/Example.json.in 2 - After that you'll find the information about the plugin - that you gave in the project wizard. + After that you'll find the information about the plugin that you gave in the + project wizard. \snippet exampleplugin/Example.json.in 3 - The \c{$$dependencyList} variable is automatically replaced by the dependency information - in \c{QTC_PLUGIN_DEPENDS} and \c{QTC_PLUGIN_RECOMMENDS} from your plugin's .pro file. + The \c {$$dependencyList} variable is automatically replaced by the + dependency information in \c {QTC_PLUGIN_DEPENDS} and + \c {QTC_PLUGIN_RECOMMENDS} from your plugin's \c {.pro} file. \section1 Plugin Class - The files \c{exampleplugin.h} and \c{exampleplugin.cpp} define the plugin + The files \c {exampleplugin.h} and \c {exampleplugin.cpp} define the plugin implementation of your little plugin. We'll concentrate on some highlights here, and give pointers to more detailed information for the various parts. \section2 Header File - The header file \c{exampleplugin.h} defines the interface of the plugin class. + The header file \c {exampleplugin.h} defines the interface of the plugin + class. \snippet exampleplugin/exampleplugin.h namespaces - The plugin is defined in a \c{Example::Internal} namespace, which conforms to - the coding rules for \l{coding-rules-namespacing}{namespacing} + The plugin is defined in a \c {Example::Internal} namespace, which conforms + to the coding rules for \l{coding-rules-namespacing}{namespacing} in \QC sources. \snippet exampleplugin/exampleplugin.h base class All \QC plugins must be derived from \l{ExtensionSystem::IPlugin} and - are QObjects. The \c{Q_PLUGIN_METADATA} macro is necessary to create a valid Qt plugin. - The \c IID given in the macro must be \c{org.qt-project.Qt.QtCreatorPlugin}, to identify it - as a \QC plugin, and \c FILE must point to the plugin's meta data file as described - in \l{Plugin Meta Data}. + are QObjects. The \c {Q_PLUGIN_METADATA} macro is necessary to create a + valid Qt plugin. The \c IID given in the macro must be + \c {org.qt-project.Qt.QtCreatorPlugin}, to identify it as a \QC plugin, and + \c FILE must point to the plugin's meta data file as described in + \l{Plugin Meta Data}. \snippet exampleplugin/exampleplugin.h plugin functions The base class defines basic functions that are called during the life cycle - of a plugin, which are here implemented for your new plugin. - These functions and their roles are described in detail in - \l{The Plugin Life Cycle}. + of a plugin, which are here implemented for your new plugin. These functions + and their roles are described in detail in \l{The Plugin Life Cycle}. \snippet exampleplugin/exampleplugin.h slot @@ -297,34 +320,36 @@ \section2 Source File - The source file contains the actual implementation of the plugin, which registers - a new menu and menu item, and opens a message box when that item is triggered. + The source file contains the actual implementation of the plugin, which + registers a new menu and menu item, and opens a message box when that item + is triggered. - All the necessary header files from the plugin code itself, - from the Core plugin, and from Qt are included in the beginning of the file. - The setup of the menu and menu item - is done in the plugin's \c{initialize} function, which is the first thing called - after the plugin constructor. In that function, the plugin can be sure that the basic - setup of plugin's that it depends on has been done, for example the Core plugin's - \c{ActionManager} instance has been created. + All the necessary header files from the plugin code itself, from the \c + Core plugin, and from Qt are included in the beginning of the file. The + setup of the menu and menu item is done in the plugin's \c initialize + function, which is the first thing called after the plugin constructor. In + that function, the plugin can be sure that the basic setup of plugin's that + it depends on has been done, for example the Core plugin's \c ActionManager + instance has been created. For more information about implementing the plugin interface, see the \l{ExtensionSystem::IPlugin} API documentation and \l{Plugin Life Cycle}. \snippet exampleplugin/exampleplugin.cpp add action - This part of the code creates a new \c{QAction}, registers it as a new - \c{Command} in the action manager, and connects it to the plugin's slot. - The action manager provides a central place where the user can assign and - change keyboard shortcuts, and manages cases where for example a menu item should be - directed to different plugins under different circumstances, as well as a few - other things. This is described in more detail in \l{Menus and Menu Items}. + This part of the code creates a new \c QAction, registers it as a new + \c Command in the action manager, and connects it to the plugin's slot. The + action manager provides a central place where the user can assign and change + keyboard shortcuts, and manages cases where for example a menu item should + be directed to different plugins under different circumstances, as well as a + few other things. This is described in more detail in + \l{Menus and Menu Items}. \snippet exampleplugin/exampleplugin.cpp add menu - Here a new menu item is created, the created command added to it, and the menu - added to the \uicontrol{Tools} menu in the menu bar. Again, this is covered in more - detail in \l{Menus and Menu Items}. + Here a new menu item is created, the created command added to it, and the + menu added to the \uicontrol Tools menu in the menu bar. Again, this is + covered in more detail in \l{Menus and Menu Items}. \snippet exampleplugin/exampleplugin.cpp slot implementation diff --git a/doc/api/getting-and-building.qdoc b/doc/api/getting-and-building.qdoc index fe459c1240e..0bbf0291b0b 100644 --- a/doc/api/getting-and-building.qdoc +++ b/doc/api/getting-and-building.qdoc @@ -26,33 +26,38 @@ \endcode There are several reasons why you might want to do your own build of \QC, - like using the most current development version and being able to tweak - \QC at one or the other place. It is also necessary if you want to - create your own \QC plugin. + like using the most current development version and being able to tweak \QC + at one or the other place. It is also necessary if you want to create your + own \QC plugin. \section1 Getting Qt - Prebuilt \QC packages usually use the latest stable release of Qt. - You can see the exact minimum requirement at the top of \QC's qtcreator.pro. + Prebuilt \QC packages usually use the latest stable release of Qt. You can + see the exact minimum requirement at the top of \QC's \c {qtcreator.pro}. (You can find the current version in our source repository here: \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/qtcreator.pro#n4}.) - You can get prebuilt Qt packages from \l{https://download.qt.io}{Qt Downloads}. - If you want to use Qt as provided by your Linux distribution, you need to make sure that all - Qt development packages and private header packages are also installed. + You can get prebuilt Qt packages from + \l{https://download.qt.io}{Qt Downloads}. If you want to use Qt as provided + by your Linux distribution, you need to make sure that all Qt development + packages and private header packages are also installed. \section1 Getting and Building \QC - You can get the \QC sources for a specific version either by using one of the - released source bundles, or from the Git repository - \l{https://code.qt.io/cgit/qt-creator/qt-creator.git}. If you intend to contribute to \QC - itself, you should use the repository from our Gerrit review tool as described - in: \l{https://wiki.qt.io/Setting_up_Gerrit}{Setting up Gerrit}. + You can get the \QC sources for a specific version either by using one of + the released source bundles, or from the Git repository + \l{https://code.qt.io/cgit/qt-creator/qt-creator.git}. If you intend to + contribute to \QC itself, you should use the repository from our Gerrit + review tool as described in: + \l{https://wiki.qt.io/Setting_up_Gerrit}{Setting up Gerrit}. We strongly encourage you to do out-of-source builds of \QC (also called shadow-builds). - After you put the \QC sources somewhere (lets call the path \c{}) + + After you put the \QC sources somewhere (lets call the path + \c {}) you build it on Linux and Mac with + \code cd /.. mkdir qtcreator-build @@ -60,5 +65,6 @@ /bin/qmake -r make \endcode + or the corresponding commands on Windows systems. */ diff --git a/doc/api/qtcreator-api.qdoc b/doc/api/qtcreator-api.qdoc index 4ade5eb0e5a..2b37b458ac5 100644 --- a/doc/api/qtcreator-api.qdoc +++ b/doc/api/qtcreator-api.qdoc @@ -21,12 +21,11 @@ \title Qt Creator API Reference - The core of Qt Creator is - basically only a \l{ExtensionSystem}{plugin loader}. - All functionality is implemented in plugins. The basis of Qt Creator is - implemented in the \l{Core} {Core} Plugin. The plugin manager provides - simple means for plugin cooperation that allow plugins to provide - hooks for other plugin's extensions. + The core of \QC is basically only a \l{ExtensionSystem}{plugin loader}. All + functionality is implemented in plugins. The basis of \QC is implemented in + the \l{Core}{Core} Plugin. The plugin manager provides simple means for + plugin cooperation that allow plugins to provide hooks for other plugin's + extensions. \section1 Libraries @@ -35,88 +34,90 @@ There are a few core libraries used by many parts of Qt Creator. \table - \header - \li Library Name - \li Description + \header + \li Library Name + \li Description - \row - \li \l{Aggregation} - \li Adds functionality for "glueing" QObjects of different - types together, so you can "cast" between them. + \row + \li \l{Aggregation} + \li Adds functionality for "glueing" QObjects of different types + together, so you can "cast" between them. - \row - \li \l{ExtensionSystem} - \li Implements the plugin loader framework. Provides a base class for plugins and - basic mechanisms for plugin interaction like an object pool. + \row + \li \l{ExtensionSystem} + \li Implements the plugin loader framework. Provides a base class + for plugins and basic mechanisms for plugin interaction like an + object pool. - \row - \li \l{Utils} - \li General utility library. + \row + \li \l{Utils} + \li General utility library. - \row - \li \l{QmlJS} - \li QML and JavaScript language support library. + \row + \li \l{QmlJS} + \li QML and JavaScript language support library. \endtable \section2 Additional libraries \table - \header - \li Library Name - \li Description - - \row - \li \l{qtcreatorcdbext} - \li Windows CDB debugger extension - + \header + \li Library Name + \li Description + \row + \li \l{qtcreatorcdbext} + \li Windows CDB debugger extension \endtable \section1 Plugins - As already mentioned, Qt Creator is basically only a plugin loader framework + As already mentioned, \QC is basically only a plugin loader framework which gets its IDE functionality through plugins. The most important plugin - is the Core plugin which provides all the basic functionality needed + is the \c Core plugin which provides all the basic functionality needed later to integrate e.g. editors or mode windows. \table - \header - \li Plugin Name - \li Description + \header + \li Plugin Name + \li Description - \row - \li \l{Core} - \li The core plugin. Provides the main window and managers for editors, - actions, mode windows and files, just to mention the most important ones. + \row + \li \l{Core} + \li The core plugin. Provides the main window and managers for + editors, actions, mode windows and files, just to mention the + most important ones. - \row - \li \l{ProjectExplorer} - \li The project explorer plugin. Provides base classes for project handling. + \row + \li \l{ProjectExplorer} + \li The project explorer plugin. Provides base classes for project + handling. - \row - \li \l{Find} - \li Support for searching text in arbitrary widgets, and arbitrary other things. + \row + \li \l{Find} + \li Support for searching text in arbitrary widgets, and arbitrary + other things. - \row - \li \l{Locator} - \li Hooks for providing content for Locator. + \row + \li \l{Locator} + \li Hooks for providing content for Locator. - \row - \li \l{Debugger} - \li Debugging functionality. + \row + \li \l{Debugger} + \li Debugging functionality. - \row - \li \l{VcsBase} - \li Base classes for version control support. - - \row - \li \l{TextEditor} - \li This is where everything starts if you want to create a text editor. Besides - the base editor itself, this plugin contains APIs for supporting functionality - like \l{Snippets}{snippets}, highlighting, \l{CodeAssist}{code assist}, indentation - and style, and others. + \row + \li \l{VcsBase} + \li Base classes for version control support. + \row + \li \l{TextEditor} + \li This is where everything starts if you want to create a text + editor. Besides the base editor itself, this plugin contains + APIs for supporting functionality like \l{Snippets}{snippets}, + highlighting, \l{CodeAssist}{code assist}, indentation and + style, and others. \endtable */ @@ -154,95 +155,101 @@ \title Common Extension Tasks This section summarizes the API functions that you can use to add UI - components to Qt Creator. + components to \QC. \table - \header - \li Task - \li Details - \li API + \header + \li Task + \li Details + \li API - \row - \li Add a menu or menu item. - \li You can extend existing menus or create new ones. - \li \l{Core::ActionManager}, \l{Core::Command} + \row + \li Add a menu or menu item. + \li You can extend existing menus or create new ones. + \li \l{Core::ActionManager}, \l{Core::Command} - \row - \li Add a configurable keyboard shortcut. - \li Registering shortcuts makes it possible for users to configure them in - the common shortcut settings dialog. - \li \l{Core::ActionManager}, \l{Core::Command} + \row + \li Add a configurable keyboard shortcut. + \li Registering shortcuts makes it possible for users to configure + them in the common shortcut settings dialog. + \li \l{Core::ActionManager}, \l{Core::Command} - \row - \li Add a mode. - \li Modes correspond to complete screens of controls, specialized for a task. - \li \l{Core::IMode} + \row + \li Add a mode. + \li Modes correspond to complete screens of controls, specialized + for a task. + \li \l{Core::IMode} - \row - \li Add a new editor type. - \li Such as an editor for XML files. - \li \l{Core::IEditorFactory}, \l{Core::IEditor}, \l{Core::IDocument} + \row + \li Add a new editor type. + \li Such as an editor for XML files. + \li \l{Core::IEditorFactory}, \l{Core::IEditor}, \l{Core::IDocument} - \row - \li Add a new wizard. - \li You can extend the wizards in File > New File or Project with your own - file and project templates. - \li \l{Core::IWizard}, \l{Core::StandardFileWizard}, - \l{Core::BaseFileWizard}, \l{Core::BaseFileWizardParameters} + \row + \li Add a new wizard. + \li You can extend the wizards in File > New File or Project with + your own file and project templates. + \li \l{Core::IWizard}, \l{Core::StandardFileWizard}, + \l{Core::BaseFileWizard}, \l{Core::BaseFileWizardParameters} - \row - \li Add support for a new version control system. - \li Version control systems integrated in QtCreator are Bazaar, CVS, Git, - Mecurial, Perforce, and Subversion. - \li \l{Core::IVersionControl} + \row + \li Add support for a new version control system. + \li Version control systems integrated in \QC are Bazaar, CVS, Git, + Mecurial, Perforce, and Subversion. + \li \l{Core::IVersionControl} - \row - \li Add a view to the navigation sidebar. - \li The one which shows the project tree, filesystem, open documents or bookmarks. - \li \l{Core::INavigationWidgetFactory} + \row + \li Add a view to the navigation sidebar. + \li The one which shows the project tree, filesystem, open documents + or bookmarks. + \li \l{Core::INavigationWidgetFactory} - \row - \li Add an options page to the \uicontrol Options dialog. - \li Add a new page to existing or new category in Tools > Options. - \li \l{Core::IOptionsPage} + \row + \li Add an options page to the \uicontrol Options dialog. + \li Add a new page to existing or new category in + \uicontrol Tools > \uicontrol Options. + \li \l{Core::IOptionsPage} - \row - \li Add a find filter to the \uicontrol Find dialog. - \li Implement any kind of search term based search. - \li \l{Find::IFindFilter}, \l{Core::SearchResultWindow} + \row + \li Add a find filter to the \uicontrol Find dialog. + \li Implement any kind of search term based search. + \li \l{Find::IFindFilter}, \l{Core::SearchResultWindow} - \row - \li Add support for the find tool bar to a widget. - \li The widget that has focus is asked whether it supports text search. You can - add support for widgets under your control. - \li \l{Core::IFindSupport}, \l{Find::BaseTextFind} + \row + \li Add support for the find tool bar to a widget. + \li The widget that has focus is asked whether it supports text + search. You can add support for widgets under your control. + \li \l{Core::IFindSupport}, \l{Find::BaseTextFind} - \row - \li Add a completely new project type. - \li - \li + \row + \li Add a completely new project type. + \li + \li - \row - \li Add a new type of build step. - \li - \li + \row + \li Add a new type of build step. + \li + \li - \row - \li Add a new filter to the locator. - \li For a text typed in by the user you provide a list of things to show in the popup. - When the user selects an entry you are requested to do whatever you want. - \li \l{Core::ILocatorFilter}, \l{Core::LocatorFilterEntry}, \l{Locator::BaseFileFilter} + \row + \li Add a new filter to the locator. + \li For a text typed in by the user you provide a list of things to + show in the popup. When the user selects an entry you are + requested to do whatever you want. + \li \l{Core::ILocatorFilter}, \l{Core::LocatorFilterEntry}, + \l{Locator::BaseFileFilter} - \row - \li Show a progress indicator for a concurrently running task. - \li You can show a progress indicator for your tasks in the left hand tool bar, - and also in the application icon (on platforms that support it). - \li \l{Core::ProgressManager}, \l{Core::FutureProgress} + \row + \li Show a progress indicator for a concurrently running task. + \li You can show a progress indicator for your tasks in the left + hand tool bar, and also in the application icon (on platforms + that support it). + \li \l{Core::ProgressManager}, \l{Core::FutureProgress} - \row - \li - \li - \li + \row + \li + \li + \li \endtable */ diff --git a/doc/api/qtcreator-dev.qdoc b/doc/api/qtcreator-dev.qdoc index 094cc3915ad..efa6f46f3b6 100644 --- a/doc/api/qtcreator-dev.qdoc +++ b/doc/api/qtcreator-dev.qdoc @@ -20,207 +20,206 @@ \page extending-index.html \title Extending Qt Creator Manual - Qt Creator is a cross-platform integrated development environment (IDE) - tailored to the needs of Qt developers. + \QC is a cross-platform integrated development environment (IDE) tailored to + the needs of Qt developers. - Qt Creator is extensible in various ways. For example, Qt Creator - architecture is based on a plugin loader, which means that all - functionality beyond plugin - loading is implemented in plugins. However, you can extend and tweak - many parts of Qt Creator without the need to resort to coding in C++ and - implementing such a plugin. + \QC is extensible in various ways. For example, \QC architecture is based on + a plugin loader, which means that all functionality beyond plugin loading + is implemented in plugins. However, you can extend and tweak many parts of + \QC without the need to resort to coding in C++ and implementing such a + plugin. - This document gives you an overview of the various ways in which - you can extend Qt Creator, - depending on what you want to achieve, and points you to the relevant - documentation. + This document gives you an overview of the various ways in which you can + extend \QC, depending on what you want to achieve, and points you to the + relevant documentation. \section1 Generating Domain Specific Code and Templates If you regularly need to write the same code, be it little code snippets, - whole files or classes spread over multiple files, or complete projects, - you can create code snippets, templates, and wizards for that purpose. + whole files or classes spread over multiple files, or complete projects, you + can create code snippets, templates, and wizards for that purpose. \section2 Snippets - Typically, snippets consist of a few lines of code (although they - can also be plain text) that you regularly - want to insert into a bigger body of code, but do not want to type each - time. For example, \c while and \c for loops, \c if-else and \c try-catch - constructs, and class skeletons. Snippets are triggered in the same way as - normal code completion (see \l{Code Assist}{Providing Code Assist}). - Qt Creator contains a set of preconfigured snippets groups - to which you can add your own snippets. + Typically, snippets consist of a few lines of code (although they can also + be plain text) that you regularly want to insert into a bigger body of code, + but do not want to type each time. For example, \c while and \c for loops, + \c if-else and \c try-catch constructs, and class skeletons. Snippets are + triggered in the same way as normal code completion (see + \l{Code Assist}{Providing Code Assist}). + \QC contains a set of preconfigured snippets groups to which you can add + your own snippets. \list - \li \l{http://doc.qt.io/qtcreator/creator-completing-code.html#editing-code-snippets} - {Snippets User Interface} - \li \l{Snippets} {Adding Snippets Groups} + \li \l{http://doc.qt.io/qtcreator/creator-completing-code.html#editing-code-snippets} + {Snippets User Interface} + \li \l{Snippets}{Adding Snippets Groups} \endlist - \section2 File, Class and Project Templates + \section2 File and Project Templates - You can extend the wizards in \uicontrol {File > New File or Project} with your - own - file and project templates by writing XML definition files for them. + You can extend the wizards in \uicontrol File > + \uicontrol {New File or Project} with your own file and project templates by + writing JSON definition files for them. \list - \li \l{http://doc.qt.io/qtcreator/creator-project-wizards.html} - {Adding New Custom Wizards} - \li \l{User Interface Text Guidelines} + \li \l{http://doc.qt.io/qtcreator/creator-project-wizards.html} + {Adding New Custom Wizards} + \li \l{User Interface Text Guidelines} \endlist \section2 Custom Wizards - If the above methods for code snippets and templates are not sufficient - for your use case, you can create a custom Qt Creator plugin. - While this gives you complete control over the wizard, it - also requires you to write most of the UI and the logic yourself. + If the above methods for code snippets and templates are not sufficient for + your use case, you can create a custom \QC plugin. While this gives you + complete control over the wizard, it also requires you to write most of the + UI and the logic yourself. + \list - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Creating Wizards in Code} - \li \l{User Interface Text Guidelines} + \li \l{Creating Plugins} + \li \l{Qt Creator Coding Rules} + \li \l{Creating Wizards in Code} + \li \l{User Interface Text Guidelines} \endlist \section1 Supporting Additional File Types - If you have files with extensions or MIME types that Qt Creator does not - handle by default, you can edit the MIME type definitions, add highlight - definition files, and create your own text editors. + If you have files with extensions or MIME types that \QC does not handle by + default, you can edit the MIME type definitions, add highlight definition + files, and create your own text editors. \section2 MIME Types - You might find that Qt Creator could handle a particular file of yours if - it knew about the type of its contents. For example, C++ header or source - files with file extensions that are not known to Qt Creator. You can adapt - the MIME type definitions in Qt Creator to your specific setup, - by adding or removing file extensions and specifying magic headers. + You might find that \QC could handle a particular file of yours if it knew + about the type of its contents. For example, C++ header or source files + with file extensions that are not known to \QC. You can adapt the MIME type + definitions in \QC to your specific setup, by adding or removing file + extensions and specifying magic headers. + \list - \li \l{http://doc.qt.io/qtcreator/creator-mime-types.html} - {Editing MIME Types} - \li \l{http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html} - {MIME Type Specification Files} + \li \l{http://doc.qt.io/qtcreator/creator-mime-types.html} + {Editing MIME Types} + \li \l{http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html} + {MIME Type Specification Files} \endlist \section2 Text Highlighting and Indentation - For text files, Qt Creator provides an easy way to add highlighting and - indentation for file types that are not known to it by default. - Generic highlighting is based on highlight definition files that are - provided by the Kate Editor. You can download highlight definition files - for use with Qt Creator and create your own definition files. + For text files, \QC provides an easy way to add highlighting and indentation + for file types that are not known to it by default. Generic highlighting is + based on highlight definition files that are provided by the Kate Editor. + You can download highlight definition files for use with \QC and create + your own definition files. + \list - \li \l{http://doc.qt.io/qtcreator/creator-editor-options.html#generic-highlighting} - {Generic Highlighting} - \li \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} - {Writing a Syntax Highlighting File} + \li \l{http://doc.qt.io/qtcreator/creator-editor-options.html#generic-highlighting} + {Generic Highlighting} + \li \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} + {Writing a Syntax Highlighting File} \endlist \section2 Custom Text Editors If you need more advanced features than the MIME type and highlighting features described above, such as custom text completion or features that - rely on semantic analysis, you can extend Qt Creator with a text editor of - your own. Qt Creator provides a special API for text editors that gives you - a basis to build on, taking away some of the pain of implementing - a text editor from the ground up. + rely on semantic analysis, you can extend \QC with a text editor of your + own. \QC provides a special API for text editors that gives you a basis to + build on, taking away some of the pain of implementing a text editor from + the ground up. + \list - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Text Editors} - \li \l{CodeAssist} {Providing Code Assist} + \li \l{Creating Plugins} + \li \l{Qt Creator Coding Rules} + \li \l{Text Editors} + \li \l{CodeAssist} {Providing Code Assist} \endlist \section2 Other Custom Editors - You can also add a completely custom editor to gain complete - control over its appearance and behavior. + You can also add a completely custom editor to gain complete control over + its appearance and behavior. + \list - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Editors} + \li \l{Creating Plugins} + \li \l{Qt Creator Coding Rules} + \li \l{Editors} \endlist \section1 Running External Tools Most software projects and development processes require various external tools. Several external tools, such as popular version control systems and - build tool chains are integrated into Qt Creator. However, it is impossible - for a single tool to cover all the use cases, and therefore you can - integrate additional tools to Qt Creator. + build tool chains are integrated into \QC. However, it is impossible for a + single tool to cover all the use cases, and therefore you can integrate + additional tools to \QC. \section2 Simple External Tools - In Qt Creator, you can specify tools that you can then run from a - menu or by using a keyboard shortcut that you assign. This allows you to - accomplish several things, with some limitations. You specify a command - to run, arguments and input for running it, and how to handle the output. - To specify the values, you can use a set of internal Qt Creator variables, - such as the file name of - the current document or project, or the currently selected text in - a text editor. If you find variables missing, please do not hesitate - to fill a feature suggestion. - The tool descriptions are saved as XML files that you can share. + In \QC, you can specify tools that you can then run from a menu or by using + a keyboard shortcut that you assign. This allows you to accomplish several + things, with some limitations. You specify a command to run, arguments and + input for running it, and how to handle the output. To specify the values, + you can use a set of internal \QC variables, such as the file name of the + current document or project, or the currently selected text in a text + editor. If you find variables missing, please do not hesitate to fill a + feature suggestion. The tool descriptions are saved as XML files that you + can share. + \list - \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html} - {Using External Tools} - \li \l{External Tool Specification Files} + \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html} + {Using External Tools} + \li \l{External Tool Specification Files} \endlist \section2 Complex External Tools When you plan to integrate more complex tools, carefully consider whether there really are advantages to be gained by tightly integrating the tool - into Qt Creator over loosely integrating it by mainly - providing a means of starting the tool with fitting parameters. + into \QC over loosely integrating it by mainly providing a means of starting + the tool with fitting parameters. \section3 Loosely Integrating Tools - If no interaction is needed between Qt Creator and the - external tool, just starting an external - application with its own user interface is preferable. That way - cluttering the Qt Creator UI is avoided, and the tool will be - available with a nice interface even without using Qt Creator - at all. + If no interaction is needed between \QC and the external tool, just starting + an external application with its own user interface is preferable. That way + cluttering the \QC UI is avoided, and the tool will be available with a + nice interface even without using \QC at all. Usually, you can use the external tool specification files to start the tool. If starting the tool and handling its output require more complex - logic, you can add a menu item to Qt Creator with a plugin. - If you need a way to configure the tool in Qt Creator, you can add an - \uicontrol Options page for it. + logic, you can add a menu item to \QC with a plugin. If you need a way to + configure the tool in \QC, you can add an \uicontrol Options page for it. + \list - \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html} - {Using External Tools} - \li \l{External Tool Specification Files} - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Menus and Menu Items} - \li \l{Options Pages} + \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html}{Using External Tools} + \li \l{External Tool Specification Files} + \li \l{Creating Plugins} + \li \l{Qt Creator Coding Rules} + \li \l{Menus and Menu Items} + \li \l{Options Pages} \endlist \section3 Interacting with Tool Output - In some cases, running an external tool would not require tight - integration with Qt Creator, but investigating the output of the tool would - benefit from it. For example, some tools generate lists of issues in files - that are part of the project and some tools create output that is related - to the code. For these tools, it is useful to interactively switch between - the output and the corresponding code. + In some cases, running an external tool would not require tight integration + with \QC, but investigating the output of the tool would benefit from it. + For example, some tools generate lists of issues in files that are part of + the project and some tools create output that is related to the code. For + these tools, it is useful to interactively switch between the output and + the corresponding code. + + One way to handle that would be to let the tool create an output file, which + is then opened within \QC. You provide an editor (probably read-only) for + handling this file. For lists of issues, consider creating task list files + which are shown in the \uicontrol Issues output pane. - One way to handle that would be to let the tool create an output - file, which is then opened within Qt Creator. You provide - an editor (probably read-only) for handling this file. - For lists of issues, consider creating task list files which are shown in - the \uicontrol {Issues} output - pane. \list - \li \l{http://doc.qt.io/qtcreator/creator-task-lists.html} - {Showing Task List Files in the Issues Pane} - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Menus and Menu Items} - \li \l{Options Pages} - \li \l{Editors} + \li \l{http://doc.qt.io/qtcreator/creator-task-lists.html} + {Showing Task List Files in the Issues Pane} + \li \l{Creating Plugins} + \li \l{Qt Creator Coding Rules} + \li \l{Menus and Menu Items} + \li \l{Options Pages} + \li \l{Editors} \endlist \section1 All Topics @@ -228,26 +227,25 @@ \list \li \l{Developing Qt Creator Plugins} \list - \li \l{Creating Plugins} - \li \l{Menus and Menu Items} - \li \l{Creating Wizards in Code} - \li \l{Editors} - \li \l{Text Editors} - \li \l{Options Pages} + \li \l{Creating Plugins} + \li \l{Menus and Menu Items} + \li \l{Creating Wizards in Code} + \li \l{Editors} + \li \l{Text Editors} + \li \l{Options Pages} \endlist \li Reference \list - \li \l{http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html} - {MIME Type Specification Files} - \li \l{External Tool Specification Files} - \li \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} - {Highlight Definition Files} - \li \l{Qt Creator Variables} - \li \l{User Interface Text Guidelines} - \li \l{Writing Documentation} - \li \l{Qt Creator Coding Rules} - \li \l{Qt Creator API Reference} - \endlist - + \li \l{http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html} + {MIME Type Specification Files} + \li \l{External Tool Specification Files} + \li \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} + {Highlight Definition Files} + \li \l{Qt Creator Variables} + \li \l{User Interface Text Guidelines} + \li \l{Writing Documentation} + \li \l{Qt Creator Coding Rules} + \li \l{Qt Creator API Reference} + \endlist \endlist */ diff --git a/doc/api/qtcreator-documentation.qdoc b/doc/api/qtcreator-documentation.qdoc index 0d9fc3d3937..91374ec64ec 100644 --- a/doc/api/qtcreator-documentation.qdoc +++ b/doc/api/qtcreator-documentation.qdoc @@ -24,10 +24,10 @@ \title Writing Documentation When you add plugins or contribute new features to \QC, you probably want - other people to know about them and to be able to use them. Therefore, - you should also contribute documentation for them. Follow the guidelines in - this section to make sure that your documentation fits in well with the rest - of the \QC documentation. + other people to know about them and to be able to use them. Therefore, you + should also contribute documentation for them. Follow the guidelines in this + section to make sure that your documentation fits in well with the rest of + the \QC documentation. When you contribute a plugin, you should write documentation both for the developers who use \QC and for the ones who develop it. @@ -35,7 +35,6 @@ Write the following user documentation for addition to the \QC Manual: \list - \li Overview topic, which describes the purpose of your plugin from the viewpoint of \QC users @@ -43,58 +42,52 @@ \li Reference topics, which contain information that developers occasionally need to look up (optional) - \endlist Write the following developer documentation for addition to the Extending \QC Manual: \list - \li Overview topic, which describes the architecture and use cases for your plugin from the viewpoint of \QC developers \li API documentation, which is generated from code comments - \endlist \section1 Configuring the Documentation Project \QC documentation is written by using QDoc. For more information about using - QDoc, see the \l{http://doc.qt.io/qt-5/qdoc-index.html} - {QDoc Manual}. + QDoc, see the \l{http://doc.qt.io/qt-5/qdoc-index.html}{QDoc Manual}. - QDoc finds the new topics automatically, when you place them as .qdoc files - in the correct folder. However, to make the topics accessible to readers, - you must also add them to the table of contents and fix the next page and - previous page links to them from other topics. + QDoc finds the new topics automatically, when you place them as \c {.qdoc} + files in the correct folder. However, to make the topics accessible to + readers, you must also add them to the table of contents and fix the next + page and previous page links to them from other topics. \section2 Creating Folders and Files These instructions apply only to the \QC Manual. Add API documentation directly to the code source files. However, you can write an API overview - also as a separate .qdoc file. + also as a separate \c {.qdoc} file. Create a subfolder for your documentation in the \QC project folder in the \c {doc\src} folder. Create a separate file for each topic. The easiest way is probably to copy an existing file, save it as a new file, - and modify it. This way, you already have samples of the necessary bits - and pieces in place, such as topic start and end commands, copyright - statement, links to next and previous topics, and topic title. + and modify it. This way, you already have samples of the necessary bits and + pieces in place, such as topic start and end commands, copyright statement, + links to next and previous topics, and topic title. \section2 Integrating Topics to Documentation - You must integrate your new topics to the \QC Manual and Extending - \QC Manual by adding links to them to the table of contents and to other + You must integrate your new topics to the \QC Manual and Extending \QC + Manual by adding links to them to the table of contents and to other relevant topics. To link to the topic, you can use the topic title. For example: \code - \l{Integrating Topics to Documentation} - \endcode This does not work if topic titles are not unique. Also, if you change the @@ -105,7 +98,7 @@ When you add new topics to a document, you must also change the navigation links of the topics around them. This is very error prone when done - manually, and therefore we have a script called \c fixnavi.pl for it. For + manually, and therefore we have a script called \c {fixnavi.pl} for it. For the script to work, you must add the \c {\nextpage} and \c {\previouspage} commands to the topic, with dummy values (for example, \c {\nextpage=anything.html}). @@ -121,23 +114,20 @@ To run the script, enter the following command in the doc folder: \list - \li nmake fixnavi (on Windows) \li make fixnavi (on Linux) - \endlist \section1 Writing Text Follow the guidelines for - \l{http://wiki.qt.io/Writing_Qt_Documentation} - {writing Qt documentation}. + \l{http://wiki.qt.io/Writing_Qt_Documentation}{writing Qt documentation}. The documentation must be grammatically correct English and use the standard form of written language. Do not use dialect or slang words. Use idiomatic - language, that is, expressions that are characteristic for English. - If possible, ask a native English speaker for a review. + language, that is, expressions that are characteristic for English. If + possible, ask a native English speaker for a review. \section2 Capitalizing Headings @@ -159,11 +149,11 @@ \section2 Taking Screen Shots - \QC has the native look and feel on Windows, Linux, and OS X, and - therefore, screen shots can end up looking very different, depending on who - takes them and which system they use. To try to preserve a consistent look - and feel in the \QC Manual, observe the guidelines listed in this section - when taking screen shots. + \QC has the native look and feel on Windows, Linux, and OS X, and therefore, + screen shots can end up looking very different, depending on who takes them + and which system they use. To try to preserve a consistent look and feel in + the \QC Manual, observe the guidelines listed in this section when taking + screen shots. To make the images look similar regardless of the operating system they were taken on, you are asked to adjust their size to 75%. This makes the screen @@ -173,7 +163,6 @@ place example values also in the text. \list - \li Use the screen resolution of 1024x768 (this is available on all screens). @@ -194,7 +183,6 @@ \li Before you submit the images to the repository, optimize them to save space. - \endlist \section2 Optimizing Images @@ -210,10 +198,9 @@ it. You can use a web service, such as \l{https://tinypng.com}, or an image - optimization tool to shrink the images. For example, you - can use the Radical Image Optimization Tool (RIOT) on Windows (very - efficient) or ImageOptim on OS X (much less efficient), or some other tool - available on Linux. + optimization tool to shrink the images. For example, you can use the Radical + Image Optimization Tool (RIOT) on Windows (very efficient) or ImageOptim on + OS X (much less efficient), or some other tool available on Linux. With ImageOptim, you simply drag and drop the image files to the application. The following section describes the settings to use for RIOT. @@ -227,7 +214,6 @@ Open your images in RIOT and use the following settings for them: \list - \li Color reduction: Optimal 256 colors palette \li Reduce colors to: 256 @@ -237,7 +223,6 @@ \li Color quantization algorithm: NeuQuant neural-net (slow) \li External optimizers: OptiPNG o3 - \endlist Compare the initial and optimized images to check that image quality is @@ -264,7 +249,6 @@ qdocconf file: \list - \li \c {include ($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)} for help files \li \c {include ($QT_INSTALL_DOCS/global/qt-html-templates-online.qdocconf)} @@ -285,27 +269,25 @@ commands from the project folder (after running qmake): \list - \li nmake docs (on Windows) - \li make docs (on Linux and OS X) + \li make docs (on Linux and OS X) \endlist The \QC Manual HTML files are generated in the \c {doc/html} directory. The Extending \QC Manual files are generated in the - \c {doc/html-dev} directory. The help files (.qch) are generated in the + \c {doc/html-dev} directory. The help files (\c {.qch}) are generated in the \c {share/doc/qtcreator} directory in the \QC build directory on Windows and Linux, and in the \c {bin/Qt Creator.app/Contents/Resources/app} directory on OS X. You can view the HTML files in a browser and the help files in - the \QC \uicontrol Help mode. For more information about adding the help files to - \QC, see + the \QC \uicontrol Help mode. For more information about adding the help + files to \QC, see \l{http://doc.qt.io/qtcreator/creator-help.html#adding-external-documentation} {Adding External Documentation}. Besides \c docs, you have the following options: \list - \li html_docs - build \QC Manual in help format, but do not generate a help file @@ -324,7 +306,6 @@ \li html_docs_online - build \QC Manual in online format \li dev_html_docs_online - build Extending \QC Manual in online format - \endlist */ diff --git a/doc/api/qtcreator-ui-text.qdoc b/doc/api/qtcreator-ui-text.qdoc index ea8c34b9566..a74c1d3afde 100644 --- a/doc/api/qtcreator-ui-text.qdoc +++ b/doc/api/qtcreator-ui-text.qdoc @@ -121,14 +121,8 @@ short, canonical HTML in the source tab of the rich text editor: \c {Note: text.} - In Qt 4.7, use only the \uicontrol Source tab of the Qt Designer rich text - editor. The automatic conversion performed by the rich text editor tab - generates a lot of redundant stylesheet information and uses hard-coded - fonts that look bad on other platforms and make translation in Qt Linguist - difficult. - - Qt Designer 4.8 has a feature that simplifies the rich text (on by - default), but still, you should verify by looking at the \uicontrol Source tab. + Qt Designer has a feature that simplifies the rich text (on by default), + but still, you should verify by looking at the \uicontrol Source tab. \section2 Writing Messages @@ -278,50 +272,54 @@ \table \header - \li Features of Languages or Writing Systems - \li Impact on Implementation + \li Features of Languages or Writing Systems + + \li Impact on Implementation \row - \li Word order - \li Different languages have different word order rules. + \li Word order + + \li Different languages have different word order rules. Do not use run-time concatenation. Use complete phrases and "%1" formatting instead. For example, use: - \c{tr("Foo failed: %1").arg(message)} + \c{tr("Foo failed: %1").arg(message)} instead of \c {tr("Foo failed: ") + message} \row - \li Singular vs. plural vs. dual forms - \li Some languages do not have plural form (for example, Chinese - and Japanese), whereas some have a different form for dual. + \li Singular vs. plural vs. dual forms - Allow room for text expansion in the layout design. Some - languages need more space to indicate plurality or duality to - convey the needed information. + \li Some languages do not have plural form (for example, Chinese + and Japanese), whereas some have a different form for dual. - For example, use + Allow room for text expansion in the layout design. Some + languages need more space to indicate plurality or duality to + convey the needed information. - \c {tr("%n files found", 0, number)} + For example, use - instead of + \c {tr("%n files found", 0, number)} - \c {tr("%1 files found").arg(number)} + instead of + + \c {tr("%1 files found").arg(number)} \row - \li Gender - \li Some languages have gender (feminine, masculine, neutral), - whereas some do not (for example, Finnish) or do not use it - extensively (for example, English). + \li Gender + + \li Some languages have gender (feminine, masculine, neutral), + whereas some do not (for example, Finnish) or do not use it + extensively (for example, English). Do not reuse text strings. The same term may not work in another context due to the gender of the base word. - Articles have a grammatical gender in some languages and - sentences cannot be as easily constructed as in English. Avoid - following types of constructs: + Articles have a grammatical gender in some languages and + sentences cannot be as easily constructed as in English. Avoid + following types of constructs: - \c {tr("%1 failed").arg(someCondition ? "the operation" : "opening a file")} + \c {tr("%1 failed").arg(someCondition ? "the operation" : "opening a file")} \endtable \section1 Common Qt Creator Terms @@ -339,16 +337,22 @@ \table \header - \li UI Text - \li Usage - \li Conventions + \li UI Text + + \li Usage + + \li Conventions + \row - \li Context menu - \li Opens when users right-click on the screen. Contents depend on - the context. - \image qtcreator-context-menu.png "Context menu" - \li You can add menu items that are relevant in a particular - context. Follow the conventions for naming menu items. + \li Context menu + + \li Opens when users right-click on the screen. Contents depend on + the context. + \image qtcreator-context-menu.png "Context menu" + + \li You can add menu items that are relevant in a particular + context. Follow the conventions for naming menu items. + \row \li Dialog \li User interface element that usually contains a number of @@ -361,20 +365,26 @@ button in the \uicontrol Documentation options opens the \uicontrol {Add Documentation} dialog. \row - \li Locator - \li Allows you to browse not only files, but any items defined by - locator filters. - \image qtcreator-locator.png "Locator" - \li You can add locator filters. Check that the filter is not - already in use and give the filter a descriptive name. + \li Locator + + \li Allows you to browse not only files, but any items defined by + locator filters. + \image qtcreator-locator.png "Locator" + + \li You can add locator filters. Check that the filter is not + already in use and give the filter a descriptive name. + \row - \li Menu - \li Contains menu items that represent commands or options and that - are logically grouped and displayed. A menu can also contain - submenus. - \image qtcreator-menu.png "Menu" - \li You can create new menus. Use short, but descriptive names that - are consistent with existing menu names. Use unambigious names. + \li Menu + + \li Contains menu items that represent commands or options and that + are logically grouped and displayed. A menu can also contain + submenus. + \image qtcreator-menu.png "Menu" + + \li You can create new menus. Use short, but descriptive names that + are consistent with existing menu names. Use unambigious names. + \row \li Menu item \li Represents a command or an option for users to choose. diff --git a/doc/config/qtcreator-project.qdocconf b/doc/config/qtcreator-project.qdocconf index 598bd327358..7b1976f0c64 100644 --- a/doc/config/qtcreator-project.qdocconf +++ b/doc/config/qtcreator-project.qdocconf @@ -7,6 +7,7 @@ sourcedirs = $SRCDIR/src imagedirs = $SRCDIR/images $SRCDIR/templates/images outputdir = $OUTDIR exampledirs = $SRCDIR/examples +examples.fileextensions += *.qml *.svg HTML.extraimages = images/commercial.png qhp.QtCreator.extraFiles = images/commercial.png diff --git a/doc/examples/accelbubble/Bluebubble.svg b/doc/examples/accelbubble/Bluebubble.svg new file mode 100644 index 00000000000..d9c406c478a --- /dev/null +++ b/doc/examples/accelbubble/Bluebubble.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/doc/examples/accelbubble/accelbubble.pro b/doc/examples/accelbubble/accelbubble.pro new file mode 100644 index 00000000000..8dcac29df2b --- /dev/null +++ b/doc/examples/accelbubble/accelbubble.pro @@ -0,0 +1,14 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) + diff --git a/doc/examples/accelbubble/main.qml b/doc/examples/accelbubble/main.qml index 10d7aa99080..02cc2f653d0 100644 --- a/doc/examples/accelbubble/main.qml +++ b/doc/examples/accelbubble/main.qml @@ -35,8 +35,8 @@ ** **************************************************************************/ -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.5 +import QtQuick.Controls 1.4 import QtSensors 5.0 @@ -47,6 +47,20 @@ ApplicationWindow { height: 480 visible: true + menuBar: MenuBar { + Menu { + title: qsTr("File") + MenuItem { + text: qsTr("&Open") + onTriggered: console.log("Open action triggered"); + } + MenuItem { + text: qsTr("Exit") + onTriggered: Qt.quit(); + } + } + } + Image { id: bubble source: "Bluebubble.svg" @@ -105,18 +119,4 @@ ApplicationWindow { function calcRoll(x, y, z) { return -(Math.atan(x / Math.sqrt(y * y + z * z)) * 57.2957795); } - - menuBar: MenuBar { - Menu { - title: qsTr("File") - MenuItem { - text: qsTr("&Open") - onTriggered: console.log("Open action triggered"); - } - MenuItem { - text: qsTr("Exit") - onTriggered: Qt.quit(); - } - } - } } diff --git a/doc/examples/transitions/main.qml b/doc/examples/transitions/main.qml index 8769546257d..c4ccfe0c5eb 100644 --- a/doc/examples/transitions/main.qml +++ b/doc/examples/transitions/main.qml @@ -1,24 +1,41 @@ -import QtQuick 2.1 -import QtQuick.Window 2.1 +import QtQuick 2.5 +import QtQuick.Controls 1.4 -Window { +ApplicationWindow { id: page visible: true width: 360 height: 360 color: "#343434" + title: qsTr("Transitions") + + menuBar: MenuBar { + Menu { + title: qsTr("File") + MenuItem { + text: qsTr("&Open") + onTriggered: console.log("Open action triggered"); + } + MenuItem { + text: qsTr("Exit") + onTriggered: Qt.quit(); + } + } + } Image { id: icon x: 10 y: 20 - source: "states.png" + source: "states.svg" } Rectangle { id: topLeftRect - width: 64 - height: 64 + x: 10 + y: 20 + width: 44 + height: 44 color: "#00000000" radius: 6 opacity: 1 @@ -37,8 +54,8 @@ Window { Rectangle { id: middleRightRect - width: 64 - height: 64 + width: 44 + height: 44 color: "#00000000" radius: 6 anchors.right: parent.right @@ -55,8 +72,8 @@ Window { Rectangle { id: bottomLeftRect - width: 64 - height: 64 + width: 44 + height: 44 color: "#00000000" radius: 6 border.width: 1 diff --git a/doc/examples/transitions/states.png b/doc/examples/transitions/states.png deleted file mode 100644 index 707d5c4e85d..00000000000 Binary files a/doc/examples/transitions/states.png and /dev/null differ diff --git a/doc/examples/transitions/states.svg b/doc/examples/transitions/states.svg new file mode 100644 index 00000000000..566acfada01 --- /dev/null +++ b/doc/examples/transitions/states.svg @@ -0,0 +1,93 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/doc/examples/uiforms/CustomerModelSingleton.qml b/doc/examples/uiforms/CustomerModelSingleton.qml new file mode 100644 index 00000000000..1a80ea083e8 --- /dev/null +++ b/doc/examples/uiforms/CustomerModelSingleton.qml @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton + +import QtQuick 2.0 + +ListModel { + property QtObject selection + ListElement { + customerId: "15881123" + firstName: "Julia" + title: "Ms." + lastName: "Jefferson" + email: "Julia@example.com" + address: "Spandia Avenue, Suite 610" + city: "Toronto" + zipCode: "92334" + phoneNumber: "0803-033330" + notes: "Very demanding customer." + history: "21.4.2014|Order|coffee~23.4.2014|Order|poster~29.4.2014|Invoice|poster 40$~05.5.2014|Overdue Notice|poster 40$" + } + + ListElement { + customerId: "29993496" + firstName: "Tim" + lastName: "Northington" + title: "Mr." + email: "Northington@example.com" + address: "North Fifth Street 55" + city: "San Jose" + zipCode: "95112" + phoneNumber: "09000-3330" + notes: "Very good customer." + history: "18.4.2014|Order|orange juice~23.4.2014|Order|chair~24.4.2014|Complaint|Chair is broken." + } + + ListElement { + customerId: "37713567" + firstName: "Daniel" + lastName: "Krumm" + title: "Mr." + email: "Krumm@example.com" + address: "Waterfront 14" + city: "Berlin" + zipCode: "12334" + phoneNumber: "0708093330" + notes: "This customer has a lot of Complaints." + history: "15.4.2014|Order|table~25.4.2014|Return|table~28.4.2014|Complaint|Table had wrong color." + } + + ListElement { + customerId: "45817387" + firstName: "Sandra" + lastName: "Booth" + title: "Ms." + email: "Sandrab@example.com" + address: "Folsom Street 23" + city: "San Francisco" + zipCode: "94103" + phoneNumber: "0103436370" + notes: "This customer is not paying." + history: "22.4.2014|Order|coffee~23.4.2014|Order|smartphone~29.4.2014|Invoice|smartphone 200$~05.5.2014|Overdue Notice|smartphone 200$" + } + + ListElement { + customerId: "588902396" + firstName: "Lora" + lastName: "Beckner" + title: "Ms." + email: "LoraB@example.com" + address: " W Wilson Apt 3" + city: "Los Angeles" + zipCode: "90086" + phoneNumber: "0903436360" + notes: "This customer usually pays late." + history: "17.4.2014|Order|soft drink~23.4.2014|Order|computer~29.4.2014|Invoice|computer 1200$~07.5.2014|Overdue Notice|computer 1200$" + } + + ListElement { + customerId: "78885693" + firstName: "Vanessa" + lastName: "Newbury" + title: "Ms." + email: "VanessaN@example.com" + address: "Madison Ave. 277" + city: "New York" + zipCode: "10016" + phoneNumber: "0503053530" + notes: "Deliveries sometime do not arrive on time." + history: "19.4.2014|Order|coffee~23.4.2014|Order|bicycle~29.4.2014|Invoice|bicycle 500$~06.5.2014|Overdue Notice|bicycle 500$" + } +} diff --git a/doc/examples/uiforms/CustomerTableView.qml b/doc/examples/uiforms/CustomerTableView.qml new file mode 100644 index 00000000000..a938fc59ebf --- /dev/null +++ b/doc/examples/uiforms/CustomerTableView.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.3 +import QtQuick.Layouts 1.1 + +TableView { + id: tableView + + property int columnWidth: width / 3 - 1 + Layout.minimumWidth: splitView1.width * 2 / 5 + + TableViewColumn { + role: "customerId" + title: qsTr("Customer Id") + width: tableView.columnWidth + } + + TableViewColumn { + role: "firstName" + title: qsTr("First Name") + width: tableView.columnWidth + } + + TableViewColumn { + role: "lastName" + title: qsTr("Last Name") + width: tableView.columnWidth + } +} diff --git a/doc/examples/uiforms/History.qml b/doc/examples/uiforms/History.qml new file mode 100644 index 00000000000..dfa1bfc0724 --- /dev/null +++ b/doc/examples/uiforms/History.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import my.customermodel.singleton 1.0 + +HistoryTableView { + + function readData() { + CustomerModel.selection.forEach(function (rowIndex) { + + var history = CustomerModel.get(rowIndex).history + var entries = history.split("~") + + model.clear() + + var index + for (index = 0; index < entries.length; index++) { + var entry = entries[index] + var data = entry.split("|") + model.append({ + date: data[0], + type: data[1], + text: data[2] + }) + } + }) + } + + Connections { + target: CustomerModel.selection + onSelectionChanged: readData() + } + + Component.onCompleted: readData() +} diff --git a/doc/examples/uiforms/HistoryTableView.qml b/doc/examples/uiforms/HistoryTableView.qml new file mode 100644 index 00000000000..4a33087f3f6 --- /dev/null +++ b/doc/examples/uiforms/HistoryTableView.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.3 +import QtQuick.Layouts 1.1 + +TableView { + id: tableView + + property int columnWidth: width / 3 + + anchors.fill: parent + + TableViewColumn { + role: "date" + title: qsTr("Date") + width: tableView.columnWidth + } + + TableViewColumn { + role: "type" + title: qsTr("Type") + width: tableView.columnWidth + } + + TableViewColumn { + role: "text" + title: qsTr("Description") + width: tableView.columnWidth + } + + model: ListModel { + } +} diff --git a/doc/examples/uiforms/MainForm.ui.qml b/doc/examples/uiforms/MainForm.ui.qml new file mode 100644 index 00000000000..d0beed79871 --- /dev/null +++ b/doc/examples/uiforms/MainForm.ui.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.1 + +Item { + property alias tableView1: tableView1 + + SplitView { + id: splitView1 + anchors.fill: parent + + CustomerTableView { + id: tableView1 + } + + TabView { + id: tabView1 + width: 360 + height: 300 + + Tab { + id: tab1 + source: "Settings.qml" + title: "Customer Settings" + } + + Tab { + id: tab2 + x: -3 + y: 5 + source: "Notes.qml" + title: "Customer Notes" + } + + Tab { + id: tab3 + x: -7 + y: -7 + source: "History.qml" + title: "Customer History" + } + } + } + +} + diff --git a/doc/examples/uiforms/Notes.qml b/doc/examples/uiforms/Notes.qml new file mode 100644 index 00000000000..be6a5d75ec5 --- /dev/null +++ b/doc/examples/uiforms/Notes.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import my.customermodel.singleton 1.0 + +NotesForm { + id: form + + function readData() { + CustomerModel.selection.forEach(function (rowIndex) { + form.textArea1.text = CustomerModel.get(rowIndex).notes + }) + + save.enabled = true + cancel.enabled = true + form.textArea1.enabled = true + } + + function writeData() { + CustomerModel.selection.forEach(function (rowIndex) { + var data = CustomerModel.get(rowIndex) + data.notes = form.textArea1.text + CustomerModel.set(rowIndex, data) + }) + } + + cancel.onClicked: readData() + save.onClicked: writeData() + + Connections { + target: CustomerModel.selection + onSelectionChanged: form.readData() + } + + Component.onCompleted: readData() +} diff --git a/doc/examples/uiforms/NotesForm.ui.qml b/doc/examples/uiforms/NotesForm.ui.qml new file mode 100644 index 00000000000..edbde598a92 --- /dev/null +++ b/doc/examples/uiforms/NotesForm.ui.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 1.2 + +Item { + id: content + width: 400 + height: 400 + property alias textArea1: textArea1 + property alias cancel: cancel + property alias save: save + + ColumnLayout { + id: columnLayout1 + height: 100 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.left: parent.left + anchors.leftMargin: 12 + anchors.top: parent.top + anchors.topMargin: 12 + + TextArea { + id: textArea1 + Layout.fillHeight: true + Layout.fillWidth: true + } + } + + RowLayout { + id: rowLayout1 + width: 100 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.bottom: parent.bottom + anchors.bottomMargin: 12 + + Button { + id: save + text: qsTr("Save") + Layout.fillHeight: true + Layout.fillWidth: true + } + + Button { + id: cancel + text: qsTr("Cancel") + Layout.fillHeight: true + Layout.fillWidth: true + } + } +} + diff --git a/doc/examples/uiforms/Settings.qml b/doc/examples/uiforms/Settings.qml new file mode 100644 index 00000000000..a0b70e161ea --- /dev/null +++ b/doc/examples/uiforms/Settings.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import my.customermodel.singleton 1.0 + +SettingsForm { + id: form + anchors.fill: parent + + function readData() { + + form.title.model = ["Mr.", "Ms."] + + CustomerModel.selection.forEach(function (rowIndex) { + form.firstName.text = CustomerModel.get(rowIndex).firstName + form.lastName.text = CustomerModel.get(rowIndex).lastName + form.customerId.text = CustomerModel.get(rowIndex).customerId + form.title.currentIndex = form.title.find(CustomerModel.get(rowIndex).title) + }) + + save.enabled = true + cancel.enabled = true + gridLayout1.enabled = true + } + + function writeData() { + CustomerModel.selection.forEach(function (rowIndex) { + var notes = CustomerModel.get(rowIndex).notes + CustomerModel.set(rowIndex, { + firstName: form.firstName.text, + lastName: form.lastName.text, + customerId: form.customerId.text, + title: form.title.currentText, + notes: notes + }) + }) + } + + cancel.onClicked: readData() + save.onClicked: writeData() + + Connections { + target: CustomerModel.selection + onSelectionChanged: form.readData() + } + + Component.onCompleted: readData() +} diff --git a/doc/examples/uiforms/SettingsForm.ui.qml b/doc/examples/uiforms/SettingsForm.ui.qml new file mode 100644 index 00000000000..5a86c8c7fd1 --- /dev/null +++ b/doc/examples/uiforms/SettingsForm.ui.qml @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.0 + +Item { + id: content + + property alias customerId: customerId + property alias lastName: lastName + property alias firstName: firstName + property alias gridLayout1: gridLayout1 + property alias rowLayout1: rowLayout1 + + property alias save: save + property alias cancel: cancel + property alias title: title + + GridLayout { + id: gridLayout1 + rows: 4 + columns: 3 + rowSpacing: 8 + columnSpacing: 8 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.left: parent.left + anchors.leftMargin: 12 + anchors.top: parent.top + anchors.topMargin: 12 + + Label { + id: label1 + text: qsTr("Title") + } + + Label { + id: label2 + text: qsTr("First Name") + } + + Label { + id: label3 + text: qsTr("Last Name") + } + + + ComboBox { + id: title + } + + + TextField { + id: firstName + text: "" + Layout.fillHeight: true + Layout.fillWidth: true + placeholderText: qsTr("First Name") + } + + + + TextField { + id: lastName + Layout.fillHeight: true + Layout.fillWidth: true + placeholderText: qsTr("Last Name") + } + + + + + Label { + id: label4 + text: qsTr("Customer Id") + Layout.fillWidth: true + Layout.fillHeight: true + } + + TextField { + id: customerId + width: 0 + height: 0 + Layout.fillHeight: true + Layout.fillWidth: true + Layout.columnSpan: 3 + placeholderText: qsTr("Customer Id") + } + } + + RowLayout { + id: rowLayout1 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.bottom: parent.bottom + anchors.bottomMargin: 12 + + Button { + id: save + text: qsTr("Save") + Layout.fillHeight: true + Layout.fillWidth: true + } + + Button { + id: cancel + text: qsTr("Cancel") + Layout.fillHeight: true + Layout.fillWidth: true + } + } +} + diff --git a/doc/examples/uiforms/deployment.pri b/doc/examples/uiforms/deployment.pri new file mode 100644 index 00000000000..5441b63dc85 --- /dev/null +++ b/doc/examples/uiforms/deployment.pri @@ -0,0 +1,27 @@ +android-no-sdk { + target.path = /data/user/qt + export(target.path) + INSTALLS += target +} else:android { + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + export(target.path) + INSTALLS += target +} else:unix { + isEmpty(target.path) { + qnx { + target.path = /tmp/$${TARGET}/bin + } else { + target.path = /opt/$${TARGET}/bin + } + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) diff --git a/doc/examples/uiforms/main.cpp b/doc/examples/uiforms/main.cpp new file mode 100644 index 00000000000..86f9268177b --- /dev/null +++ b/doc/examples/uiforms/main.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QUrl resourceUrl(QStringLiteral("qrc:/CustomerModelSingleton.qml")); + qmlRegisterSingletonType(resourceUrl, "my.customermodel.singleton", 1, 0, "CustomerModel"); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + + return app.exec(); +} diff --git a/doc/examples/uiforms/main.qml b/doc/examples/uiforms/main.qml new file mode 100644 index 00000000000..0d6830d5e51 --- /dev/null +++ b/doc/examples/uiforms/main.qml @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 +import my.customermodel.singleton 1.0 + +ApplicationWindow { + visible: true + width: 640 + height: 480 + title: qsTr("Qt Quick UI Forms") + + menuBar: MenuBar { + Menu { + title: qsTr("&File") + MenuItem { + text: qsTr("E&xit") + onTriggered: Qt.quit(); + } + } + Menu { + title: qsTr("&Edit") + MenuItem { + action: cutAction + } + MenuItem { + action: copyAction + } + MenuItem { + action: pasteAction + } + } + Menu { + title: qsTr("&Help") + MenuItem { + text: qsTr("About...") + onTriggered: aboutDialog.open() + } + } + } + + Action { + id: copyAction + text: qsTr("&Copy") + shortcut: StandardKey.Copy + iconName: "edit-copy" + enabled: (!!activeFocusItem && !!activeFocusItem["copy"]) + onTriggered: activeFocusItem.copy() + } + + Action { + id: cutAction + text: qsTr("Cu&t") + shortcut: StandardKey.Cut + iconName: "edit-cut" + enabled: (!!activeFocusItem && !!activeFocusItem["cut"]) + onTriggered: activeFocusItem.cut() + } + + Action { + id: pasteAction + text: qsTr("&Paste") + shortcut: StandardKey.Paste + iconName: "edit-paste" + enabled: (!!activeFocusItem && !!activeFocusItem["paste"]) + onTriggered: activeFocusItem.paste() + } + + MainForm { + anchors.fill: parent + Layout.minimumWidth: 800 + Layout.minimumHeight: 480 + Layout.preferredWidth: 768 + Layout.preferredHeight: 480 + tableView1.model: CustomerModel + + Component.onCompleted: CustomerModel.selection = tableView1.selection + } + + MessageDialog { + id: aboutDialog + icon: StandardIcon.Information + title: qsTr("About") + text: "Qt Quick UI Forms" + informativeText: qsTr("This example demonstrates how to separate the " + + "implementation of an application from the UI " + + "using ui.qml files.") + } +} + diff --git a/doc/examples/uiforms/qml.qrc b/doc/examples/uiforms/qml.qrc new file mode 100644 index 00000000000..a459cec0380 --- /dev/null +++ b/doc/examples/uiforms/qml.qrc @@ -0,0 +1,14 @@ + + + main.qml + MainForm.ui.qml + CustomerModelSingleton.qml + Settings.qml + SettingsForm.ui.qml + Notes.qml + NotesForm.ui.qml + History.qml + HistoryTableView.qml + CustomerTableView.qml + + diff --git a/doc/examples/uiforms/uiforms.pro b/doc/examples/uiforms/uiforms.pro new file mode 100644 index 00000000000..d11099c2b53 --- /dev/null +++ b/doc/examples/uiforms/uiforms.pro @@ -0,0 +1,15 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) + +DISTFILES += diff --git a/doc/images/qmldesigner-tutorial-design-mode.png b/doc/images/qmldesigner-tutorial-design-mode.png index 1cd9f9e7756..0733593ae4e 100644 Binary files a/doc/images/qmldesigner-tutorial-design-mode.png and b/doc/images/qmldesigner-tutorial-design-mode.png differ diff --git a/doc/images/qmldesigner-tutorial-page.png b/doc/images/qmldesigner-tutorial-page.png index 8148788ae17..7adecac391f 100644 Binary files a/doc/images/qmldesigner-tutorial-page.png and b/doc/images/qmldesigner-tutorial-page.png differ diff --git a/doc/images/qmldesigner-tutorial-project.png b/doc/images/qmldesigner-tutorial-project.png index f03bb501dd0..5f395a639e0 100644 Binary files a/doc/images/qmldesigner-tutorial-project.png and b/doc/images/qmldesigner-tutorial-project.png differ diff --git a/doc/images/qmldesigner-tutorial-topleftrect.png b/doc/images/qmldesigner-tutorial-topleftrect.png index d4b90ec9be7..853602ddcf0 100644 Binary files a/doc/images/qmldesigner-tutorial-topleftrect.png and b/doc/images/qmldesigner-tutorial-topleftrect.png differ diff --git a/doc/images/qmldesigner-tutorial-user-icon.png b/doc/images/qmldesigner-tutorial-user-icon.png index cf678c7b4fb..972b73c79fd 100644 Binary files a/doc/images/qmldesigner-tutorial-user-icon.png and b/doc/images/qmldesigner-tutorial-user-icon.png differ diff --git a/doc/images/qmldesigner-tutorial.png b/doc/images/qmldesigner-tutorial.png index a4afab78681..af60348eb17 100644 Binary files a/doc/images/qmldesigner-tutorial.png and b/doc/images/qmldesigner-tutorial.png differ diff --git a/doc/images/qmldesigner-uiforms-example-about-dialog.png b/doc/images/qmldesigner-uiforms-example-about-dialog.png new file mode 100644 index 00000000000..0cf6e33210c Binary files /dev/null and b/doc/images/qmldesigner-uiforms-example-about-dialog.png differ diff --git a/doc/images/qmldesigner-uiforms-example-main-view.png b/doc/images/qmldesigner-uiforms-example-main-view.png new file mode 100644 index 00000000000..099611c10fe Binary files /dev/null and b/doc/images/qmldesigner-uiforms-example-main-view.png differ diff --git a/doc/images/qmldesigner-uiforms-example-settings-tab.png b/doc/images/qmldesigner-uiforms-example-settings-tab.png new file mode 100644 index 00000000000..7c5319bc1c9 Binary files /dev/null and b/doc/images/qmldesigner-uiforms-example-settings-tab.png differ diff --git a/doc/images/qmldesigner-uiforms-example.png b/doc/images/qmldesigner-uiforms-example.png new file mode 100644 index 00000000000..01292e5e105 Binary files /dev/null and b/doc/images/qmldesigner-uiforms-example.png differ diff --git a/doc/images/qmldesigner-uiforms-reset-height.png b/doc/images/qmldesigner-uiforms-reset-height.png new file mode 100644 index 00000000000..99d748a72db Binary files /dev/null and b/doc/images/qmldesigner-uiforms-reset-height.png differ diff --git a/doc/src/analyze/qtquick-profiler.qdoc b/doc/src/analyze/qtquick-profiler.qdoc index e917afc9668..eb6e000a365 100644 --- a/doc/src/analyze/qtquick-profiler.qdoc +++ b/doc/src/analyze/qtquick-profiler.qdoc @@ -534,30 +534,5 @@ \uicontrol {Copy Table} or \uicontrol {Copy Row} in the context menu. JavaScript events are shown in the \uicontrol 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 \uicontrol V8 view. - - \section2 Viewing More Data - - The QML JavaScript engine optimizes trivial bindings. The QML Profiler - may not receive all information about optimized bindings, and therefore, - it may display the text \uicontrol {} and the message - \uicontrol {Source code not available} in the \uicontrol Callers and \uicontrol {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 - variable for the current project in the project settings: - - \list 1 - - \li Select \uicontrol {Projects > Run}. - - \li In \uicontrol {Run Environment}, click \uicontrol Add. - - \li Add the QML_DISABLE_OPTIMIZER variable and set its value to 1. - - \endlist - + that use Qt Quick 2 and are compiled with Qt 5.3 or later. */ diff --git a/doc/src/editors/creator-coding-edit-mode.qdoc b/doc/src/editors/creator-coding-edit-mode.qdoc index 9e02fd6a4fd..6793f96cfd5 100644 --- a/doc/src/editors/creator-coding-edit-mode.qdoc +++ b/doc/src/editors/creator-coding-edit-mode.qdoc @@ -30,8 +30,8 @@ \title Working in Edit Mode - This section describes how to use the \uicontrol Edit mode. For more information - about using the sidebar, see \l{Browsing Project Contents}. + This section describes how to use the \uicontrol Edit mode. For more + information about using the sidebar, see \l{Browsing Project Contents}. \section1 Using the Editor Toolbar @@ -41,30 +41,30 @@ \image qtcreator-editortoolbar-symbols.png - Use the toolbar to navigate between open files and symbols in use. - To browse backward or forward through your location history, click + Use the toolbar to navigate between open files and symbols in use. To browse + backward or forward through your location history, click \inlineimage qtcreator-back.png (\uicontrol {Go Back}) and \inlineimage qtcreator-forward.png (\uicontrol {Go Forward}). - To go to any open file, select it from the \uicontrol{Open files} drop-down menu (1). - Right-click the menu title and select \uicontrol {Copy Full Path} to - copy the path and name of the current file to the clipboard. + To go to any open file, select it from the \uicontrol {Open files} drop-down + menu (1). Right-click the menu title and select \uicontrol {Copy Full Path} + to copy the path and name of the current file to the clipboard. To jump to any symbol used in the current file, select it from the - \uicontrol Symbols drop-down menu (2). By default, the symbols are displayed in the - order in which they appear in the file. Right-click the menu title and - select \uicontrol {Sort Alphabetically} to arrange the symbols in alphabetic - order. + \uicontrol Symbols drop-down menu (2). By default, the symbols are displayed + in the order in which they appear in the file. Right-click the menu title + and select \uicontrol {Sort Alphabetically} to arrange the symbols in + alphabetic order. To jump to a line and column in the current file, select the line and column - indicator (3) or press \key {Ctrl+L} (or \key {Cmd+L} on OS X) to open - the locator. Enter the line number and column number in the locator, - separated by a colon (:). + indicator (3) or press \key {Ctrl+L} (or \key {Cmd+L} on OS X) to open the + locator. Enter the line number and column number in the locator, separated + by a colon (:). To show the file encoding of the current file on the editor toolbar (4), - select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Display > - \uicontrol {Display file encoding}. + select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol Display > \uicontrol {Display file encoding}. \note Other convenient ways of navigating in \QC are provided by the \l{Searching with the Locator}{locator}, \l{Keyboard Shortcuts} @@ -82,15 +82,16 @@ \list \li To split the editor view into a top and bottom view, select - \uicontrol Window > \uicontrol Split, press \key{Ctrl+E, 2}, or select the - \inlineimage qtcreator-split-button.png + \uicontrol Window > \uicontrol Split, press \key {Ctrl+E, 2}, or + select the \inlineimage qtcreator-split-button.png (\uicontrol Split) button and then select \uicontrol Split. Split command creates views below the currently active editor view. \li To split the editor view into adjacent views, select - \uicontrol Window > \uicontrol{Split Side by Side}, press \key{Ctrl+E, 3}, or - select \uicontrol {Split > Split Side by Side}. + \uicontrol Window > \uicontrol {Split Side by Side}, press + \key {Ctrl+E, 3}, or select \uicontrol Split > + \uicontrol {Split Side by Side}. Side by side split command creates views to the right of the currently active editor view. @@ -104,16 +105,17 @@ \endlist - To move between split views and detached editor windows, select \uicontrol Window - > \uicontrol{Go to Next Split or Window} or press \key{Ctrl+E, O}. + To move between split views and detached editor windows, select + \uicontrol Window > \uicontrol {Go to Next Split or Window} or press + \key {Ctrl+E, O}. To remove a split view, place the cursor within the view you want to - remove and select \uicontrol Window > \uicontrol{Remove Current Split}, press - \key{Ctrl+E, 0}, or select the + remove and select \uicontrol Window > \uicontrol {Remove Current Split}, + press \key {Ctrl+E, 0}, or select the \inlineimage qtcreator-remove-split-button.png - (\uicontrol {Remove Split}) button. To remove all but the currently selected split - view, - select \uicontrol Window > \uicontrol{Remove All Splits} or press \key{Ctrl+E, 1}. + (\uicontrol {Remove Split}) button. To remove all but the currently selected + split view, select \uicontrol Window > \uicontrol {Remove All Splits} or + press \key {Ctrl+E, 1}. \section1 Using Bookmarks @@ -132,8 +134,8 @@ \image qtcreator-togglebookmark.png To add a note to a bookmark, right-click the bookmark and select - \uicontrol{Edit Bookmark}. To view the note, move the mouse pointer over the - bookmark. + \uicontrol {Edit Bookmark}. To view the note, move the mouse pointer over + the bookmark. To go to previous bookmark in the current session, press \key {Ctrl+,}. @@ -142,40 +144,42 @@ \section1 Moving to Symbol Definition or Declaration You can move directly to the definition or the declaration of a symbol by - holding the \key Ctrl key and clicking the symbol. If you have multiple splits - opened, you can open the link in the next split by holding \key Ctrl and - \key Alt while clicking the symbol. + holding the \key Ctrl key and clicking the symbol. If you have multiple + splits opened, you can open the link in the next split by holding \key Ctrl + and \key Alt while clicking the symbol. - To enable this moving function, select \uicontrol Tools > \uicontrol{Options} > - \uicontrol{Text Editor} > \uicontrol Behavior > \uicontrol{Enable mouse navigation}. + To enable this moving function, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Behavior > + \uicontrol {Enable mouse navigation}. You can also select the symbol and press \key F2, or right-click the symbol - and select \uicontrol {Follow Symbol Under Cursor} to move to its definition or - declaration. This feature is supported for namespaces, classes, functions, - variables, include statements, and macros. + and select \uicontrol {Follow Symbol Under Cursor} to move to its definition + or declaration. This feature is supported for namespaces, classes, + functions, variables, include statements, and macros. To switch between the definition and declaration of a function, place the - cursor on either and press \key {Shift+F2} or right-click and select \uicontrol - {Switch Between Function Declaration/Definition}. For example, this allows - you to navigate from anywhere within a function body directly to the function - declaration. + cursor on either and press \key {Shift+F2} or right-click and select + \uicontrol {Switch Between Function Declaration/Definition}. For example, + this allows you to navigate from anywhere within a function body directly to + the function declaration. Links are opened in the same split by default. To open links in the next - split, prepend \key {Ctrl+E} to the shortcut. For example, press \key {Ctrl+E,F2} - to follow the symbol in the next split. If necessary, the view is - automatically split. To change the default behavior, select \uicontrol Tools > - \uicontrol{Options} > \uicontrol{Text Editor} > \uicontrol Display, and then select - \uicontrol{Always Open Links in Next Split}. Additional symbols are displayed and - switching between definition and declaration is done in another split. - If you change the default behavior, the shortcuts for opening link targets - in the next split are used to open them in the current split. + split, prepend \key {Ctrl+E} to the shortcut. For example, press + \key {Ctrl+E,F2} to follow the symbol in the next split. If necessary, the + view is automatically split. To change the default behavior, select + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol Display, and then select + \uicontrol {Always Open Links in Next Split}. Additional symbols are + displayed and switching between definition and declaration is done in + another split. If you change the default behavior, the shortcuts for opening + link targets in the next split are used to open them in the current split. \section1 Reparsing Externally Changed Files If source files are modified from outside \QC, the opened files will be - reparsed automatically. For all other files, you can use \uicontrol{Tools} > - \uicontrol{C++} > \uicontrol{Reparse Externally Changed Files} to update the code - model. + reparsed automatically. For all other files, you can use \uicontrol Tools > + \uicontrol {C++} > \uicontrol {Reparse Externally Changed Files} to update + the code model. \section1 Inspecting the Code Model @@ -185,14 +189,13 @@ inspection. To view information about the C++ code model in the - \uicontrol {C++ Code Model Inspector} dialog and write it to a log file, select - \uicontrol Tools > \uicontrol C++ > \uicontrol {Inspect C++ Code Model} or press - \key {Ctrl+Shift+F12}. + \uicontrol {C++ Code Model Inspector} dialog and write it to a log file, + select \uicontrol Tools > \uicontrol {C++} > + \uicontrol {Inspect C++ Code Model} or press \key {Ctrl+Shift+F12}. \QC generates the code model inspection log file in a temporary folder. - \QC underlines semantic errors in olive in the C++ code editor. To - check the correct paths for includes that are not resolved or that are - resolved to the wrong file, select \uicontrol {Project Parts} > - \uicontrol {Include Paths}. + \QC underlines semantic errors in olive in the C++ code editor. To check the + correct paths for includes that are not resolved or that are resolved to the + wrong file, select \uicontrol {Project Parts} > \uicontrol {Include Paths}. */ diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 926dd1a8f23..124be5bb69d 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -31,8 +31,7 @@ \title Semantic Highlighting \QC understands the C++, QML, and JavaScript languages as code, not as plain - text. - It reads the source code, analyzes it, and highlights it based on the + text. It reads the source code, analyzes it, and highlights it based on the semantic checks that it does for the following code elements: \list @@ -48,10 +47,11 @@ \endlist To specify the color scheme to use for semantic highlighting, select - \uicontrol {Tools > Options > Text Editor > Fonts & Color}. + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol {Fonts & Color}. - \QC supports syntax highlighting also for other types of files than - C++, QML, or JavaScript. + \QC supports syntax highlighting also for other types of files than C++, + QML, or JavaScript. \section1 Generic Highlighting @@ -65,9 +65,9 @@ If you have a Unix installation that comes with the Kate Editor, you might already have the definition files installed. Typically, the files are located in a read-only directory, and therefore, you cannot manage them. \QC - can try to locate them and use them as fallback files, when the - primary location does not contain the definition for the current file type. - You can also specify the directory that contains preinstalled highlight + can try to locate them and use them as fallback files, when the primary + location does not contain the definition for the current file type. You can + also specify the directory that contains preinstalled highlight definition files as the primary location. When you open a file for editing and the editor cannot find the highlight @@ -78,8 +78,8 @@ \list 1 - \li Select \uicontrol {Tools > Options > Text Editor > Generic - Highlighter}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol {Text Editor} > \uicontrol {Generic Highlighter}. \image qtcreator-generic-highlighter.png "Generic Highlighter options" @@ -113,27 +113,27 @@ \section1 Highlighting and Folding Blocks Use block highlighting to visually separate parts of the code that belong - together. For example, when you place the cursor within the braces, - the code enclosed in braces is highlighted. + together. For example, when you place the cursor within the braces, the code + enclosed in braces is highlighted. \image qtcreator-blockhighlighting.png - To enable block highlighting, select \uicontrol Tools > \uicontrol{Options} > - \uicontrol{Text Editor} > \uicontrol Display > \uicontrol{Highlight blocks}. + To enable block highlighting, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Display > + \uicontrol {Highlight blocks}. - Use the folding markers to collapse and expand blocks of code within - braces. Click the folding marker to collapse or expand a block. In the - figure above, the folding markers are located between the line number and - the text pane. + Use the folding markers to collapse and expand blocks of code within braces. + Click the folding marker to collapse or expand a block. In the figure above, + the folding markers are located between the line number and the text pane. - To show the folding markers, select \uicontrol Tools > \uicontrol{Options} > - \uicontrol{Text Editor} > \uicontrol Display > \uicontrol{Display folding markers}. This - option is enabled by default. + To show the folding markers, select \uicontrol Tools > \uicontrol Options > + \uicontrol {Text Editor} > \uicontrol Display > + \uicontrol {Display folding markers}. This option is enabled by default. - When the cursor is on a brace, the matching brace is animated - by default. To turn off the animation and just highlight the block and - the braces, select \uicontrol {Tools > Options > Text Editor > Display} and - deselect \uicontrol {Animate matching parentheses}. + When the cursor is on a brace, the matching brace is animated by default. To + turn off the animation and just highlight the block and the braces, select + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol Display and deselect \uicontrol {Animate matching parentheses}. */ @@ -148,9 +148,9 @@ As you write code, \QC checks code syntax. When \QC spots a syntax error in your code it underlines it and shows error details when you move the mouse - pointer over the error. - Similarly, when you are working on an instance of a JavaScript object - notation (JSON) entity, \QC underlines errors in JSON data structure. + pointer over the error. Similarly, when you are working on an instance of a + JavaScript object notation (JSON) entity, \QC underlines errors in JSON data + structure. \list @@ -194,15 +194,16 @@ \section1 Checking JavaScript and QML Syntax - To run the checks, select \uicontrol {Tools > QML/JS > Run Checks} or press - \key Ctrl+Shift+C. The results are shown in the \uicontrol {QML Analysis} - filter of the \uicontrol {Issues} output pane. + To run the checks, select \uicontrol Tools > \uicontrol {QML/JS} > + \uicontrol {Run Checks} or press \key {Ctrl+Shift+C}. The results are shown + in the \uicontrol {QML Analysis} filter of the \uicontrol Issues output + pane. \section1 List of JavaScript and QML Checks - Many of the JavaScript checks are similar to the ones in Douglas - Crockford's JSLint tool and are explained well on + Many of the JavaScript checks are similar to the ones in Douglas Crockford's + JSLint tool and are explained well on \l{http://www.jslint.com/lint.html}{the JSLint website}. \table @@ -293,19 +294,19 @@ \row \li M16 \li Error - \li Invalid property name 'name' + \li Invalid property name \c name \li \row \li M17 \li Error - \li 'Name' does not have members + \li \c Name does not have members \li \row \li M18 \li Error - \li 'Field' is not a member of 'object' + \li \c Field is not a member of \c object \li \row @@ -316,31 +317,30 @@ assignment in parentheses. \row - \li M20 - \li Warning - \li Unterminated non-empty case block - \li Case blocks should either be empty or end in a flow control - statement such as 'break', 'return' or 'continue'. - Alternatively you can indicate intentional fall through by - ending with a '// fall through' comment. + \li M20 + \li Warning + \li Unterminated non-empty case block + \li Case blocks should either be empty or end in a flow control + statement such as \c break, \c return or \c continue. + Alternatively you can indicate intentional fall through by ending + with a \c {// fall through} comment. \row \li M23 \li Warning - \li Do not use 'eval' + \li Do not use \c eval \li \row - \li M28 - \li Warning - \li Unreachable - \li Indicates that the underlined statement will never be - executed. + \li M28 + \li Warning + \li Unreachable + \li Indicates that the underlined statement will never be executed. \row \li M29 \li Warning - \li Do not use 'with' + \li Do not use \c with \li \row @@ -358,85 +358,85 @@ \row \li M103 \li Warning - \li 'Name' is already a formal parameter + \li \c Name is already a formal parameter \li \row \li M104 \li Warning - \li 'Name' is already a function + \li \c Name is already a function \li \row \li M105 \li Warning - \li Var 'name' is used before its declaration + \li Var \c name is used before its declaration \li \row \li M106 \li Warning - \li 'Name' is already a var + \li \c Name is already a var \li \row - \li M107 - \li Warning - \li 'Name' is declared more than once - \li Variables declared in a function are always visible everywhere - in the function, even when declared in nested blocks or - 'for' statement conditions. Redeclaring a variable has no - effect. + \li M107 + \li Warning + \li \c Name is declared more than once + \li Variables declared in a function are always visible everywhere in + the function, even when declared in nested blocks or \c for + statement conditions. Redeclaring a variable has no effect. \row \li M108 \li Warning - \li Function 'name' is used before its declaration + \li Function \c name is used before its declaration \li \row \li M109 \li Warning - \li Do not use 'Boolean' as a constructor + \li Do not use \c Boolean as a constructor \li \row \li M110 \li Warning - \li Do not use 'String' as a constructor + \li Do not use \c String as a constructor \li \row \li M111 \li Warning - \li Do not use 'Object' as a constructor + \li Do not use \c Object as a constructor \li \row \li M112 \li Warning - \li Do not use 'Array' as a constructor + \li Do not use \c Array as a constructor \li \row \li M113 \li Warning - \li Do not use 'Function' as a constructor + \li Do not use \c Function as a constructor \li \row - \li M114 - \li Hint - \li The 'function' keyword and the opening parenthesis should be separated by a single space + \li M114 + \li Hint + \li The \c function keyword and the opening parenthesis should be + separated by a single space \li \row - \li M115 - \li Warning - \li Do not use stand-alone blocks - \li Blocks do not affect variable scoping. Thus blocks that are - not associated to 'if', 'while', etc. have no effect and - should be avoided. + \li M115 + \li Warning + \li Do not use stand-alone blocks + \li Blocks do not affect variable scoping. Thus blocks that are not + associated to \c if, \c while, etc. have no effect and should be + avoided. \row \li M116 @@ -470,19 +470,20 @@ \target m126 \row - \li M126 - \li Warning - \li == and != may perform type coercion, use === or !== to avoid it - \li The non-strict equality comparison is allowed to convert its - arguments to a common type. That can lead to unexpected - results such as \c {' \t\r\n' == 0} being true. Use the - strict equality operators === and !== and be explicit about - conversions you require. + \li M126 + \li Warning + \li \c == and \c != may perform type coercion, use \c === or \c !== to + avoid it + \li The non-strict equality comparison is allowed to convert its + arguments to a common type. That can lead to unexpected results such + as \c {' \t\r\n' == 0} being true. Use the strict equality operators + \c === and \c !== and be explicit about conversions you require. \row - \li M127 - \li Warning - \li Expression statements should be assignments, calls or delete expressions only + \li M127 + \li Warning + \li Expression statements should be assignments, calls or delete + expressions only \li \row @@ -509,10 +510,10 @@ \li This QML type is not supported in the Qt Quick Designer \li \row - \li M205 - \li Warning - \li Reference to parent QML type cannot be resolved correctly by the - Qt Quick Designer + \li M205 + \li Warning + \li Reference to parent QML type cannot be resolved correctly by the Qt + Quick Designer \li \row @@ -529,22 +530,22 @@ \li \row - \li M208 - \li Error - \li This type (%1) is not supported as a root element by \QMLD. + \li M208 + \li Error + \li This type (type name) is not supported as a root element by \QMLD. \li \row - \li M220 - \li Error - \li This type (%1) is not supported as a root element of a Qt Quick UI - form. + \li M220 + \li Error + \li This type (type name) is not supported as a root element of a Qt + Quick UI form. \li \row - \li M221 - \li Error - \li This type (%1) is not supported in a Qt Quick UI form. + \li M221 + \li Error + \li This type (type name) is not supported in a Qt Quick UI form. \li \row @@ -587,48 +588,50 @@ \row \li M301 \li Error - \li Could not resolve the prototype 'name' of 'object' + \li Could not resolve the prototype \c name of \c object \li \row \li M302 \li Error - \li Could not resolve the prototype 'name' + \li Could not resolve the prototype \c name \li \row \li M303 \li Error - \li Prototype cycle, the last non-repeated component is 'name' + \li Prototype cycle, the last non-repeated component is \c name \li \row \li M304 \li Error - \li Invalid property type 'name' + \li Invalid property type \c name \li \row - \li M305 - \li Warning - \li == and != perform type coercion, use === or !== to avoid it - \li See \l{m126}{M126}. + \li M305 + \li Warning + \li \c == and \c != perform type coercion, use \c === or \c !== to + avoid it + \li See \l{m126}{M126}. \row - \li M306 - \li Warning - \li Calls of functions that start with an uppercase letter should use 'new' - \li By convention, functions that start with an uppercase letter - are constructor functions that should only be used with 'new'. + \li M306 + \li Warning + \li Calls of functions that start with an uppercase letter should use + \c new + \li By convention, functions that start with an uppercase letter + are constructor functions that should only be used with \c new. \row - \li M307 - \li Warning - \li Use 'new' only with functions that start with an uppercase letter + \li M307 + \li Warning + \li Use \c new only with functions that start with an uppercase letter \li \row \li M308 \li Warning - \li Do not use 'Number' as a constructor + \li Do not use \c Number as a constructor \li \row @@ -644,15 +647,15 @@ \li \row - \li M311 - \li Hint - \li Use 'type' instead of 'var' or 'variant' to improve performance + \li M311 + \li Hint + \li Use \c type instead of \c var or \c variant to improve performance \li \row \li M312 \li Error - \li Missing property 'number' + \li Missing property \c number \li \row @@ -670,19 +673,19 @@ \row \li M315 \li Error - \li 'Value' value expected + \li \c Value value expected \li \row \li M316 \li Error - \li Maximum number value is 'number' + \li Maximum number value is \c number \li \row \li M317 \li Error - \li Minimum number value is 'number' + \li Minimum number value is \c number \li \row @@ -706,30 +709,30 @@ \row \li M321 \li Error - \li Minimum string value length is 'number' + \li Minimum string value length is \c number \li \row \li M322 \li Error - \li Maximum string value length is 'number' + \li Maximum string value length is \c number \li \row \li M323 \li Error - \li 'Number' elements expected in array value + \li \c Number elements expected in array value \li \row - \li M324 - \li Warning - \li Using Qt Quick 1 code model instead of Qt Quick 2 - \li The code model might be corrupt or the QML emulation layer might - have been built with a different Qt version than the one selected - in the build and run kit. For more information, see - \l {Resetting the Code Model} and - \l {Running QML Modules in Qt Quick Designer}. + \li M324 + \li Warning + \li Using Qt Quick 1 code model instead of Qt Quick 2 + \li The code model might be corrupt or the QML emulation layer might + have been built with a different Qt version than the one selected in + the build and run kit. For more information, see + \l {Resetting the Code Model} and + \l {Running QML Modules in Qt Quick Designer}. \endtable @@ -777,11 +780,11 @@ To open the list of suggestions at any time, press \key {Ctrl+Space}. If only one option is available, \QC inserts it automatically. - When completion is invoked manually, \QC completes the common prefix - of the list of suggestions. This is especially useful for classes with - several similarly named members. To disable this functionality, uncheck - \uicontrol{Autocomplete common prefix} in the code completion preferences. - Select \uicontrol Tools > \uicontrol{Options} > \uicontrol{Text Editor} + When completion is invoked manually, \QC completes the common prefix of the + list of suggestions. This is especially useful for classes with several + similarly named members. To disable this functionality, uncheck + \uicontrol {Autocomplete common prefix} in the code completion preferences. + Select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Completion. By default, code completion considers only the first letter case-sensitive. @@ -790,8 +793,8 @@ \section2 Summary of Available Types - The following table lists available types for code completion and icon - used for each. + The following table lists available types for code completion and icon used + for each. \table \header @@ -858,12 +861,11 @@ \section2 Completing Code Snippets - Code snippets can consist of multiple - variables that you specify values for. Select an item in the list and press - \key Tab or \key Enter to complete the code. Press \key Tab to - move between the variables and specify values for them. When you specify a - value for a variable, all instances of the variable within the snippet - are renamed. + Code snippets can consist of multiple variables that you specify values for. + Select an item in the list and press \key Tab or \key Enter to complete the + code. Press \key Tab to move between the variables and specify values for + them. When you specify a value for a variable, all instances of the variable + within the snippet are renamed. \image qmldesigner-code-completion.png "Completing QML code" @@ -871,7 +873,8 @@ Code snippets specify C++ or QML code constructs. You can add, modify, and remove snippets in the snippet editor. To open the editor, select - \uicontrol {Tools > Options > Text Editor > Snippets}. + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol Snippets. \image qtcreator-edit-code-snippets.png "Snippet options" @@ -891,10 +894,10 @@ \section3 Adding and Editing Snippets Select a snippet in the list to edit it in the snippet editor. To add a new - snippet, select \uicontrol Add. Specify a trigger and, if the trigger is already - in use, an optional variant, which appear in the list of suggestions when - you write code. Also specify a text string or C++ or QML code construct in - the snippet editor, depending on the snippet category. + snippet, select \uicontrol Add. Specify a trigger and, if the trigger is + already in use, an optional variant, which appear in the list of suggestions + when you write code. Also specify a text string or C++ or QML code construct + in the snippet editor, depending on the snippet category. The snippet editor provides you with: @@ -944,27 +947,27 @@ or add. However, when you use the snippets, the code editor marks any errors by underlining them in red. - To discard the changes you made to a built-in snippet, select \uicontrol {Revert - Built-in}. + To discard the changes you made to a built-in snippet, select + \uicontrol {Revert Built-in}. \section3 Removing Snippets - Several similar built-in snippets might be provided for different use - cases. To make the list of suggestions shorter when you write code, remove - the built-in snippets that you do not need. If you need them later, you - can restore them. + Several similar built-in snippets might be provided for different use cases. + To make the list of suggestions shorter when you write code, remove the + built-in snippets that you do not need. If you need them later, you can + restore them. To remove snippets, select a snippet in the list, and then select - \uicontrol Remove. To restore the removed snippets, select \uicontrol {Restore Removed - Built-ins}. + \uicontrol Remove. To restore the removed snippets, select + \uicontrol {Restore Removed Built-ins}. \section3 Resetting Snippets To remove all added snippets and to restore all removed snippets, select \uicontrol {Reset All}. - \note If you now select \uicontrol OK or \uicontrol Apply, you permanently lose all - your own snippets. + \note If you now select \uicontrol OK or \uicontrol Apply, you permanently + lose all your own snippets. */ @@ -999,60 +1002,64 @@ \list 1 - \li Select \uicontrol Tools > \uicontrol Options > \uicontrol{Code Pasting}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol {Code Pasting}. \image qtcreator-code-pasting-options.png "Code Pasting options" - \li In the \uicontrol {Default protocol} field, select a code pasting service - to use by default. + \li In the \uicontrol {Default protocol} field, select a code pasting + service to use by default. \li In the \uicontrol Username field, enter your username. - \li In the \uicontrol {Expires after} field, specify the time to keep the - pasted snippet on the server. + \li In the \uicontrol {Expires after} field, specify the time to keep + the pasted snippet on the server. - \li Select the \uicontrol {Copy-paste URL to clipboard} check box to copy the - URL of the post on the code pasting service to the clipboard when - you paste a post. + \li Select the \uicontrol {Copy-paste URL to clipboard} check box to + copy the URL of the post on the code pasting service to the + clipboard when you paste a post. \li Select the \uicontrol {Display Output pane after sending a post} to - display the URL in the \uicontrol {General Messages} output pane when you - paste a post. + display the URL in the \uicontrol {General Messages} output pane + when you paste a post. \endlist - Select \uicontrol Fileshare to specify the path to a shared - network drive. The code snippets are copied to the drive as simple files. - You have to delete obsolete files from the drive manually. + Select \uicontrol Fileshare to specify the path to a shared network drive. + The code snippets are copied to the drive as simple files. You have to + delete obsolete files from the drive manually. \section1 Using Code Pasting Services - To paste a snippet of code onto the server, select \uicontrol{Tools} > - \uicontrol{Code Pasting} > \uicontrol{Paste Snippet} or press \key{Alt+C,Alt+P}. - By default, \QC copies the URL of the snippet to the clipboard and displays - the URL in the \uicontrol {General Messages} output pane. + To paste a snippet of code onto the server, select \uicontrol Tools > + \uicontrol {Code Pasting} > \uicontrol {Paste Snippet} or press + \key {Alt+C,Alt+P}. By default, \QC copies the URL of the snippet to the + clipboard and displays the URL in the \uicontrol {General Messages} output + pane. - To paste any content that you copied to the clipboard, select \uicontrol Tools > - \uicontrol {Code Pasting} > \uicontrol {Paste Snippet}. + To paste any content that you copied to the clipboard, select + \uicontrol Tools > \uicontrol {Code Pasting} > \uicontrol {Paste Snippet}. To paste content from the \l{Comparing Files}{diff editor}, right-click a chunk and select \uicontrol {Send Chunk to CodePaster} in the context menu. - To fetch a snippet of code from the server, select \uicontrol{Tools} > - \uicontrol{Code Pasting} > \uicontrol{Fetch Snippet} or press \key{Alt+C,Alt+F}. Select - the snippet to fetch from the list. + To fetch a snippet of code from the server, select \uicontrol Tools > + \uicontrol {Code Pasting} > \uicontrol {Fetch Snippet} or press + \key {Alt+C,Alt+F}. Select the snippet to fetch from the list. To fetch the content stored at an URL, select \uicontrol Tools > \uicontrol {Code Pasting} > \uicontrol {Fetch from URL}. For example, you might ask colleagues to review a change that you plan to submit to a version control system. If you use the Git version control - system, you can create a \e{diff} view by selecting \uicontrol{Tools > Git > - Diff Repository}. You can then upload its contents to the server by choosing - \uicontrol{Tools} > \uicontrol{Code Pasting} > \uicontrol{Paste Snippet}. The reviewers can - retrieve the code snippet by selecting \uicontrol{Tools > Code Pasting > - Fetch Snippet}. If they have the project currently opened in \QC, they can - apply and test the change by choosing \uicontrol{Tools > Git > Apply Patch}. + system, you can create a \e{diff} view by selecting \uicontrol Tools > + \uicontrol Git > \uicontrol {Diff Repository}. You can then upload its + contents to the server by choosing \uicontrol Tools > + \uicontrol {Code Pasting} > \uicontrol {Paste Snippet}. The reviewers can + retrieve the code snippet by selecting \uicontrol Tools > + \uicontrol {Code Pasting} > \uicontrol {Fetch Snippet}. If they have the + project currently opened in \QC, they can apply and test the change by + choosing \uicontrol Tools > \uicontrol Git > \uicontrol {Apply Patch}. */ @@ -1065,26 +1072,31 @@ \title Using Text Editing Macros - To record a text editing macro, select \uicontrol {Tools > Text Editing Macros > Record Macro} - or press \key {Alt+(}. To stop recording, select \uicontrol {Tools > Text Editing Macros > - Stop Recording Macro} or press \key {Alt+)}. + To record a text editing macro, select \uicontrol Tools > + \uicontrol {Text Editing Macros} > \uicontrol {Record Macro} + or press \key {Alt+(}. To stop recording, select \uicontrol Tools > + \uicontrol {Text Editing Macros} > \uicontrol {Stop Recording Macro} or + press \key {Alt+)}. \note The macro recorder does not support code completion. - To play the last macro, select \uicontrol {Tools > Text Editing Macros > Play Last Macro} or + To play the last macro, select \uicontrol Tools > + \uicontrol {Text Editing Macros} > \uicontrol {Play Last Macro} or press \key {Alt+R}. - To save the last macro, select \uicontrol {Tools > Text Editing Macros > Save Last Macro}. + To save the last macro, select \uicontrol Tools > + \uicontrol {Text Editing Macros} > \uicontrol {Save Last Macro}. - To assign a keyboard shortcut to a text editing macro, select \uicontrol {Tools > - Options > Environment > Keyboard}. For more information, see + To assign a keyboard shortcut to a text editing macro, select + \uicontrol Tools > \uicontrol Options > \uicontrol Environment > + \uicontrol Keyboard. For more information, see \l{Configuring Keyboard Shortcuts}. You can also use the \c rm locator filter to run a macro. For more information, see \l{Searching with the Locator}. - To view and remove saved macros, select \uicontrol {Tools > Options > Text - Editor > Macros}. + To view and remove saved macros, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Macros. */ @@ -1097,44 +1109,45 @@ \title Using FakeVim Mode - In the \uicontrol{FakeVim} mode, you can run the main editor in a manner similar - to the Vim editor. To run the editor in the \uicontrol{FakeVim} mode, select - \uicontrol{Edit} > \uicontrol{Advanced} > \uicontrol{Use Vim-style Editing} or press - \key{Alt+V,Alt+V}. + In the \uicontrol FakeVim mode, you can run the main editor in a manner + similar to the Vim editor. To run the editor in the \uicontrol FakeVim + mode, select \uicontrol Edit > \uicontrol Advanced > + \uicontrol {Use Vim-style Editing} or press \key {Alt+V,Alt+V}. - In the \uicontrol{FakeVim} mode, most keystrokes in the main editor will be + In the \uicontrol FakeVim mode, most keystrokes in the main editor will be intercepted and interpreted in a way that resembles Vim. Documentation for - Vim is not included in \QC. For more information on using Vim, - see \l{http://www.vim.org/docs.php}{Documentation} on the Vim web site. + Vim is not included in \QC. For more information on using Vim, see + \l{http://www.vim.org/docs.php}{Documentation} on the Vim web site. - To map commands entered on the \uicontrol{FakeVim} command line to actions of the - \QC core, select \uicontrol{Tools} > \uicontrol{Options} > \uicontrol{FakeVim} > - \uicontrol{Ex Command Mapping}. + To map commands entered on the \uicontrol FakeVim command line to actions + of the \QC core, select \uicontrol Tools > \uicontrol Options > + \uicontrol FakeVim > \uicontrol {Ex Command Mapping}. - To map \e {user commands} to keyboard shortcuts, select \uicontrol{Tools > Options - > FakeVim > User Command Mapping}. The user command mapped to the shortcut + To map \e {user commands} to keyboard shortcuts, select \uicontrol Tools > + \uicontrol Options > \uicontrol FakeVim > + \uicontrol {User Command Mapping}. The user command mapped to the shortcut is executed by FakeVim as if you were typing it (as when replaying a macro). - To make changes to the Vim-style settings, select \uicontrol{Tools} > - \uicontrol{Options} > \uicontrol FakeVim > \uicontrol{General}. + To make changes to the Vim-style settings, select \uicontrol Tools > + \uicontrol Options > \uicontrol FakeVim > \uicontrol General. \image qtcreator-fakevim-options.png "FakeVim options" To preselect the indentation settings specified for the text editor, select - \uicontrol {Copy Text Editor Settings}. To preselect the Qt coding style, select - \uicontrol {Set Qt Style}. To preselect a simple indentation style, select - \uicontrol {Set Plain Style}. You can then change any of the preselected settings. + \uicontrol {Copy Text Editor Settings}. To preselect the Qt coding style, + select \uicontrol {Set Qt Style}. To preselect a simple indentation style, + select \uicontrol {Set Plain Style}. You can then change any of the + preselected settings. - To use a Vim-style color scheme, select \uicontrol {Tools > Options > - Text Editor > Fonts & Color}. In the \uicontrol {Color Scheme} list, select - \uicontrol {Vim (dark)}. + To use a Vim-style color scheme, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol {Fonts & Color}. + In the \uicontrol {Color Scheme} list, select \uicontrol {Vim (dark)}. - To quit the FakeVim mode, unselect \uicontrol{Tools} > \uicontrol{Options} > - \uicontrol{FakeVim} > \uicontrol {Use FakeVim} or press \key{Alt+V,Alt+V}. + To quit the FakeVim mode, unselect \uicontrol Tools > \uicontrol Options > + \uicontrol FakeVim > \uicontrol {Use FakeVim} or press \key {Alt+V,Alt+V}. - You can temporarily escape FakeVim mode to access the normal \QC - keyboard shortcuts like \key{Ctrl-R} for \uicontrol{Run} by pressing - \key{,} first. + You can temporarily escape FakeVim mode to access the normal \QC keyboard + shortcuts like \key {Ctrl-R} for \uicontrol Run by pressing \key {,} first. */ @@ -1146,9 +1159,9 @@ \title Indenting Text or Code - When you type text or code, it is indented automatically according to the selected - text editor or code style options. Select a block to indent it when you - press \key Tab. Press \key {Shift+Tab} to decrease the indentation. You + When you type text or code, it is indented automatically according to the + selected text editor or code style options. Select a block to indent it when + you press \key Tab. Press \key {Shift+Tab} to decrease the indentation. You can disable automatic indentation. You can specify indentation for: @@ -1173,10 +1186,10 @@ \list 1 - \li Select \uicontrol {Tools > Options > C++}. + \li Select \uicontrol Tools > \uicontrol Options > \uicontrol {C++}. - \li In the \uicontrol {Current settings} field, select the settings to modify - and click \uicontrol Copy. + \li In the \uicontrol {Current settings} field, select the settings to + modify and click \uicontrol Copy. \image qtcreator-options-code-style-cpp.png "C++ Code Style options" @@ -1211,8 +1224,8 @@ You can use the live preview to see how the options change the indentation. - To specify different settings for a particular project, select \uicontrol {Projects > - Code Style Settings}. + To specify different settings for a particular project, select + \uicontrol Projects > \uicontrol {Code Style Settings}. \section1 Indenting QML Files @@ -1220,10 +1233,11 @@ \list 1 - \li Select \uicontrol {Tools > Options >Qt Quick}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol {Qt Quick}. - \li In the \uicontrol {Current settings} field, select the settings to modify - and click \uicontrol Copy. + \li In the \uicontrol {Current settings} field, select the settings to + modify and click \uicontrol Copy. \image qtcreator-options-code-style-qml.png "QML Code Style options" @@ -1238,18 +1252,19 @@ You can specify how to interpret the \key Tab key presses and how to align continuation lines. - To specify different settings for a particular project, select \uicontrol {Projects > - Code Style Settings}. + To specify different settings for a particular project, select + \uicontrol Projects > \uicontrol {Code Style Settings}. \section1 Indenting Other Text Files - To specify indentation settings for text files that do not contain C++ or QML code (such - as Python code files), select \uicontrol {Tools > Options > Text Editor > Behavior}. + To specify indentation settings for text files that do not contain C++ or + QML code (such as Python code files), select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Behavior. \image qtcreator-indentation.png "Text Editor Behavior options" - To specify different settings for a particular project, select \uicontrol Projects - > \uicontrol Editor. + To specify different settings for a particular project, select + \uicontrol Projects > \uicontrol Editor. You can specify how to interpret the \key Tab and \key Backspace key presses and how to align continuation lines. @@ -1276,39 +1291,41 @@ \section2 Specifying Tabs and Indentation - You can specify tab policy and tab size in the \uicontrol Typing group. In the - \uicontrol {Tab policy} field, select whether to use only spaces or only tabs for - indentation, or to use a mixture of them. + You can specify tab policy and tab size in the \uicontrol Typing group. In + the \uicontrol {Tab policy} field, select whether to use only spaces or + only tabs for indentation, or to use a mixture of them. By default, the tab length in code editor is 8 spaces and the indent size is 4 spaces. You can specify the tab length and indent size separately for each project and for different types of files. You can have continuation lines aligned with the previous line. In the - \uicontrol {Align continuation lines} field, select \uicontrol {Not at all} to disable - automatic alignment and indent continuation lines to the logical depth. - To always use spaces for alignment, select \uicontrol {With Spaces}. To follow the - \uicontrol {Tab policy}, select \uicontrol {With Regular Indent}. + \uicontrol {Align continuation lines} field, select + \uicontrol {Not at all} to disable automatic alignment and indent + continuation lines to the logical depth. To always use spaces for alignment, + select \uicontrol {With Spaces}. To follow the \uicontrol {Tab policy}, + select \uicontrol {With Regular Indent}. \section2 Specifying Typing Options - When you type text or code, it is indented automatically according to the selected - text editor or code style options. Specify typing options in the + When you type text or code, it is indented automatically according to the + selected text editor or code style options. Specify typing options in the \uicontrol Typing group. To disable automatic indentation, deselect the \uicontrol {Enable automatic indentation} check box. You can specify how the indentation is decreased when you press - \uicontrol Backspace in the \uicontrol {Backspace indentation} field. To go back one - space at a time, select \uicontrol None. To decrease indentation in leading white - space by one level, select \uicontrol {Follows Previous Indents}. To move back one - tab length if the character to the left of the cursor is a space, select + \uicontrol Backspace in the \uicontrol {Backspace indentation} field. To go + back one space at a time, select \uicontrol None. To decrease indentation + in leading white space by one level, select + \uicontrol {Follows Previous Indents}. To move back one tab length if the + character to the left of the cursor is a space, select \uicontrol Unindents. You can specify whether the \key Tab key automatically indents text when you press it. To automatically indent text, select \uicontrol Always in the - \uicontrol {Tab key performs auto-indent} field. To only indent text when the - cursor is located within leading white space, select \uicontrol {In Leading White - Space}. + \uicontrol {Tab key performs auto-indent} field. To only indent text when + the cursor is located within leading white space, select \uicontrol {In + Leading White Space}. \section1 Specifying Settings for Content @@ -1336,10 +1353,10 @@ \section1 Specifying Alignment - To align continuation lines to tokens after assignments, such as = or - +=, select the \uicontrol {Align after assignments} check box. You can specify - additional settings for aligning continuation lines in the \uicontrol General - tab. + To align continuation lines to tokens after assignments, such as \c = or + \c +=, select the \uicontrol {Align after assignments} check box. You can + specify additional settings for aligning continuation lines in the + \uicontrol General tab. You can also add spaces to conditional statements, so that they are not aligned with the following line. Usually, this only affects \c if @@ -1349,12 +1366,12 @@ \section1 Binding Pointers and References - To bind pointers (*) and references (&) in types and declarations to + To bind pointers (\c *) and references (\c &) in types and declarations to identifiers, type names, or left or right \c const or \c volatile keywords, select the check boxes in the \uicontrol {Pointers and References} tab. - The * and & characters are automatically bound to identifiers of pointers to - functions and pointers to arrays. + The \c * and \c & characters are automatically bound to identifiers of + pointers to functions and pointers to arrays. \image qtcreator-pointers-references.png "Pointers and References options" @@ -1373,8 +1390,8 @@ \list 1 - \li Press \key Ctrl+F or select \uicontrol Edit > \uicontrol Find/Replace > - \uicontrol{Find/Replace}. + \li Press \key {Ctrl+F} or select \uicontrol Edit > + \uicontrol {Find/Replace} > \uicontrol {Find/Replace}. \li Enter the text you are looking for. @@ -1384,7 +1401,7 @@ (\uicontrol {Find Next}), or press \key F3. To go to the previous occurrence click \inlineimage qtcreator-previous.png - (\uicontrol {Find Previous}), or press \key Shift+F3. + (\uicontrol {Find Previous}), or press \key {Shift+F3}. \endlist @@ -1396,14 +1413,13 @@ \li To make your search case sensitive, select \uicontrol {Case Sensitive}. - \li To search only whole words, select - \uicontrol {Whole Words Only}. + \li To search only whole words, select \uicontrol {Whole Words Only}. \li To search using regular expressions, select - \uicontrol {Regular Expressions}. - Regular expressions used in \QC are modeled on Perl regular - expressions. For more information on using regular expressions, see - the documentation for the QRegExp Class. + \uicontrol {Regular Expressions}. Regular expressions used in \QC + are modeled on Perl regular expressions. For more information on + using regular expressions, see the documentation for the + QRegularExpression Class. \endlist @@ -1416,36 +1432,37 @@ \list \li To replace the selected occurrence and move to the next one, - click \uicontrol {Find Next} - or press \key Ctrl+=. + click \uicontrol {Find Next} or press \key {Ctrl+=}. \li To replace the selected occurrence and move to the previous one, - click \uicontrol {Find Previous} - . + click \uicontrol {Find Previous}. - \li To replace all occurrences in the file, click \uicontrol{Replace All}. + \li To replace all occurrences in the file, click + \uicontrol {Replace All}. \endlist - The \uicontrol{Preserve Case when Replacing} option can be selected to preserve - the case of the original text when replacing. This option is not compatible - with the \uicontrol {Regular Expressions} search option, and will thus be - disabled when regular expressions are used. When the option is used, the - case of the occurrence will be conserved, according to the following rules: + The \uicontrol {Preserve Case when Replacing} option can be selected to + preserve the case of the original text when replacing. This option is not + compatible with the \uicontrol {Regular Expressions} search option, and will + thus be disabled when regular expressions are used. When the option is used, + the case of the occurrence will be conserved, according to the following + rules: \list - \li All upper-case occurrences are replaced with the upper-case new text. - - \li All lower-case occurrences are replaced with the lower-case new text. + \li All upper-case occurrences are replaced with the upper-case new + text. + \li All lower-case occurrences are replaced with the lower-case new + text. \li Capitalized occurrences are replaced with the capitalized new text. \li Other occurrences are replaced with the new text as entered. - \li If an occurrence and the new text have the same prefix or suffix, - then the case of the prefix and/or suffix are preserved, and the - other rules are applied on the rest of the occurrence only. + \li If an occurrence and the new text have the same prefix or suffix, + then the case of the prefix and/or suffix are preserved, and the + other rules are applied on the rest of the occurrence only. \endlist @@ -1455,24 +1472,26 @@ \list 1 - \li Press \key Ctrl+Shift+F or select \uicontrol Edit > \uicontrol Find/Replace > - \uicontrol{Advanced Find} > \uicontrol{Open Advanced Find}. + \li Press \key {Ctrl+Shift+F} or select \uicontrol Edit > + \uicontrol {Find/Replace} > \uicontrol {Advanced Find} > + \uicontrol {Open Advanced Find}. \li Select the scope of your search: \list - \li \uicontrol{All Projects} searches files matching the defined file - pattern in all currently open projects. + \li \uicontrol {All Projects} searches files matching the + defined file pattern in all currently open projects. - For example, to search for \tt previewer only in \tt .cpp - and \tt .h files, enter in \uicontrol{File pattern} - \tt *.cpp,*.h. + For example, to search for \c previewer only in \c {.cpp} + and \c {.h} files, enter in \uicontrol {File pattern} + \c {*.cpp,*.h}. \image qtcreator-search-allprojects.png - \li \uicontrol{Current Project} searches files matching the defined - file pattern only in the project you are currently editing. + \li \uicontrol {Current Project} searches files matching the + defined file pattern only in the project you are currently + editing. \li \uicontrol {Files on File System} recursively searches files matching the defined file pattern in the selected directory. @@ -1498,7 +1517,8 @@ \li To go to an occurrence, double-click it. \li To repeat the search after you have made changes to the - listed files, for example, select \uicontrol {Search Again}. + listed files, for example, select + \uicontrol {Search Again}. \endlist @@ -1507,8 +1527,8 @@ The search results are stored in the search history from which you can select earlier searches. - \note You can use \uicontrol{Advanced Find} also to search for symbols. For more - information, see \l{Finding Symbols}. + \note You can use \uicontrol {Advanced Find} also to search for symbols. For + more information, see \l{Finding Symbols}. */ @@ -1547,11 +1567,12 @@ \list - \li \uicontrol {Tools > C++ > Find Usages} + \li \uicontrol Tools > \uicontrol {C++} > \uicontrol {Find Usages} - \li \uicontrol {Tools > QML/JS > Find Usages} + \li \uicontrol Tools > \uicontrol {QML/JS} > + \uicontrol {Find Usages} - \li \key Ctrl+Shift+U + \li \key {Ctrl+Shift+U} \endlist @@ -1568,15 +1589,16 @@ \endlist - \note You can also select \uicontrol{Edit > Find/Replace > Advanced Find > - C++ Symbols} to search for classes, functions, enums, and declarations - either from files listed as part of the project or from all files that - are used by the code, such as include files. + \note You can also select \uicontrol Edit > \uicontrol {Find/Replace} > + \uicontrol {Advanced Find} > \uicontrol {C++ Symbols} to search for + classes, functions, enums, and declarations either from files listed as + part of the project or from all files that are used by the code, such as + include files. \image qtcreator-search-cpp-symbols.png - \li The \uicontrol{Search Results} pane opens and shows the location and - number of instances of the symbol in the current project. + \li The \uicontrol {Search Results} pane opens and shows the location + and number of instances of the symbol in the current project. \image qtcreator-refactoring-find.png @@ -1589,17 +1611,16 @@ \li To go directly to an instance, double-click the instance in the \uicontrol {Search Results} pane. - \li To move between instances, click - \inlineimage qtcreator-forward.png - and - \inlineimage qtcreator-back.png - in the \uicontrol{Search Results} pane. + \li To move between instances, click \inlineimage qtcreator-forward.png + and \inlineimage qtcreator-back.png + in the \uicontrol {Search Results} pane. \li To expand and collapse the list of all instances, click \inlineimage qtcreator-expand.png . - \li To clear the search results, click \inlineimage qtcreator-clear.png + \li To clear the search results, click + \inlineimage qtcreator-clear.png . \endlist @@ -1611,18 +1632,20 @@ \list 1 \li In the editor, place the cursor on the symbol you would like to - change and select \uicontrol Tools > \uicontrol C++ > - \uicontrol{Rename Symbol Under Cursor} or \uicontrol Tools > \uicontrol QML/JS > - \uicontrol{Rename Symbol Under Cursor}. Alternatively, press - \key Ctrl+Shift+R. + change and select \uicontrol Tools > \uicontrol {C++} > + \uicontrol {Rename Symbol Under Cursor} or + \uicontrol Tools > \uicontrol {QML/JS} > + \uicontrol {Rename Symbol Under Cursor}. Alternatively, press + \key {Ctrl+Shift+R}. - The \uicontrol{Search Results} pane opens and shows the location and - number of instances of the symbol in the current project. + The \uicontrol {Search Results} pane opens and shows the location + and number of instances of the symbol in the current project. \image qtcreator-refactoring-replace.png \li To replace all selected instances, enter the name of the new symbol - in the \uicontrol{Replace with} text box and click \uicontrol Replace. + in the \uicontrol {Replace with} text box and click + \uicontrol Replace. To omit an instance, uncheck the check-box next to the instance. @@ -1632,9 +1655,9 @@ \endlist - \note Renaming local symbols does not open the \uicontrol{Search Results} pane. - The instances of the symbol are highlighted in code and you can edit the - symbol. All instances of the local symbol are changed as you type. + \note Renaming local symbols does not open the \uicontrol {Search Results} + pane. The instances of the symbol are highlighted in code and you can edit + the symbol. All instances of the local symbol are changed as you type. \section1 Column Editing @@ -1644,19 +1667,19 @@ \section1 Applying Refactoring Actions - \QC allows you to quickly and conveniently apply actions to refactor - your code by selecting them in a context menu. The actions available depend - on the position of the cursor in the code editor and on whether you are - writing C++ or QML code. + \QC allows you to quickly and conveniently apply actions to refactor your + code by selecting them in a context menu. The actions available depend on + the position of the cursor in the code editor and on whether you are writing + C++ or QML code. To apply refactoring actions to C++ code, right-click an operand, conditional statement, string, or name to open a context menu. In QML code, click an item ID or name. - In the context menu, select \uicontrol {Refactoring} and then select a refactoring - action. + In the context menu, select \uicontrol {Refactoring} and then select a + refactoring action. - You can also press \uicontrol {Alt+Enter} to open a context menu that contains + You can also press \key {Alt+Enter} to open a context menu that contains refactoring actions available in the current cursor position. \section2 Refactoring C++ Code @@ -1690,33 +1713,33 @@ \li Description \li Activation \row - \li Add Curly Braces - \li Adds curly braces to an if statement that does not contain a - compound statement. For example, rewrites + \li Add Curly Braces + \li Adds curly braces to an if statement that does not contain a + compound statement. For example, rewrites \code if (a) b; \endcode - as + as \code if (a) { b; } \endcode - \li if + \li \c if \row - \li Move Declaration out of Condition - \li Moves a declaration out of an if or while condition to simplify the - condition. For example, rewrites + \li Move Declaration out of Condition + \li Moves a declaration out of an if or while condition to simplify + the condition. For example, rewrites \code if (Type name = foo()) {} \endcode - as + as \code Type name = foo; @@ -1724,23 +1747,23 @@ \endcode \li Name of the introduced variable \row - \li Rewrite Condition Using || - \li Rewrites the expression according to De Morgan's laws. For example, - rewrites: + \li Rewrite Condition Using || + \li Rewrites the expression according to De Morgan's laws. For + example, rewrites: \code !a && !b \endcode - as + as \code !(a || b) \endcode - \li && + \li \c && \row - \li Rewrite Using \e operator - \li Rewrites an expression negating it and using the inverse operator. For - example, rewrites: + \li Rewrite Using \e operator + \li Rewrites an expression negating it and using the inverse + operator. For example, rewrites: \list @@ -1748,7 +1771,7 @@ a op b \endcode - as + as \code !(a invop b) @@ -1758,7 +1781,7 @@ (a op b) \endcode - as + as \code !(a invop b) @@ -1768,7 +1791,7 @@ !(a op b) \endcode - as + as \code (a invob b) @@ -1776,16 +1799,16 @@ \endlist - \li <= < > >= == != + \li \c {<=}, \c {<}, \c {>}, \c {>=}, \c {==} or \c {!=} \row - \li Split Declaration - \li Splits a simple declaration into several declarations. For example, - rewrites: + \li Split Declaration + \li Splits a simple declaration into several declarations. For + example, rewrites: \code int *a, b; \endcode - as + as \code int *a; @@ -1793,14 +1816,16 @@ \endcode \li Type name or variable name \row - \li Split if Statement - \li Splits an if statement into several statements. For example, rewrites: + \li Split if Statement + \li Splits an if statement into several statements. For example, + rewrites: + \code if (something && something_else) { } \endcode - as + as \code if (something) { @@ -1809,14 +1834,14 @@ } \endcode - and + and \code if (something || something_else) x; \endcode - with + with \code if (something) @@ -1825,20 +1850,21 @@ x; \endcode - \li && || + \li \c && or \c || \row - \li Swap Operands - \li Rewrites an expression in the inverse order using the inverse operator. - For example, rewrites: + \li Swap Operands + \li Rewrites an expression in the inverse order using the inverse + operator. For example, rewrites: \code a op b \endcode - as + as \code b flipop a \endcode - \li <= < > >= == != && || + \li \c {<=}, \c {<}, \c {>}, \c {>=}, \c {==}, \c {!=}, \c {&&} + or \c {||} \row \li Convert to Decimal \li Converts an integer literal to decimal representation @@ -1852,9 +1878,10 @@ \li Converts an integer literal to octal representation \li Numeric literal \row - \li Convert to Objective-C String Literal - \li Converts a string literal to an Objective-C string literal - if the file type is Objective-C(++). For example, rewrites the following strings + \li Convert to Objective-C String Literal + \li Converts a string literal to an Objective-C string literal if + the file type is Objective-C(++). For example, rewrites the + following strings \code "abcd" @@ -1862,38 +1889,39 @@ QLatin1Literal("abcd") \endcode - as + as \code @"abcd" \endcode \li String literal \row - \li Enclose in QLatin1Char() - \li Sets the encoding for a character to Latin-1, unless the character is - already enclosed in QLatin1Char, QT_TRANSLATE_NOOP, tr, trUtf8, - QLatin1Literal, or QLatin1String. For example, rewrites + \li Enclose in QLatin1Char() + \li Sets the encoding for a character to Latin-1, unless the + character is already enclosed in QLatin1Char, QT_TRANSLATE_NOOP, + tr, trUtf8, QLatin1Literal, or QLatin1String. For example, + rewrites \code 'a' \endcode - as + as \code QLatin1Char('a') \endcode \li String literal \row - \li Enclose in QLatin1String() - \li Sets the encoding for a string to Latin-1, unless the string is - already enclosed in QLatin1Char, QT_TRANSLATE_NOOP, tr, trUtf8, - QLatin1Literal, or QLatin1String. For example, rewrites + \li Enclose in QLatin1String() + \li Sets the encoding for a string to Latin-1, unless the string is + already enclosed in QLatin1Char, QT_TRANSLATE_NOOP, tr, trUtf8, + QLatin1Literal, or QLatin1String. For example, rewrites \code "abcd" \endcode - as + as \code QLatin1String("abcd") @@ -1902,9 +1930,10 @@ \li String literal \row - \li Mark as Translatable - \li Marks a string translatable. For example, rewrites \c "abcd" with - one of the following options, depending on which of them is available: + \li Mark as Translatable + \li Marks a string translatable. For example, rewrites \c "abcd" + with one of the following options, depending on which of them is + available: \code tr("abcd") @@ -1915,12 +1944,15 @@ \li String literal \row - \li Add Definition in ... - \li Inserts a definition stub for a function declaration either in the header file - (inside or outside the class) or in the implementation file. For free functions, inserts - the definition after the declaration of the function or in the implementation file. - Qualified names are minimized when possible, instead of always being fully expanded. - For example, rewrites + \li Add Definition in ... + \li Inserts a definition stub for a function declaration either in + the header file (inside or outside the class) or in the + implementation file. For free functions, inserts the definition + after the declaration of the function or in the implementation + file. Qualified names are minimized when possible, instead of + always being fully expanded. + + For example, rewrites \code Class Foo { @@ -1928,7 +1960,7 @@ }; \endcode - as (inside class) + as (inside class) \code Class Foo { @@ -1938,7 +1970,7 @@ }; \endcode - as (outside class) + as (outside class) \code Class Foo { @@ -1951,7 +1983,7 @@ } \endcode - as (in implementation file) + as (in implementation file) \code // Header file @@ -1968,68 +2000,72 @@ \li Function name \row - \li Add 'Function' Declaration - \li Inserts the member function declaration that matches the member function - definition into the class declaration. The function can be public, - protected, private, public slot, protected slot, or private slot. - \li Function name + \li Add \c Function Declaration + \li Inserts the member function declaration that matches the member + function definition into the class declaration. The function can + be \c {public}, \c {protected}, \c {private}, \c {public slot}, + \c {protected slot}, or \c {private slot}. + \li Function name \row \li Switch with Next/Previous Parameter \li Moves a parameter down or up one position in a parameter list. \li Parameter in the declaration or definition of a function \row - \li Extract Function - \li Moves the selected code to a new function and replaces the block of - code with a call to the new function. Enter a name for the function in - the \uicontrol {Extract Function Refactoring} dialog. - \li Block of code selected + \li Extract Function + \li Moves the selected code to a new function and replaces the block + of code with a call to the new function. Enter a name for the + function in the \uicontrol {Extract Function Refactoring} + dialog. + \li Block of code selected \row - \li Extract Constant as Function Parameter - \li Replaces the selected literal and all its occurrences with the function parameter - \c{newParameter}. The parameter \c{newParameter} will have the original literal as the - default value. - \li Block of code selected + \li Extract Constant as Function Parameter + \li Replaces the selected literal and all its occurrences with the + function parameter \c{newParameter}. The parameter + \c{newParameter} will have the original literal as the default + value. + \li Block of code selected \row - \li Add Local Declaration - \li - Adds the type of an assignee, if the type of the right-hand side of the assignment - is known. For example, rewrites + \li Add Local Declaration + \li Adds the type of an assignee, if the type of the right-hand + side of the assignment is known. For example, rewrites \code a = foo(); \endcode - as + as \code Type a = foo(); \endcode - where Type is the return type of \c {foo()} + where Type is the return type of \c {foo()} \li Assignee \row - \li Convert to Camel Case - \li Converts a symbol name to camel case, where elements of the name are joined - without delimiter characters and the initial character of each element is - capitalized. For example, rewrites \c an_example_symbol - as \c anExampleSymbol and \c AN_EXAMPLE_SYMBOL as \c AnExampleSymbol - \li Identifier + \li Convert to Camel Case + \li Converts a symbol name to camel case, where elements of the name + are joined without delimiter characters and the initial + character of each element is capitalized. For example, rewrites + \c an_example_symbol as \c anExampleSymbol and + \c AN_EXAMPLE_SYMBOL as \c AnExampleSymbol + \li Identifier \row - \li Complete Switch Statement - \li Adds all possible cases to a switch statement of the type \c enum - \li Switch + \li Complete Switch Statement + \li Adds all possible cases to a switch statement of the type + \c enum + \li \c switch \row - \li Generate Missing Q_PROPERTY Members - \li Adds missing members to a Q_PROPERTY: + \li Generate Missing Q_PROPERTY Members + \li Adds missing members to a \c Q_PROPERTY: \list \li \c read function \li \c write function, if there is a WRITE \li \c {onChanged} signal, if there is a NOTIFY \li data member with the name \c {m_} \endlist - \li Q_PROPERTY + \li \c Q_PROPERTY \row \li Apply Changes \li Keeps function declarations and definitions synchronized by @@ -2037,44 +2073,45 @@ edit a function signature and by applying the changes to the matching code. \li Function signature. When this action is available, a light bulb - icon appears: - \inlineimage qml-toolbar-indicator.png + icon appears: \inlineimage qml-toolbar-indicator.png \row \li Add #include for undeclared or forward declared identifier - \li Adds an #include directive to the current file to make the + \li Adds an \c {#include} directive to the current file to make the definition of a symbol available. \li Undeclared identifier \row \li Reformat Pointers or References \li Reformats declarations with pointers or references according - to the code style settings for the current project. In case no - project is open, the current global code style settings are used. - For example, rewrites: + to the code style settings for the current project. In case no + project is open, the current global code style settings are + used. + + For example, rewrites: \code char*s; \endcode - as + as \code char *s; \endcode - When applied to selections, all suitable declarations in the selection are - rewritten. + When applied to selections, all suitable declarations in the + selection are rewritten. \li Declarations with pointers or references and selections - containing such declarations + containing such declarations \row - \li Create Getter and Setter Member Functions - \li Creates either both getter and setter member functions for member variables or - only a getter or setter. - \li Member variable in class definition + \li Create Getter and Setter Member Functions + \li Creates either both getter and setter member functions for + member variables or only a getter or setter. + \li Member variable in class definition \row \li Move Function Definition - \li Moves a function definition to the implementation file, outside the class or back to its declaration. For example, rewrites: - + \li Moves a function definition to the implementation file, outside + the class or back to its declaration. For example, rewrites: \code class Foo { @@ -2085,7 +2122,7 @@ }; \endcode - as + as \code class Foo { @@ -2100,8 +2137,8 @@ \li Function signature \row \li Move All Function Definitions - \li Moves all function definitions to the implementation file or outside the class. For example, rewrites: - + \li Moves all function definitions to the implementation file or + outside the class. For example, rewrites: \code class Foo { @@ -2116,7 +2153,8 @@ }; \endcode - as + as + \code class Foo { @@ -2136,22 +2174,29 @@ \li Class name \row \li Assign to Local Variable - \li Adds a local variable which stores the return value of a function call or a new expression. For example, rewrites: + \li Adds a local variable which stores the return value of a + function call or a new expression. For example, rewrites: \code QString s; s.loLatin1(); \endcode - as + + as + \code QString s; QByteArray latin1 = s.toLatin1(); \endcode - and + + and + \code new Foo; \endcode - as + + as + \code Foo * localFoo = new Foo; \endcode @@ -2172,83 +2217,97 @@ \li Class or base class name \row \li Optimize for-Loop - \li Rewrites post increment operators as pre increment operators and post decrement - operators as pre decrement operators. It also moves other than string or numeric - literals and id expressions from the condition of a for loop to its initializer. - For example, rewrites: + \li Rewrites post increment operators as pre increment operators and + post decrement operators as pre decrement operators. It also + moves other than string or numeric literals and id expressions + from the condition of a for loop to its initializer. For + example, rewrites: \code for (int i = 0; i < 3 * 2; i++) \endcode - as + + as + \code for (int i = 0, total = 3 * 2; i < total; ++i) \endcode - \li for + \li \c for \row \li Escape String Literal as UTF-8 - \li Escapes non-ASCII characters in a string literal to hexadecimal escape sequences. - String Literals are handled as UTF-8. + \li Escapes non-ASCII characters in a string literal to hexadecimal + escape sequences. String Literals are handled as UTF-8. \li String literal \row \li Unescape String Literal as UTF-8 - \li Unescapes octal or hexadecimal escape sequences in a string literal. - String Literals are handled as UTF-8. + \li Unescapes octal or hexadecimal escape sequences in a string + literal. String Literals are handled as UTF-8. \li String literal \row \li Convert to Stack Variable - \li Converts the selected pointer to a stack variable. For example, rewrites: + \li Converts the selected pointer to a stack variable. For example, + rewrites: + \code QByteArray *foo = new QByteArray("foo"); foo->append("bar"); \endcode - as + + as + \code QByteArray foo = "foo"; foo.append("bar"); \endcode - This operation is limited to work only within function scope. - Also, the coding style for pointers and references is not respected yet. + + This operation is limited to work only within function scope. + Also, the coding style for pointers and references is not + respected yet. \li Pointer Variable \row \li Convert to Pointer - \li Converts the selected stack variable to a pointer. For example, rewrites: + \li Converts the selected stack variable to a pointer. For example, + rewrites: + \code QByteArray foo = "foo"; foo.append("bar"); \endcode - as + + as + \code QByteArray *foo = new QByteArray("foo"); foo->append("bar"); \endcode - This operation is limited to work only within function scope. - Also, the coding style for pointers and references is not respected yet. + + This operation is limited to work only within function scope. + Also, the coding style for pointers and references is not + respected yet. \li Stack Variable - \row - \li Convert connect() to Qt 5 Style - \li Converts a Qt 4 \c QObject::connect() to Qt 5 style. - \li \c QObject::connect() (Qt 4 style) + \row + \li Convert connect() to Qt 5 Style + \li Converts a Qt 4 QObject::connect() to Qt 5 style. + \li QObject::connect() (Qt 4 style) \endtable - \section2 Refactoring QML Code + \section2 Refactoring QML Code - You can apply the following types of refactoring actions to QML code: + You can apply the following types of refactoring actions to QML code: - \list + \list \li Rename IDs \li Split initializers - \li Move a QML type into a separate file to reuse it in other - .qml files + \li Move a QML type into a separate file to reuse it in other .qml files - \endlist + \endlist The following table summarizes the refactoring actions for QML code. The action is available when the cursor is in the position described in the @@ -2261,18 +2320,19 @@ \li Activation \row - \li Move Component into 'filename.qml' + \li Move Component into \c filename.qml \li Moves a QML type into a separate file \li QML type name \row - \li Split Initializer - \li Reformats a one-line type into a multi-line type. For example, - rewrites + \li Split Initializer + \li Reformats a one-line type into a multi-line type. For example, + rewrites + \code Item { x: 10; y: 20; width: 10 } \endcode - as + as \code Item { @@ -2284,15 +2344,15 @@ \li QML type property \row - \li Wrap in Loader - \li Wraps the type in a Component type and loads it dynamically in - a Loader type. This is usually done to improve startup time. - \li QML type name + \li Wrap in Loader + \li Wraps the type in a Component type and loads it dynamically in a + Loader type. This is usually done to improve startup time. + \li QML type name \row - \li Add a message suppression comment - \li Prepends the line with an annotation comment that stops the message - from being generated. - \li Error, warning or hint from static analysis + \li Add a message suppression comment + \li Prepends the line with an annotation comment that stops the + message from being generated. + \li Error, warning or hint from static analysis \endtable */ @@ -2314,7 +2374,7 @@ \list - \li Press \key Ctrl+K (\key Cmd+K on OS X). + \li Press \key {Ctrl+K} (\key {Cmd+K} on OS X). \li Select \uicontrol Tools > \uicontrol Locate. @@ -2329,15 +2389,15 @@ \list 1 - \li Activate the locator by pressing \key Ctrl+K. + \li Activate the locator by pressing \key {Ctrl+K}. - \li Enter \tt{main.cpp}. + \li Enter \c {main.cpp}. \image qtcreator-locator-open.png \li Press \key Enter. - The main.cpp file opens in the editor. + The \c {main.cpp} file opens in the editor. \li To move to a line in the file, enter the line number in the locator. @@ -2360,9 +2420,9 @@ \list - \li To match any number of any or no characters, enter \b{*}. + \li To match any number of any or no characters, enter \c{*}. - \li To match a single instance of any character, enter \b{?}. + \li To match a single instance of any character, enter \c{?}. \endlist @@ -2373,32 +2433,32 @@ \list - \li Locating any open document (o) + \li Locating any open document (\c {o}) - \li Locating files anywhere on your file system (f) + \li Locating files anywhere on your file system (\c {f}) - \li Locating files belonging to your project (p), such as source, header - resource, and .ui files, or to any project (a) + \li Locating files belonging to your project (\c {p}), such as source, + header resource, and \c {.ui} files, or to any project (\c {a}) - \li Locating class (c), enum, and function (m) definitions in your - project or anywhere referenced from your project (:) + \li Locating class (\c {c}), enum, and function (m) definitions in your + project or anywhere referenced from your project (\c {:}) - \li Locating symbols in the current document (.) + \li Locating symbols in the current document (\c {.}) \li Locating a specific line and column in the document displayed in - your editor (l) + your editor (\c {l}) - \li Opening help topics, including Qt documentation (?) + \li Opening help topics, including Qt documentation (\c {?}) - \li Performing web searches (r) + \li Performing web searches (\c {r}) - \li Running text editing macros that you record and save (rm). For more - information, see \l{Using Text Editing Macros} + \li Running text editing macros that you record and save (\c {rm}). For + more information, see \l{Using Text Editing Macros} - \li Executing shell commands (!) + \li Executing shell commands (\c {!}) - \li Executing version control system commands (git). For more information, see - \l{Using Version Control Systems} + \li Executing version control system commands (\c {git}). For more + information, see \l{Using Version Control Systems} \endlist @@ -2412,7 +2472,7 @@ \li Activate the locator. - \li Enter \tt{\b{: QDataStream}} (: (colon) followed by a + \li Enter \c{: QDataStream} (\c{:} (colon) followed by a \key Space and the symbol name (QDataStream)). The locator lists the results. @@ -2434,16 +2494,16 @@ \list - \li Going to a line and column in the current file (l). + \li Going to a line and column in the current file (\c {l}). - \li Going to an open file (o). + \li Going to an open file (\c {o}). - \li Going to a file in any open project (a). + \li Going to a file in any open project (\c {a}). \endlist If locator does not find some files, you can add them to the \c DISTFILES - variable in the .pro file to include them into the distribution tarball + variable in the \c .pro file to include them into the distribution tarball of your project and thus make them known to \QC as well. \section1 Configuring Locator Filters @@ -2457,8 +2517,8 @@ \list 1 \li In the locator, click \inlineimage qtcreator-locator-magnify.png - (\uicontrol {Options}) and select \uicontrol Configure to open the \uicontrol Locator - options. + (\uicontrol Options) and select \uicontrol Configure to open the + \uicontrol Locator options. \li Select a filter, and then select \uicontrol Edit. @@ -2474,7 +2534,7 @@ \section2 Adding Web Search Engines - You can use the \uicontrol {Web Search (\c r)} locator filter to perform + You can use the \uicontrol {Web Search (r)} locator filter to perform web searches. URLs and search commands for Bing, Google, Yahoo! Search, cplusplus.com, and Wikipedia are configured by default. @@ -2487,16 +2547,16 @@ \list 1 - \li Select \uicontrol {Tools > Options > Environment > Locator > - Web Search (prefix: r) > - Edit}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol Environment > \uicontrol Locator > + \uicontrol {Web Search (prefix: r)} > \uicontrol Edit. \li Select \uicontrol Add to add a new entry to the list. \image qtcreator-add-online-doc.png "Filter Configuration dialog" \li Double-click the new entry to specify a URL and a search command. - For example, http://www.google.com/search?q=%1. + For example, \c {http://www.google.com/search?q=%1}. \li Click \uicontrol OK. @@ -2512,8 +2572,8 @@ \list 1 - \li In the locator, select \uicontrol {Options > Configure} to open the - \uicontrol Locator options. + \li In the locator, select \uicontrol Options > + \uicontrol Configure to open the \uicontrol Locator options. \image qtcreator-locator-customize.png @@ -2529,7 +2589,7 @@ recursively. \li Define the file pattern as a comma separated list. For example, - to search all .h and .cpp files, enter \b{*.h,*.cpp} + to search all \c {.h} and \c {.cpp} files, enter \c{*.h,*.cpp} \li Specify the prefix string. @@ -2540,29 +2600,29 @@ \endlist - \li Click OK. + \li Click \uicontrol OK. \endlist \section1 Configuring Locator Cache - The locator searches the files matching your file pattern in the - directories you have selected and caches that information. The cache for - all default filters is updated as you write your code. By default, - \QC updates the filters created by you once an hour. + The locator searches the files matching your file pattern in the directories + you have selected and caches that information. The cache for all default + filters is updated as you write your code. By default, \QC updates the + filters created by you once an hour. - To update the cached information manually, select \uicontrol {Options > Refresh} - in the locator. + To update the cached information manually, select \uicontrol Options > + \uicontrol Refresh in the locator. To set a new cache update time: \list 1 - \li Select \uicontrol {Tools > Options > Environment > Locator}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol Environment > \uicontrol Locator. \li In \uicontrol {Refresh interval}, define new time in minutes. \endlist */ - diff --git a/doc/src/overview/creator-tutorials.qdoc b/doc/src/overview/creator-tutorials.qdoc index e14391bf8c3..3ad43aa4fbc 100644 --- a/doc/src/overview/creator-tutorials.qdoc +++ b/doc/src/overview/creator-tutorials.qdoc @@ -26,7 +26,7 @@ \contentspage {Qt Creator Manual} \previouspage creator-build-example-application.html \page creator-tutorials.html - \nextpage creator-qml-application.html + \nextpage {Creating a Qt Quick Application} \title Tutorials @@ -51,6 +51,14 @@ Learn how to create a Qt Quick application using Qt Quick Controls for Android and iOS devices. + \li \l{Using Qt Quick UI Forms} + + Learn how to develop a Qt Quick application by using UI forms. + UI forms are split into \e .qml and \e .js files that contain the + business logic, and \e .ui.qml files that only contain the purely + declarative description of the UI. Note that some of the described + features are only available in the commercial version of \QC. + \endlist */ diff --git a/doc/src/projects/creator-projects-overview.qdoc b/doc/src/projects/creator-projects-overview.qdoc index 013243fccca..e7751703dbf 100644 --- a/doc/src/projects/creator-projects-overview.qdoc +++ b/doc/src/projects/creator-projects-overview.qdoc @@ -24,7 +24,7 @@ /*! \contentspage {Qt Creator Manual} - \previouspage creator-mobile-app-tutorial.html + \previouspage {Using Qt Quick UI Forms} \page creator-project-managing.html \nextpage creator-project-creating.html diff --git a/doc/src/qtcreator.qdoc b/doc/src/qtcreator.qdoc index 9b2c51c174c..d1917e537e6 100644 --- a/doc/src/qtcreator.qdoc +++ b/doc/src/qtcreator.qdoc @@ -139,6 +139,7 @@ \li \l{Creating a Qt Quick Application} \li \l{Creating a Qt Widget Based Application} \li \l{Creating a Mobile Application} + \li \l{Using Qt Quick UI Forms} \endlist \endlist \li \l{Managing Projects} diff --git a/doc/src/qtquick/creator-mobile-app-tutorial.qdoc b/doc/src/qtquick/creator-mobile-app-tutorial.qdoc index 56f84210f8b..2110e822d58 100644 --- a/doc/src/qtquick/creator-mobile-app-tutorial.qdoc +++ b/doc/src/qtquick/creator-mobile-app-tutorial.qdoc @@ -25,8 +25,8 @@ /*! \contentspage {Qt Creator Manual} \previouspage creator-writing-program.html - \page creator-mobile-app-tutorial.html - \nextpage creator-project-managing.html + \example accelbubble + \nextpage {Using Qt Quick UI Forms} \title Creating a Mobile Application @@ -61,17 +61,23 @@ \list 1 - \li Select \uicontrol File > \uicontrol {New File or Project} > \uicontrol Application > - \uicontrol {Qt Quick Application} > \uicontrol Choose. + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol Application > \uicontrol {Qt Quick Controls Application} + > \uicontrol Choose. - \li In the \uicontrol{Name} field, type \b{accelbubble}. + \li In the \uicontrol Name field, type \e {accelbubble}. - \li In the \uicontrol {Create in} field, enter the path for the project files. - For example, \c {C:\Qt\examples}, and then click \uicontrol{Next} (or - \uicontrol Continue on OS X). + \li In the \uicontrol {Create in} field, enter the path for the project + files, and then click \uicontrol Next (or \uicontrol Continue on + OS X). - \li In the \uicontrol {Qt Quick component set} field, select - \uicontrol {Qt Quick Controls 1.1}. + \li In the \uicontrol {Minimal required Qt version} field, select the Qt + version to develop with. + + \note This page determines the set of files that the wizard + generates and their contents. The instructions in this tutorial + might not apply if you select the \uicontrol {With .ui.qml file} + check box. \li Select \l{glossary-buildandrun-kit}{kits} for Android ARM and iPhone OS, and click \uicontrol{Next}. @@ -97,11 +103,8 @@ The main view of the application displays an SVG bubble image at the center of the main window. - To use the Bluebubble.svg used by the Qt Sensors example, Accel Bubble, in - your project, you must copy it to the project directory (same subdirectory - as the QML file) from the examples directory in the Qt installation - directory. For example: - \c {C:\Qt\Qt5.2.0\5.2.0\msvc2010\examples\sensors\accelbubble\content}. + To use \l{accelbubble/Bluebubble.svg}{Bluebubble.svg} in your project, + copy it to the project directory (same subdirectory as the QML file). The image appears in \uicontrol Resources. You can also use any other image or a QML type, instead. @@ -110,20 +113,21 @@ \li In the \uicontrol Projects view, double-click the main.qml file to open it in the code editor. - \li Modify the properties of the ApplicationWindow type to specify the - application name, give the ApplicationWindow an id, and to set it - visible, as illustrated by the following code snippet: - - \quotefromfile accelbubble/main.qml - \skipto ApplicationWindow - \printuntil visible - \skipto /^\}/ - \printuntil } - \li Click \uicontrol Design to open the file in \QMLD. - \li In the \uicontrol Navigator, select \uicontrol Label and press \key Delete - to delete it. + \li In the \uicontrol Navigator, select \uicontrol Label and press + \key Delete to delete it. + + \li Select \uicontrol ApplicationWindow to edit its properties. + + \list a + + \li In the \uicontrol Id field, enter \e mainWindow, to be able to + reference the window from other places. + + \li In the \uicontrol Title field, type \e {Accelerate Bubble}. + + \endlist \li In \uicontrol Library > \uicontrol Resources, select Bluebubble.svg and drag and drop it to the canvas. @@ -132,34 +136,23 @@ able to reference the image from other places. \li In the code editor, add the following new properties to the image to - position the image at the center of ApplicationWindow when the + position the image at the center of the application window when the application starts: \quotefromfile accelbubble/main.qml \skipto Image \printuntil bubble.width - \li Set the x and y position of the image based on the new - properties: + \li Set the x and y position of the image based on the new properties: \dots \printuntil centerY \skipto /^\}/ \printuntil } + \endlist - Here is how the accelbubble.qml file looks after you made the changes: - - \quotefromfile accelbubble/main.qml - \skipto import QtQuick - \printuntil 1.1 - \codeline - \skipto ApplicationWindow - \printuntil true - \skipto Image - \printuntil y: - \skipto /^\}/ - \printuntil } + For an example, see \l{accelbubble/main.qml}{main.qml}. \section1 Moving the Bubble @@ -275,19 +268,11 @@ If you are using a device running Android v4.2.2, it should prompt you to verify the connection to allow USB debugging from the PC it is connected - to. To avoid such prompts every time you connect the device, check - "Always allow from the computer" and select \uicontrol OK. + to. To avoid such prompts every time you connect the device, select the + \uicontrol {Always allow from the computer} check box, and then select + \uicontrol OK. \li To run the application on the device, press \key {Ctrl+R}. \endlist - - \section1 Example Code - - When you have completed the steps, the main.qml file should look as follows: - - \quotefromfile accelbubble/main.qml - \skipto import - \printuntil /^\}/ - */ diff --git a/doc/src/qtquick/qtquick-app-tutorial.qdoc b/doc/src/qtquick/qtquick-app-tutorial.qdoc index 204ce69bdae..f6c24cfe7da 100644 --- a/doc/src/qtquick/qtquick-app-tutorial.qdoc +++ b/doc/src/qtquick/qtquick-app-tutorial.qdoc @@ -25,7 +25,7 @@ /*! \contentspage {Qt Creator Manual} \previouspage creator-tutorials.html - \page creator-qml-application.html + \example transitions \nextpage creator-writing-program.html \title Creating a Qt Quick Application @@ -43,6 +43,9 @@ For more information about using \QMLD, see \l{Developing Qt Quick Applications}. + For tutorials that describe using Qt Quick Controls, see + \l{Qt Quick Text Editor Guide} and \l{Qt Quick Controls - UI Forms}. + \section1 Creating the Project \list 1 @@ -50,20 +53,19 @@ \li Select \uicontrol{File > New File or Project > Application > Qt Quick Application > Choose}. - \li In the \uicontrol{Name} field, type \b {Transitions}. + \li In the \uicontrol{Name} field, type \e {Transitions}. \li In the \uicontrol {Create in} field, enter the path for the project files. For example, \c {C:\Qt\examples}, and then click \uicontrol{Next} (on Windows and Linux) or \uicontrol Continue (on OS X). - \li In the \uicontrol {Qt Quick component set} field, select - \uicontrol {Qt Quick 2.1}. + \li In the \uicontrol {Minimal required Qt version} field, select the Qt + version to develop with. - \note This selection determines the set of files that the wizard + \note This page determines the set of files that the wizard generates and their contents. The instructions in this tutorial - might not apply if you select some other component set, such as Qt - Quick 2.4. The wizard indicates which Qt version each component set - requires at minimum. + might not apply if you select the \uicontrol {With .ui.qml file} + check box. \li Select \l{glossary-buildandrun-kit}{kits} for running and building your project, and then click \uicontrol{Next}. @@ -93,7 +95,7 @@ The main view of the application displays a Qt logo in the top left corner of the screen and two empty rectangles. - To use the states.png image in your application, you must copy it to the + To use the states.svg image in your application, you must copy it to the project directory (same subdirectory as the QML file) from the examples directory in the Qt installation directory. For example: \c {C:\Qt\Examples\Qt-5.4\declarative\animation\states}. The image appears @@ -109,10 +111,10 @@ \image qmldesigner-tutorial-design-mode.png "Transitions project in Design Mode" - \li In the \uicontrol Navigator, select \uicontrol MouseArea and - \uicontrol Text and press \key Delete to delete them. + \li In the \uicontrol Navigator, select \uicontrol Label and press + \key Delete to delete it. - \li Select \uicontrol Window to edit its properties. + \li Select \uicontrol ApplicationWindow to edit its properties. \image qmldesigner-tutorial-page.png "Page properties" @@ -121,12 +123,17 @@ \li In the \uicontrol Id field, enter \e page, to be able to reference the window from other places. + \li In the \uicontrol Title field, type \e Transitions. + + \li In the \uicontrol Size field, set \uicontrol W and \uicontrol H + to \e 330. + \li In the \uicontrol Color field, set the window background color - to #343434. + to \e #343434. \endlist - \li In \uicontrol Library > \uicontrol Resources, select states.png and + \li In \uicontrol Library > \uicontrol Resources, select states.svg and drag and drop it to the canvas. \image qmldesigner-tutorial-user-icon.png "Image properties" @@ -135,15 +142,17 @@ \li In the \uicontrol Id field, enter \e icon. - \li In the \uicontrol Position field, set \uicontrol X to 10 and \uicontrol Y to 20. + \li In the \uicontrol Position field, set \uicontrol X to \e 10 and + \uicontrol Y to \e 20. \endlist \li Right-click the resource file, qml.qrc, in the \uicontrol Projects - view, and select \uicontrol {Open in Editor} to add states.png to + view, and select \uicontrol {Open in Editor} to add states.svg to the resource file for deployment. - \li Click \uicontrol Add and select states.png. + \li Click \uicontrol Add > \uicontrol {Add File} and select + \e states.svg. \li In the \uicontrol Design mode, \uicontrol Library view, \uicontrol {QML Types} tab, select \uicontrol Rectangle, @@ -155,26 +164,21 @@ \li In the \uicontrol Id field, enter \e topLeftRect. - \li In the \uicontrol Size field, set \uicontrol W and \uicontrol H to 64, for the - rectangle size to match the image size. + \li In the \uicontrol Size field, set \uicontrol W and \uicontrol H + to \e 44, for the rectangle size to match the image size. \li In the \uicontrol Color field, click the \inlineimage qmldesigner-transparent-button.png (\uicontrol Transparent) button to make the rectangle transparent. - \li In the \uicontrol Border field, set the border color to #808080. + \li In the \uicontrol Border field, set the border color to + \e #808080. \li In the \uicontrol Rectangle group, \uicontrol Border field, set the border - width to 1. + width to \e 1. - \note If the \uicontrol Border field does not appear after you set the - border color, try setting the border color to solid by clicking - the - \inlineimage qmldesigner-solid-color-button.png - (\uicontrol {Solid Color}) button. - - \li In the \uicontrol Radius field, select 6 to create rounded corners for - the rectangle. + \li In the \uicontrol Radius field, select \e 6 to create rounded + corners for the rectangle. \li Click \uicontrol {Layout}, and then click the top and left anchor buttons to anchor the rectangle to the top left corner of the @@ -182,8 +186,8 @@ \image qmldesigner-tutorial-topleftrect-layout.png "Layout tab" - \li In the \uicontrol Margin field, select 20 for the top anchor and 10 - for the left anchor. + \li In the \uicontrol Margin field, select \e 20 for the top anchor + and \e 10 for the left anchor. \endlist @@ -235,8 +239,8 @@ then the right anchor button to anchor the rectangle to the middle right margin of the screen. - \li In the \uicontrol Margin field, select 10 for the right anchor and 0 - for the vertical center anchor. + \li In the \uicontrol Margin field, select \e 10 for the right + anchor and \e 0 for the vertical center anchor. \li In the code editor, add a pointer to a clicked expression to the mouse area. The following expression sets the state to @@ -257,8 +261,8 @@ \li In \uicontrol {Layout}, select the bottom and left anchor buttons to anchor the rectangle to the bottom left margin of the screen. - \li In the \uicontrol Margin field, select 20 for the bottom anchor and 10 - for the left anchor. + \li In the \uicontrol Margin field, select \e 20 for the bottom + anchor and \e 10 for the left anchor. \li In the code editor, add a pointer to a clicked expression to the mouse area. The following expression sets the state to @@ -370,13 +374,4 @@ \endlist Click the rectangles to view the animated transitions. - - \section1 Example Code - - When you have completed the steps, the main.qml file should look as follows: - - \quotefromfile transitions/main.qml - \skipto Window { - \printuntil /^\}/ - */ diff --git a/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc b/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc new file mode 100644 index 00000000000..39e01d0b7a2 --- /dev/null +++ b/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc @@ -0,0 +1,516 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator +** +** +** GNU Free Documentation License +** +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of this +** file. +** +** +****************************************************************************/ +/*! + \contentspage {Qt Creator Manual} + \previouspage {Creating a Mobile Application} + \example uiforms + \nextpage creator-project-managing.html + + \title Using Qt Quick UI Forms + + \commercial + + This tutorial describes how to develop an application that uses \e ui.qml + files to separate the application logic from the UI. The tutorial uses \QMLD + to implement a simplified version of the \l{Qt Quick Controls - UI Forms} + {UI Forms example}, which provides an interface to a customer database and + is purely written in QML and JavaScript. + + \note Some of the described features are only available in the commercial + version of \QC. + + \image qmldesigner-uiforms-example.png + + \e {UI forms} consist of \e .qml and \e .js files that implement the + business logic, and corresponding \e .ui.qml files that only contain the + purely declarative description of the UI. The \e .ui.qml files should be + edited only in the \uicontrol Design mode of \QC. However, \QMLD does not + fully support all QML controls, such as the TableView, so you sometimes need + to edit UI forms also in the \uicontrol Edit mode. You can keep this to the + minimum by creating custom QML types that you edit in the \uicontrol Edit + mode. + + \section1 Creating the UI Forms Project + + \list 1 + + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol Application > \uicontrol {Qt Quick Controls Application} + > \uicontrol Choose. + + \li In the \uicontrol Name field, type \b uiforms. + + \li In the \uicontrol {Create in} field, enter the path for the project + files and then click \uicontrol Next (or \uicontrol Continue on + OS X). + + \li In the \uicontrol {Minimal required Qt version} field, select + \uicontrol {Qt 5.4}, or later. + + \li Select \l{glossary-buildandrun-kit}{kits} for your project and click + \uicontrol{Next}. + + \note Kits are listed if they have been specified in + \uicontrol Tools > \uicontrol Options > \uicontrol {Build & Run} > + \uicontrol Kits (on Windows and Linux) or in \uicontrol {Qt Creator} + > \uicontrol Preferences \uicontrol {Build & Run} > \uicontrol Kits + (on OS X). + + \li Review the project settings, and click \uicontrol Finish (or + \uicontrol Done on OS X). + + \endlist + + \QC generates a default UI file, \e MainForm.ui.qml, that you can modify to + create the main view of the application. + + \section1 Creating the UI Forms Main View + + The main view of the application displays a customer list in a table view + and detailed information about the selected customer in a tab view. + + \image qmldesigner-uiforms-example-main-view.png + + To create the main view: + + \list 1 + + \li In the \uicontrol Projects view (1), double-click the + \e MainForm.ui.qml file to open it in \QMLD. + + \li In the \uicontrol Navigator (2), select the \uicontrol RowLayout and + press \key Delete to delete it. + + \li In \uicontrol Library > \uicontrol {QML Types} (3), select + \uicontrol SplitView and drag and drop it to the \uicontrol Item in + the navigator. + + \li Select the split view in the navigator, then select the + \uicontrol Layout tab in \uicontrol Properties (4), and then click + the \inlineimage qmldesigner-anchor-fill-screen.png + (\uicontrol {Fill to Parent}) button to anchor the split view to the + item. + + \li Drag and drop a \uicontrol TableView and a \uicontrol {Tab View} + from the library to the split view in the navigator. + + \li Select the \inlineimage qmldesigner-export-item-button.png + (\uicontrol Export) button in the navigator to export the table view + as a property. + + \li Right-click \uicontrol TabView to open the context menu and select + \uicontrol {Add Tab} to create a Tab element. + + \QC creates the element as a separate QML file with the name that + you enter in the dialog. By default, the element is called + \uicontrol Tab. + + \li Select the tab in the navigator and enter \b {Customer Settings} in + the \uicontrol Title field in the properties. + + \li Press \key Ctrl+C to copy the tab to the clipboard, and then press + \key Ctrl+V twice to create two more tabs that you name + \b {Customer Notes} and \b {Customer History}. \QC uses the \l Tab + type in the \e MainForm.ui.qml file. You will create separate UI + forms for the tab contents later. + + \endlist + + \section2 Editing the Table View + + \QMLD does not support adding columns to TableView types, and therefore, you + must use the code editor to add them. To keep editing the \e MainForm.ui.qml + file in the \uicontrol Edit mode to the minimum, move the TableView type to + a separate QML file called \e CustomerTableView.qml: + + \list 1 + + \li Click \uicontrol Edit to open \e MainForm.ui.qml in \uicontrol Edit + mode. + + \li To move the TableView type to a separate QML file, right-click it + and select \uicontrol Refactoring > + \uicontrol {Move Component into Separate File}. + + \li Add the code from the \l {uiforms/CustomerTableView.qml} + {CustomerTableView.qml} example file to the file that \QC creates + for you. + + \endlist + + \section1 Implementing the Application Logic for the Main View + + The new project wizard adds boilerplate code to the \e main.qml file to + create menu items and push buttons. Modify the boilerplate code by removing + obsolete code and by adding new code. You removed the push buttons from the + UI Form, so you also need to remove the corresponding code from + \e main.qml (or the application cannot be built). + + You will want to keep the dialog box and menu bar, but change their + contents, as instructed later. + + Edit the \e main.qml file in the code editor, as described in the following + sections. + + \section2 Specifying Main View Size + + The wizard creates an ApplicationWindow type and a MainForm type that + specify the application main view. Enter the application name as the + value of the \c title property. + + Clean up the MainForm code by removing the obsolete lines that call + functions when buttons are clicked: + + \badcode + MainForm { + anchors.fill: parent + button1.onClicked: messageDialog.show(qsTr("Button 1 pressed")) + button2.onClicked: messageDialog.show(qsTr("Button 2 pressed")) + } + \endcode + + Remove the \c width and \c height properties from the ApplicationWindow + type and use a Layout type in the MainForm type to set the minimum and + preferred size of the main view. + + To use the Layouts, import QtQuick Layouts: + + \quotefromfile uiforms/main.qml + \skipto QtQuick.Layouts + \printline Layouts + + Then specify the following properties for the MainForm: + + \skipto MainForm + \printuntil Layout.preferredHeight + + \section2 Creating the Table View Model + + Use a list model to display customer data in the table view. Because the + list model is accessed from several different \e .qml files, access it + through a singleton type defined in \e CustomerModelSingleton.qml and + registered in \e main.cpp. This way, you do not have to rely on the QML + context scoping rules to access the list model. + + \list 1 + + \li In the \uicontrol Projects view, right-click \uicontrol qml.qrc and + select \uicontrol {Add New} > \uicontrol Qt > + \uicontrol {QML File (Qt Quick 2)} to create the + \e CustomerModelSingleton.qml file and to add it to the project. + + \li Copy the implementation from \l{uiforms/CustomerModelSingleton.qml} + {CustomerModelSingleton.qml}. + + \li Add the following code to the MainForm in \e main.qml to access the + list model: + + \quotefromfile uiforms/main.qml + \skipto tableView1.model: CustomerModel + \printuntil tableView1.selection + + \li To register the singleton type in the \e main.cpp file, include the + Qt QML module and call the \c qmlRegisterSingletonType() function in + the initialization function: + + \quotefromfile uiforms/main.cpp + \dots + \skipto QtQml + \printuntil "CustomerModel"); + + \li To use the registered singleton type in \e main.qml, you must import + the singleton type: + + \quotefromfile uiforms/main.qml + \skipto my.customermodel.singleton + \printline 1.0 + + \endlist + + \section1 Creating Tabs + + You can use the new file wizard to create UI forms that specify tab + contents and functionality. You set the QML files as sources for the tabs + in the \e MainForm.ui.qml file and modify the corresponding UI forms in the + \uicontrol Design mode. + + \section2 Creating UI Forms for Tab Contents + + To create UI forms for the tab contents: + + \list 1 + + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol Qt > \uicontrol {QtQuick UI File} > \uicontrol Choose. + + \li In the \uicontrol {Component name} field, enter \b Settings. + + \li Click \uicontrol Next. + + \li Click \uicontrol Finish to create the UI form, + \e SettingsForm.ui.qml, and a corresponding QML file, + \e Settings.qml. + + \endlist + + Create the UI form, \e NotesForm.ui.qml, and the corresponding QML file, + \e Notes.qml, for the notes tab in the same way. You will not need an + \e ui.qml file for the history tab, so you will create the QML file for it + later. + + \section2 Creating the Settings Tab + + The \uicontrol {Customer Settings} tab contains information about the + selected user. + + \image qmldesigner-uiforms-example-settings-tab.png + + To create the tab contents: + + \list 1 + + \li Double-click \e SettingsForm.ui.qml in the \uicontrol Projects + view to open it for editing in the \uicontrol Design mode. + + \li Select \uicontrol Item in the \uicontrol Navigator and enter + \b content in the \uicontrol Id field in \uicontrol Properties. + + \li In \uicontrol Library, select \uicontrol Imports > + \uicontrol {Add Import} and import Qt Quick Controls and Layouts to + make the QML types in those modules visible in the library. + + \li Drag and drop a \uicontrol {Grid Layout} from the library to the + \b content item in the navigator. + + \li Select \uicontrol Layout > \uicontrol Top, \uicontrol Left, and + \uicontrol Right buttons to anchor the grid layout to the parent. + + \li In the \uicontrol Margin fields for the anchors, set the margins + to \b 12. + + \li In \uicontrol Properties, set \uicontrol {Column spacing} and + \uicontrol {Row spacing} to \b 8, \uicontrol Columns to \b 3, and + \uicontrol Rows to \b 4. If you add more fields, add the necessary + amount of rows. + + \li Drag and drop four \uicontrol Label controls, a + \uicontrol {Combo Box}, and three \uicontrol {Text Field} controls + from the library to the navigator. + + \li Use the down arrow in the navigator to move one label down to the + position above the last text field. + + \li In the properties, change the label text for each field in the + \uicontrol Text field. You need the following labels: \b Title, + \b {First Name}, \b {Last Name}, and \b {Customer Id}. + + \li In the properties, change the placeholder text for each text field + in the \uicontrol {Placeholder text} field to be the same as the + field label. + + \li Select the customer ID text field, then select \uicontrol Layout + in properties and set \uicontrol {Column span} to 3 and check + \uicontrol {Fill width} to make the ID field span the length of + the grid layout. + + \li Drag and drop a \uicontrol {Row Layout} from the library to the + \b content item in the navigator and click on it. + + \li Reset the height of the row layout in properties. + + \image qmldesigner-uiforms-reset-height.png + + \li Select \uicontrol Layout > \uicontrol Bottom and \uicontrol Right + buttons to anchor the row layout to the parent. + + \li In the \uicontrol Margin fields for the anchors, set the margins + to \b 12. + + \li Drag and drop two \uicontrol Button controls from the library to the + row layout in the navigator. + + \li In the properties, change the button labels in the \uicontrol Text + field to \b Save and \b Cancel. + + \li Select \uicontrol Layout and > \uicontrol {Fill width} and + \uicontrol {Fill height} in properties for each button to have the + buttons fill the row layout. + + \li In the navigator, select \uicontrol Export for each field to export + the field IDs as properties. The following items should be exported, + so that they can be referred to in \e Settings.qml: + + \quotefromfile uiforms/SettingsForm.ui.qml + \skipto property + \printuntil title + + \endlist + + \section2 Creating the Notes Tab + + The \uicontrol {Customer Notes} tab contains a text area for entering notes + about the selected customer and buttons for saving or canceling the changes. + + To create the tab contents: + + \list 1 + + \li Double-click \e NotesForm.ui.qml in the \uicontrol Projects + view to open it for editing in the \uicontrol Design mode. + + \li Select \uicontrol Item in the \uicontrol Navigator and enter + \b content in the \uicontrol Id field in \uicontrol Properties. + + \li In \uicontrol Library, select \uicontrol Imports > + \uicontrol {Add Import} and import Qt Quick Controls and Layouts. + + \li Drag and drop a \uicontrol {Column Layout} from the library to the + \b content item in the navigator. + + \li Select \uicontrol Layout > \uicontrol Top, \uicontrol Left, and + \uicontrol Right buttons to anchor the grid layout to the parent + and set the margins to \b 12. + + \li Drag and drop a \uicontrol {Text Area} from the library to the + column layout. + + \li Select \uicontrol Layout and > \uicontrol {Fill width} and + \uicontrol {Fill height} in properties to have the text area fill + the column layout. + + \li Create the \uicontrol Save and \uicontrol Cancel buttons as + instructed in \l {Creating the Settings Tab}. You can also copy and + paste the row layout from SettingsForm.ui.qml. + + \li In the navigator, select \uicontrol Export for each field to export + the field IDs as properties. The following items should be exported, + so that they can be referred to in \e Notes.qml: + + \quotefromfile uiforms/NotesForm.ui.qml + \skipto property + \printuntil save + + \endlist + + \section2 Creating the History Tab + + The \uicontrol {Customer History} tab contains a table view that displays + the transactions performed by the customer. Create a custom HistoryTableView + type that you can edit in the \uicontrol Edit mode. For the history tab, you + do not need an \e ui.qml file at all. + + To create the history tab: + + \list 1 + + \li In the \uicontrol Projects view, right-click \uicontrol qml.qrc and + select \uicontrol {Add New} > \uicontrol Qt > + \uicontrol {QML File (Qt Quick 2)} to create the + \e HistoryTableView.qml file and to add it to the project. + + \li Copy the implementation from \l{uiforms/HistoryTableView.qml} + {HistoryTableView.qml}. + + \li Add the code from the example \l{uiforms/History.qml}{History.qml} + file to your \e History.qml file to access the code model. + + \endlist + + \section1 Adding Tab Functionality + + Add functions for displaying data from the customer model in the tabs. You + have already created the files that you need. You now need to copy the + implementation for the settings tab from the \l {uiforms/Settings.qml} + {Settings.qml} file and for the notes tab from the \l {uiforms/Notes.qml} + {Notes.qml} file. + + To display the tab contents in the main view, set the QML files as sources + for the tabs in the \uicontrol Design mode. Select the settings tab in the + \uicontrol Navigator and specify for example \e Settings.qml in the + \uicontrol Source field in the \uicontrol Properties view. Similarly, + specify the sources for the notes and history tabs. + + You can then remove the \e Tab.qml file that the wizard generated but that + you no longer need by selecting \uicontrol {Remove File} in the context + menu. + + \section1 Creating Menus + + The wizard adds a menu bar to the \e main.qml file that contains a + \uicontrol File menu with the \uicontrol Open and \uicontrol Exit menu + items. Keep the menu and the \uicontrol Exit menu item, and add the + \uicontrol Edit and \uicontrol Help menus with standard menu items. + + The wizard creates the following code: + + \badcode + menuBar: MenuBar { + Menu { + title: qsTr("&File") + MenuItem { + text: qsTr("&Open") + onTriggered: messageDialog.show(qsTr("Open action triggered")); + } + MenuItem { + text: qsTr("E&xit") + onTriggered: Qt.quit(); + } + } + } + \endcode + + Remove the \uicontrol Open menu item and add the following code to create + the new menus: + + \quotefromfile uiforms/main.qml + \skipto menuBar + \printuntil activeFocusItem.paste + \printuntil } + + \section1 Creating Dialogs + + \image qmldesigner-uiforms-example-about-dialog.png + + The wizard creates a message box in the \e main.qml file that you should + turn into an \uicontrol About dialog for the purpose of this example: + + \badcode + MessageDialog { + id: messageDialog + title: qsTr("May I have your attention, please?") + + function show(caption) { + messageDialog.text = caption; + messageDialog.open(); + } + \endcode + + Modify the code created by the wizard to add an icon and some text: + + \quotefromfile uiforms/main.qml + \skipto MessageDialog + \printuntil } + + Enable access to the \uicontrol About dialog from the \uicontrol Help menu + that you create next. + + \section1 Running the Application + + The application is complete and ready to be run on the desktop or deployed + to a device. To run the application, press \key {Ctrl+R}. +*/ diff --git a/doc/src/widgets/qtdesigner-app-tutorial.qdoc b/doc/src/widgets/qtdesigner-app-tutorial.qdoc index f15590829c4..1a4affebfdd 100644 --- a/doc/src/widgets/qtdesigner-app-tutorial.qdoc +++ b/doc/src/widgets/qtdesigner-app-tutorial.qdoc @@ -24,9 +24,9 @@ /*! \contentspage {Qt Creator Manual} - \previouspage creator-qml-application.html + \previouspage {Creating a Qt Quick Application} \page creator-writing-program.html - \nextpage creator-mobile-app-tutorial.html + \nextpage {Creating a Mobile Application} \title Creating a Qt Widget Based Application diff --git a/qbs/imports/QtcLibrary.qbs b/qbs/imports/QtcLibrary.qbs index a4fc14bdd68..93b60110582 100644 --- a/qbs/imports/QtcLibrary.qbs +++ b/qbs/imports/QtcLibrary.qbs @@ -27,6 +27,6 @@ QtcProduct { Export { Depends { name: "cpp" } - cpp.includePaths: [libIncludeBase] + cpp.includePaths: [product.libIncludeBase] } } diff --git a/qbs/imports/QtcPlugin.qbs b/qbs/imports/QtcPlugin.qbs index a103f485728..6bbe1efcaa3 100644 --- a/qbs/imports/QtcPlugin.qbs +++ b/qbs/imports/QtcPlugin.qbs @@ -52,6 +52,6 @@ QtcProduct { Export { Depends { name: "ExtensionSystem" } Depends { name: "cpp" } - cpp.includePaths: [pluginIncludeBase] + cpp.includePaths: [product.pluginIncludeBase] } } diff --git a/qtcreator.pro b/qtcreator.pro index c78f6bec4f4..3078c34be1b 100644 --- a/qtcreator.pro +++ b/qtcreator.pro @@ -128,14 +128,9 @@ installer.depends = bindist_installer installer.commands = python -u $$PWD/scripts/packageIfw.py -i \"$(IFW_PATH)\" -v $${QTCREATOR_VERSION} -a \"$${INSTALLER_ARCHIVE}\" "$$INSTALLER_NAME" macx { - # this should be very temporary: - MENU_NIB = $$(MENU_NIB_FILE) - isEmpty(MENU_NIB): MENU_NIB = "FATAT_SET_MENU_NIB_FILE_ENV" - copy_menu_nib_installer.commands = cp -R \"$$MENU_NIB\" \"$${INSTALLER_NAME}.app/Contents/Resources\" - codesign_installer.commands = codesign -s \"$(SIGNING_IDENTITY)\" $(SIGNING_FLAGS) \"$${INSTALLER_NAME}.app\" dmg_installer.commands = hdiutil create -srcfolder "$${INSTALLER_NAME}.app" -volname \"Qt Creator\" -format UDBZ "$${BASENAME}-installer.dmg" -ov -scrub -size 1g -verbose - QMAKE_EXTRA_TARGETS += codesign_installer dmg_installer copy_menu_nib_installer + QMAKE_EXTRA_TARGETS += codesign_installer dmg_installer } win32 { diff --git a/scripts/deployqt.py b/scripts/deployqt.py index 1932a28134a..f7bf539f2f1 100755 --- a/scripts/deployqt.py +++ b/scripts/deployqt.py @@ -91,7 +91,8 @@ def fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames): for filename in filenames: fpath = os.path.join(dirpath, filename) relpath = os.path.relpath(install_dir+'/lib/qtcreator', dirpath) - command = [chrpath_bin, '-r', '$ORIGIN/'+relpath, fpath] + relpluginpath = os.path.relpath(install_dir+'/lib/qtcreator/plugins', dirpath) + command = [chrpath_bin, '-r', '$ORIGIN/'+relpath+':$ORIGIN/'+relpluginpath, fpath] print fpath, ':', command try: subprocess.check_call(command) @@ -215,20 +216,31 @@ def copy_translations(install_dir, qt_tr_dir): print translation, '->', tr_dir shutil.copy(translation, tr_dir) +def copyPreservingLinks(source, destination): + if os.path.islink(source): + linkto = os.readlink(source) + destFilePath = destination + if os.path.isdir(destination): + destFilePath = os.path.join(destination, os.path.basename(source)) + os.symlink(linkto, destFilePath) + else: + shutil.copy(source, destination) + def copy_libclang(install_dir, llvm_install_dir): - libsource = "" + libsources = [] libtarget = "" if sys.platform.startswith("win"): - libsource = os.path.join(llvm_install_dir, 'bin', 'libclang.dll') + libsources = [os.path.join(llvm_install_dir, 'bin', 'libclang.dll')] libtarget = os.path.join(install_dir, 'bin') else: - libsource = os.path.join(llvm_install_dir, 'lib', 'libclang.so') + libsources = glob(os.path.join(llvm_install_dir, 'lib', 'libclang.so*')) libtarget = os.path.join(install_dir, 'lib', 'qtcreator') resourcesource = os.path.join(llvm_install_dir, 'lib', 'clang') resourcetarget = os.path.join(install_dir, 'share', 'qtcreator', 'cplusplus', 'clang') print "copying libclang..." - print libsource, '->', libtarget - shutil.copy(libsource, libtarget) + for libsource in libsources: + print libsource, '->', libtarget + copyPreservingLinks(libsource, libtarget) print resourcesource, '->', resourcetarget if (os.path.exists(resourcetarget)): shutil.rmtree(resourcetarget) diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index 638cc2f0069..120a4d030a9 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -57,7 +57,9 @@ fi if [ $LLVM_INSTALL_DIR ]; then if [ "$LLVM_INSTALL_DIR"/lib/libclang.dylib -nt "$1/Contents/PlugIns"/libclang.dylib ]; then echo "- Copying libclang" - cp -f "$LLVM_INSTALL_DIR"/lib/libclang.dylib "$1/Contents/PlugIns/" || exit 1 + mkdir -p "$1/Contents/Frameworks" || exit 1 + # use recursive copy to make it copy symlinks as symlinks + cp -Rf "$LLVM_INSTALL_DIR"/lib/libclang.*dylib "$1/Contents/Frameworks/" || exit 1 cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$1/Contents/Resources/cplusplus/" || exit 1 fi _CLANG_CODEMODEL_LIB="$1/Contents/PlugIns/libClangCodeModel_debug.dylib" @@ -66,7 +68,8 @@ if [ $LLVM_INSTALL_DIR ]; then fi # this will just fail when run a second time on libClangCodeModel xcrun install_name_tool -delete_rpath "$LLVM_INSTALL_DIR/lib" "$_CLANG_CODEMODEL_LIB" || true - xcrun install_name_tool -add_rpath "@loader_path/" "$_CLANG_CODEMODEL_LIB" || true + xcrun install_name_tool -add_rpath "@loader_path/../Frameworks" "$_CLANG_CODEMODEL_LIB" || true + clangbackendArgument="-executable=$1/Contents/Resources/clangbackend" fi #### macdeployqt @@ -93,7 +96,8 @@ if [ ! -d "$1/Contents/Frameworks/QtCore.framework" ]; then "-executable=$1/Contents/Resources/ios/iostool" \ "-executable=$1/Contents/Resources/ios/iossim" \ "-executable=$1/Contents/Resources/ios/iossim_1_8_2" \ - "-executable=$1/Contents/MacOS/buildoutputparser" \ + "-executable=$1/Contents/Resources/buildoutputparser" \ + "-executable=$1/Contents/Resources/cpaster" \ "-executable=$qbsapp" \ "-executable=$qbsapp-config" \ "-executable=$qbsapp-config-ui" \ @@ -101,6 +105,6 @@ if [ ! -d "$1/Contents/Frameworks/QtCore.framework" ]; then "-executable=$qbsapp-setup-android" \ "-executable=$qbsapp-setup-qt" \ "-executable=$qbsapp-setup-toolchains" \ - "$qmlpuppetArgument" "$qml2puppetArgument" || exit 1 + "$qmlpuppetArgument" "$qml2puppetArgument" "$clangbackendArgument" || exit 1 fi diff --git a/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h b/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h index 22f6f0ca2f0..cc7ca503bd7 100644 --- a/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h +++ b/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h @@ -30,16 +30,24 @@ #define QT_NO_META_MACROS -#define signals public __attribute__((annotate("qt_signal"))) -#define slots __attribute__((annotate("qt_slot"))) -#define Q_SIGNALS signals -#define Q_SLOTS slots +#if defined(QT_NO_KEYWORDS) +# define QT_NO_EMIT +#else +# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS +# define signals public __attribute__((annotate("qt_signal"))) +# define slots __attribute__((annotate("qt_slot"))) +# endif +#endif +#define Q_SIGNALS public __attribute__((annotate("qt_signal"))) +#define Q_SLOTS slots __attribute__((annotate("qt_slot"))) #define Q_SIGNAL __attribute__((annotate("qt_signal"))) #define Q_SLOT __attribute__((annotate("qt_slot"))) -# define Q_PRIVATE_SLOT(d, signature) +#define Q_PRIVATE_SLOT(d, signature) #define Q_EMIT -#define emit +#ifndef QT_NO_EMIT +# define emit +#endif #define Q_CLASSINFO(name, value) #define Q_PLUGIN_METADATA(x) #define Q_INTERFACES(x) @@ -49,6 +57,8 @@ #define Q_OVERRIDE(text) #define Q_ENUMS(x) #define Q_FLAGS(x) +#define Q_ENUM(x) +#define Q_FLAG(x) #define Q_SCRIPTABLE #define Q_INVOKABLE diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 4622b22ff7b..7c6de9c3a17 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -26,7 +26,7 @@ from dumper import * # ####################################################################### -def savePrint(output): +def safePrint(output): try: print(output) except: @@ -47,7 +47,7 @@ def registerCommand(name, func): def __init__(self): super(Command, self).__init__(name, gdb.COMMAND_OBSCURE) def invoke(self, args, from_tty): - savePrint(func(args)) + safePrint(func(args)) Command() @@ -130,7 +130,7 @@ class ScanStackCommand(gdb.Command): def invoke(self, args, from_tty): if len(args) == 0: args = 20 - savePrint(scanStack(gdb.parse_and_eval("$sp"), int(args))) + safePrint(scanStack(gdb.parse_and_eval("$sp"), int(args))) ScanStackCommand() @@ -438,7 +438,7 @@ class Dumper(DumperBase): self.output.append(',partial="%d"' % isPartial) - print(''.join(self.output)) + safePrint(''.join(self.output)) def enterSubItem(self, item): if not item.iname: @@ -1619,7 +1619,7 @@ class Dumper(DumperBase): frame = frame.older() i += 1 - print(''.join(self.output)) + safePrint(''.join(self.output)) def createResolvePendingBreakpointsHookBreakpoint(self, args): class Resolver(gdb.Breakpoint): diff --git a/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json index 6e14d9b695a..d633eddf6bf 100644 --- a/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json @@ -15,7 +15,8 @@ { "key": "ProFileName", "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'pro')}" }, { "key": "MainCppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" }, { "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" }, - { "key": "QtQuickWindowVersion", "value": "%{JS: %{QtVersion}.qtQuickWindowVersion}" } + { "key": "QtQuickWindowVersion", "value": "%{JS: %{QtVersion}.qtQuickWindowVersion}" }, + { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" } ], "pages": @@ -86,13 +87,7 @@ "typeId": "Kits", "data": { "projectFilePath": "%{ProFileName}", - "requiredFeatures": - [ - "QtSupport.Wizards.FeatureQt", - { "feature": "QtSupport.Wizards.FeatureQtQuick.2.3", "condition": "%{JS: '%{QtQuickVersion}' === '2.3'}" }, - { "feature": "QtSupport.Wizards.FeatureQtQuick.2.4", "condition": "%{JS: '%{QtQuickVersion}' === '2.4'}" }, - { "feature": "QtSupport.Wizards.FeatureQtQuick.2.5", "condition": "%{JS: '%{QtQuickVersion}' === '2.5'}" } - ] + "requiredFeatures": [ "QtSupport.Wizards.FeatureQt", "%{QtQuickFeature}" ] } }, { diff --git a/share/qtcreator/templates/wizards/projects/qmake/qtquickcontrolsapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qmake/qtquickcontrolsapplication/wizard.json index 13567e55f13..7738f28e5ac 100644 --- a/share/qtcreator/templates/wizards/projects/qmake/qtquickcontrolsapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qmake/qtquickcontrolsapplication/wizard.json @@ -17,7 +17,8 @@ { "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" }, { "key": "QtQuickControlsVersion", "value": "%{JS: %{QtVersion}.qtQuickControlsVersion}" }, { "key": "QtQuickDialogsVersion", "value": "%{JS: %{QtVersion}.qtQuickDialogsVersion}" }, - { "key": "QtQuickLayoutsVersion", "value": "%{JS: %{QtVersion}.qtQuickLayoutsVersion}" } + { "key": "QtQuickLayoutsVersion", "value": "%{JS: %{QtVersion}.qtQuickLayoutsVersion}" }, + { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" } ], "pages": @@ -46,7 +47,7 @@ "value": "{ 'qtQuickVersion': '2.5', - 'qtQuickControlsVersion': '1.3', + 'qtQuickControlsVersion': '1.4', 'qtQuickDialogsVersion': '1.2', 'qtQuickLayoutsVersion': '1.2' }", @@ -57,7 +58,7 @@ "value": "{ 'qtQuickVersion': '2.4', - 'qtQuickControlsVersion': '1.2', + 'qtQuickControlsVersion': '1.3', 'qtQuickDialogsVersion': '1.2', 'qtQuickLayoutsVersion': '1.1' }", @@ -103,12 +104,7 @@ "typeId": "Kits", "data": { "projectFilePath": "%{ProFileName}", - "requiredFeatures": - [ - "QtSupport.Wizards.FeatureQt", - { "feature": "QtSupport.Wizards.FeatureQtQuick.Controls.1.2", "condition": "%{JS: '%{QtQuickControlsVersion' === '1.2' }" }, - { "feature": "QtSupport.Wizards.FeatureQtQuick.Controls.1.3", "condition": "%{JS: '%{QtQuickControlsVersion' === '1.3' }" } - ] + "requiredFeatures": [ "QtSupport.Wizards.FeatureQt", "%{QtQuickFeature}" ] } }, { diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index b8cda42b59c..c44d9b4a814 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -3348,7 +3348,7 @@ public: DeclarationAST *declaration; public: // annotations - Template *symbol; + Scope *symbol; public: TemplateDeclarationAST() diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index c135de16730..0deb19dd544 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -2367,11 +2367,15 @@ bool Bind::visit(ParameterDeclarationAST *ast) bool Bind::visit(TemplateDeclarationAST *ast) { - Template *templ = control()->newTemplate(ast->firstToken(), 0); - templ->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin()); - templ->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd()); - ast->symbol = templ; - Scope *previousScope = switchScope(templ); + Scope *scope = 0; + if (ast->less_token) + scope = control()->newTemplate(ast->firstToken(), 0); + else + scope = control()->newExplicitInstantiation(ast->firstToken(), 0); + scope->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin()); + scope->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd()); + ast->symbol = scope; + Scope *previousScope = switchScope(scope); for (DeclarationListAST *it = ast->template_parameter_list; it; it = it->next) { this->declaration(it->value); @@ -2380,12 +2384,17 @@ bool Bind::visit(TemplateDeclarationAST *ast) this->declaration(ast->declaration); (void) switchScope(previousScope); - if (Symbol *decl = templ->declaration()) { - templ->setSourceLocation(decl->sourceLocation(), translationUnit()); - templ->setName(decl->name()); + Symbol *decl = 0; + if (Template *templ = scope->asTemplate()) + decl = templ->declaration(); + else if (ExplicitInstantiation *inst = scope->asExplicitInstantiation()) + decl = inst->declaration(); + if (decl) { + scope->setSourceLocation(decl->sourceLocation(), translationUnit()); + scope->setName(decl->name()); } - _scope->addMember(templ); + _scope->addMember(scope); return false; } diff --git a/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h b/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h index 9b1c5a30cf7..54f9db96dac 100644 --- a/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h @@ -112,6 +112,7 @@ class Function; class Namespace; class NamespaceAlias; class Template; +class ExplicitInstantiation; class BaseClass; class Block; class Class; diff --git a/src/libs/3rdparty/cplusplus/Control.cpp b/src/libs/3rdparty/cplusplus/Control.cpp index afdd6790560..463a2f88f69 100644 --- a/src/libs/3rdparty/cplusplus/Control.cpp +++ b/src/libs/3rdparty/cplusplus/Control.cpp @@ -366,9 +366,16 @@ public: Template *newTemplate(unsigned sourceLocation, const Name *name) { - Template *ns = new Template(translationUnit, sourceLocation, name); - symbols.push_back(ns); - return ns; + Template *templ = new Template(translationUnit, sourceLocation, name); + symbols.push_back(templ); + return templ; + } + + ExplicitInstantiation *newExplicitInstantiation(unsigned sourceLocation, const Name *name) + { + ExplicitInstantiation *inst = new ExplicitInstantiation(translationUnit, sourceLocation, name); + symbols.push_back(inst); + return inst; } NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name) @@ -692,6 +699,9 @@ Namespace *Control::newNamespace(unsigned sourceLocation, const Name *name) Template *Control::newTemplate(unsigned sourceLocation, const Name *name) { return d->newTemplate(sourceLocation, name); } +ExplicitInstantiation *Control::newExplicitInstantiation(unsigned sourceLocation, const Name *name) +{ return d->newExplicitInstantiation(sourceLocation, name); } + NamespaceAlias *Control::newNamespaceAlias(unsigned sourceLocation, const Name *name) { return d->newNamespaceAlias(sourceLocation, name); } diff --git a/src/libs/3rdparty/cplusplus/Control.h b/src/libs/3rdparty/cplusplus/Control.h index 85b8c3d3d7c..bb2bf9cd108 100644 --- a/src/libs/3rdparty/cplusplus/Control.h +++ b/src/libs/3rdparty/cplusplus/Control.h @@ -120,6 +120,9 @@ public: /// Creates a new Template symbol. Template *newTemplate(unsigned sourceLocation, const Name *name = 0); + /// Creates a new ExplicitInstantiation symbol. + ExplicitInstantiation *newExplicitInstantiation(unsigned sourceLocation, const Name *name = 0); + /// Creates a new Namespace symbol. NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0); diff --git a/src/libs/3rdparty/cplusplus/Matcher.cpp b/src/libs/3rdparty/cplusplus/Matcher.cpp index 7a3c21cafc9..379ed595869 100644 --- a/src/libs/3rdparty/cplusplus/Matcher.cpp +++ b/src/libs/3rdparty/cplusplus/Matcher.cpp @@ -218,6 +218,17 @@ bool Matcher::match(const Template *type, const Template *otherType) return true; } +bool Matcher::match(const ExplicitInstantiation *type, const ExplicitInstantiation *otherType) +{ + if (type == otherType) + return true; + + if (! Matcher::match(type->name(), otherType->name(), this)) + return false; + + return true; +} + bool Matcher::match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType) { if (type == otherType) diff --git a/src/libs/3rdparty/cplusplus/Matcher.h b/src/libs/3rdparty/cplusplus/Matcher.h index 1a9d9d35116..4d2b40b64d1 100644 --- a/src/libs/3rdparty/cplusplus/Matcher.h +++ b/src/libs/3rdparty/cplusplus/Matcher.h @@ -61,6 +61,7 @@ public: virtual bool match(const Enum *type, const Enum *otherType); virtual bool match(const Namespace *type, const Namespace *otherType); virtual bool match(const Template *type, const Template *otherType); + virtual bool match(const ExplicitInstantiation *type, const ExplicitInstantiation *otherType); virtual bool match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType); virtual bool match(const Class *type, const Class *otherType); virtual bool match(const ObjCClass *type, const ObjCClass *otherType); diff --git a/src/libs/3rdparty/cplusplus/Symbol.cpp b/src/libs/3rdparty/cplusplus/Symbol.cpp index ae20b14bb75..0ddd4ffbb2a 100644 --- a/src/libs/3rdparty/cplusplus/Symbol.cpp +++ b/src/libs/3rdparty/cplusplus/Symbol.cpp @@ -361,6 +361,9 @@ bool Symbol::isNamespace() const bool Symbol::isTemplate() const { return asTemplate() != 0; } +bool Symbol::isExplicitInstantiation() const +{ return asExplicitInstantiation() != 0; } + bool Symbol::isClass() const { return asClass() != 0; } diff --git a/src/libs/3rdparty/cplusplus/Symbol.h b/src/libs/3rdparty/cplusplus/Symbol.h index 919268b14b6..cbed45f4612 100644 --- a/src/libs/3rdparty/cplusplus/Symbol.h +++ b/src/libs/3rdparty/cplusplus/Symbol.h @@ -135,7 +135,7 @@ public: /// Returns true if this Symbol is an Enum. bool isEnum() const; - /// Returns true if this Symbol is an Function. + /// Returns true if this Symbol is a Function. bool isFunction() const; /// Returns true if this Symbol is a Namespace. @@ -144,6 +144,9 @@ public: /// Returns true if this Symbol is a Template. bool isTemplate() const; + /// Returns true if this Symbol is an ExplicitInstantiation. + bool isExplicitInstantiation() const; + /// Returns true if this Symbol is a Class. bool isClass() const; @@ -203,6 +206,7 @@ public: virtual const Function *asFunction() const { return 0; } virtual const Namespace *asNamespace() const { return 0; } virtual const Template *asTemplate() const { return 0; } + virtual const ExplicitInstantiation *asExplicitInstantiation() const { return 0; } virtual const NamespaceAlias *asNamespaceAlias() const { return 0; } virtual const Class *asClass() const { return 0; } virtual const Block *asBlock() const { return 0; } @@ -229,6 +233,7 @@ public: virtual Function *asFunction() { return 0; } virtual Namespace *asNamespace() { return 0; } virtual Template *asTemplate() { return 0; } + virtual ExplicitInstantiation *asExplicitInstantiation() { return 0; } virtual NamespaceAlias *asNamespaceAlias() { return 0; } virtual Class *asClass() { return 0; } virtual Block *asBlock() { return 0; } diff --git a/src/libs/3rdparty/cplusplus/SymbolVisitor.h b/src/libs/3rdparty/cplusplus/SymbolVisitor.h index 4311672eca8..5331525e9fa 100644 --- a/src/libs/3rdparty/cplusplus/SymbolVisitor.h +++ b/src/libs/3rdparty/cplusplus/SymbolVisitor.h @@ -51,6 +51,7 @@ public: virtual bool visit(Function *) { return true; } virtual bool visit(Namespace *) { return true; } virtual bool visit(Template *) { return true; } + virtual bool visit(ExplicitInstantiation *) { return true; } virtual bool visit(Class *) { return true; } virtual bool visit(Block *) { return true; } virtual bool visit(ForwardClassDeclaration *) { return true; } diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp index f8a8440c097..3c632f1cd7f 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.cpp +++ b/src/libs/3rdparty/cplusplus/Symbols.cpp @@ -481,10 +481,12 @@ void Enum::visitSymbol0(SymbolVisitor *visitor) Template::Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name) : Scope(translationUnit, sourceLocation, name) + , _isExplicitInstantiation(false) { } Template::Template(Clone *clone, Subst *subst, Template *original) : Scope(clone, subst, original) + , _isExplicitInstantiation(original->_isExplicitInstantiation) { } Template::~Template() @@ -537,6 +539,56 @@ bool Template::match0(const Type *otherType, Matcher *matcher) const return false; } +ExplicitInstantiation::ExplicitInstantiation(TranslationUnit *translationUnit, + unsigned sourceLocation, const Name *name) + : Scope(translationUnit, sourceLocation, name) +{ } + +ExplicitInstantiation::ExplicitInstantiation(Clone *clone, Subst *subst, ExplicitInstantiation *original) + : Scope(clone, subst, original) +{ } + +ExplicitInstantiation::~ExplicitInstantiation() +{ } + +Symbol *ExplicitInstantiation::declaration() const +{ + if (isEmpty()) + return 0; + + if (Symbol *s = memberAt(memberCount() - 1)) { + if (s->isClass() || s->isForwardClassDeclaration() || + s->isTemplate() || s->isExplicitInstantiation() || + s->isFunction() || s->isDeclaration()) { + return s; + } + } + + return 0; +} + +FullySpecifiedType ExplicitInstantiation::type() const +{ return FullySpecifiedType(const_cast(this)); } + +void ExplicitInstantiation::visitSymbol0(SymbolVisitor *visitor) +{ + if (visitor->visit(this)) { + for (unsigned i = 0; i < memberCount(); ++i) { + visitSymbol(memberAt(i), visitor); + } + } +} + +void ExplicitInstantiation::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + +bool ExplicitInstantiation::match0(const Type *otherType, Matcher *matcher) const +{ + if (const ExplicitInstantiation *otherTy = otherType->asExplicitInstantiationType()) + return matcher->match(this, otherTy); + return false; +} + Namespace::Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name) : Scope(translationUnit, sourceLocation, name) , _isInline(false) diff --git a/src/libs/3rdparty/cplusplus/Symbols.h b/src/libs/3rdparty/cplusplus/Symbols.h index 257bdb86826..f2d92c23f2b 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.h +++ b/src/libs/3rdparty/cplusplus/Symbols.h @@ -423,8 +423,41 @@ protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); virtual bool match0(const Type *otherType, Matcher *matcher) const; + +private: + bool _isExplicitInstantiation; }; +class CPLUSPLUS_EXPORT ExplicitInstantiation : public Scope, public Type +{ +public: + ExplicitInstantiation(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name); + ExplicitInstantiation(Clone *clone, Subst *subst, ExplicitInstantiation *original); + virtual ~ExplicitInstantiation(); + + Symbol *declaration() const; + + // Symbol's interface + virtual FullySpecifiedType type() const; + + virtual const ExplicitInstantiation *asExplicitInstantiation() const + { return this; } + + virtual ExplicitInstantiation *asExplicitInstantiation() + { return this; } + + // Type's interface + virtual const ExplicitInstantiation *asExplicitInstantiationType() const + { return this; } + + virtual ExplicitInstantiation *asExplicitInstantiationType() + { return this; } + +protected: + virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); + virtual bool match0(const Type *otherType, Matcher *matcher) const; +}; class CPLUSPLUS_EXPORT Namespace: public Scope, public Type { diff --git a/src/libs/3rdparty/cplusplus/Templates.cpp b/src/libs/3rdparty/cplusplus/Templates.cpp index 2aaefe416ff..41e462a3b87 100644 --- a/src/libs/3rdparty/cplusplus/Templates.cpp +++ b/src/libs/3rdparty/cplusplus/Templates.cpp @@ -125,6 +125,12 @@ void CloneType::visit(Template *type) _type = templ; } +void CloneType::visit(ExplicitInstantiation *type) +{ + ExplicitInstantiation *inst = _clone->symbol(type, _subst)->asExplicitInstantiation(); + _type = inst; +} + void CloneType::visit(Class *type) { Class *klass = _clone->symbol(type, _subst)->asClass(); @@ -291,6 +297,14 @@ bool CloneSymbol::visit(Template *symbol) return false; } +bool CloneSymbol::visit(ExplicitInstantiation *symbol) +{ + ExplicitInstantiation *inst = new ExplicitInstantiation(_clone, _subst, symbol); + _symbol = inst; + _control->addSymbol(inst); + return false; +} + bool CloneSymbol::visit(Class *symbol) { Class *klass = new Class(_clone, _subst, symbol); diff --git a/src/libs/3rdparty/cplusplus/Templates.h b/src/libs/3rdparty/cplusplus/Templates.h index 9db69084f71..e39f79a7a66 100644 --- a/src/libs/3rdparty/cplusplus/Templates.h +++ b/src/libs/3rdparty/cplusplus/Templates.h @@ -85,6 +85,7 @@ protected: virtual void visit(Function *type); virtual void visit(Namespace *type); virtual void visit(Template *type); + virtual void visit(ExplicitInstantiation *type); virtual void visit(Class *type); virtual void visit(Enum *type); virtual void visit(ForwardClassDeclaration *type); @@ -152,6 +153,7 @@ protected: virtual bool visit(Function *symbol); virtual bool visit(Namespace *symbol); virtual bool visit(Template *symbol); + virtual bool visit(ExplicitInstantiation *symbol); virtual bool visit(Class *symbol); virtual bool visit(Block *symbol); virtual bool visit(ForwardClassDeclaration *symbol); diff --git a/src/libs/3rdparty/cplusplus/Type.cpp b/src/libs/3rdparty/cplusplus/Type.cpp index bad4d42eebd..69ffb5030a8 100644 --- a/src/libs/3rdparty/cplusplus/Type.cpp +++ b/src/libs/3rdparty/cplusplus/Type.cpp @@ -68,6 +68,9 @@ bool Type::isNamespaceType() const bool Type::isTemplateType() const { return asTemplateType() != 0; } +bool Type::isExplicitInstantiationType() const +{ return asExplicitInstantiationType() != 0; } + bool Type::isClassType() const { return asClassType() != 0; } diff --git a/src/libs/3rdparty/cplusplus/Type.h b/src/libs/3rdparty/cplusplus/Type.h index 958ba15efdd..2661628f76a 100644 --- a/src/libs/3rdparty/cplusplus/Type.h +++ b/src/libs/3rdparty/cplusplus/Type.h @@ -43,6 +43,7 @@ public: bool isFunctionType() const; bool isNamespaceType() const; bool isTemplateType() const; + bool isExplicitInstantiationType() const; bool isClassType() const; bool isEnumType() const; bool isForwardClassDeclarationType() const; @@ -64,6 +65,7 @@ public: virtual const Function *asFunctionType() const { return 0; } virtual const Namespace *asNamespaceType() const { return 0; } virtual const Template *asTemplateType() const { return 0; } + virtual const ExplicitInstantiation *asExplicitInstantiationType() const { return 0; } virtual const Class *asClassType() const { return 0; } virtual const Enum *asEnumType() const { return 0; } virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; } @@ -85,6 +87,7 @@ public: virtual Function *asFunctionType() { return 0; } virtual Namespace *asNamespaceType() { return 0; } virtual Template *asTemplateType() { return 0; } + virtual ExplicitInstantiation *asExplicitInstantiationType() { return 0; } virtual Class *asClassType() { return 0; } virtual Enum *asEnumType() { return 0; } virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; } diff --git a/src/libs/3rdparty/cplusplus/TypeVisitor.h b/src/libs/3rdparty/cplusplus/TypeVisitor.h index b3a24b15723..86568dcebca 100644 --- a/src/libs/3rdparty/cplusplus/TypeVisitor.h +++ b/src/libs/3rdparty/cplusplus/TypeVisitor.h @@ -51,6 +51,7 @@ public: virtual void visit(Function *) {} virtual void visit(Namespace *) {} virtual void visit(Template *) {} + virtual void visit(ExplicitInstantiation *) {} virtual void visit(Class *) {} virtual void visit(Enum *) {} virtual void visit(ForwardClassDeclaration *) {} diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri index f49e3ab2197..50c5974d4e8 100644 --- a/src/libs/clangbackendipc/clangbackendipc-lib.pri +++ b/src/libs/clangbackendipc/clangbackendipc-lib.pri @@ -35,8 +35,8 @@ SOURCES += $$PWD/ipcserverinterface.cpp \ $$PWD/translationunitdoesnotexistcommand.cpp \ $$PWD/codecompletionchunk.cpp \ $$PWD/projectpartcontainer.cpp \ - $$PWD/projectpartsdonotexistcommand.cpp - + $$PWD/projectpartsdonotexistcommand.cpp \ + $$PWD/lineprefixer.cpp HEADERS += \ $$PWD/ipcserverinterface.h \ @@ -66,6 +66,7 @@ HEADERS += \ $$PWD/projectpartcontainer.h \ $$PWD/projectpartsdonotexistcommand.h \ $$PWD/container_common.h \ - $$PWD/clangbackendipc_global.h + $$PWD/clangbackendipc_global.h \ + $$PWD/lineprefixer.h contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols diff --git a/src/libs/clangbackendipc/clangbackendipc.qbs b/src/libs/clangbackendipc/clangbackendipc.qbs index 0ffe8cacb2b..479d9b67650 100644 --- a/src/libs/clangbackendipc/clangbackendipc.qbs +++ b/src/libs/clangbackendipc/clangbackendipc.qbs @@ -6,7 +6,7 @@ QtcLibrary { Depends { name: "Qt.network" } Depends { name: "Sqlite" } - cpp.defines: base.concat("CLANGIPC_LIBRARY") + cpp.defines: base.concat("CLANGBACKENDIPC_LIBRARY") cpp.includePaths: base.concat(".") Group { diff --git a/src/libs/clangbackendipc/connectionclient.cpp b/src/libs/clangbackendipc/connectionclient.cpp index 4636ef22759..90a6d4a4718 100644 --- a/src/libs/clangbackendipc/connectionclient.cpp +++ b/src/libs/clangbackendipc/connectionclient.cpp @@ -54,7 +54,9 @@ QString connectionName() ConnectionClient::ConnectionClient(IpcClientInterface *client) : serverProxy_(client, &localSocket), - isAliveTimerResetted(false) + isAliveTimerResetted(false), + stdErrPrefixer("ClangBackEnd-StdErr: "), + stdOutPrefixer("ClangBackEnd: ") { processAliveTimer.setInterval(10000); @@ -95,10 +97,17 @@ bool ConnectionClient::isConnected() const return localSocket.state() == QLocalSocket::ConnectedState; } +void ConnectionClient::ensureCommandIsWritten() +{ + while (localSocket.bytesToWrite() > 0) + localSocket.waitForBytesWritten(); +} + void ConnectionClient::sendEndCommand() { serverProxy_.end(); localSocket.flush(); + ensureCommandIsWritten(); } void ConnectionClient::resetProcessAliveTimer() @@ -148,8 +157,6 @@ void ConnectionClient::restartProcessIfTimerIsNotResettedAndSocketIsEmpty() bool ConnectionClient::connectToLocalSocket() { - QThread::msleep(30); - for (int counter = 0; counter < 1000; counter++) { localSocket.connectToServer(connectionName()); bool isConnected = localSocket.waitForConnected(20); @@ -191,19 +198,20 @@ void ConnectionClient::killProcess() } } -void ConnectionClient::printLocalSocketError(QLocalSocket::LocalSocketError /*socketError*/) +void ConnectionClient::printLocalSocketError(QLocalSocket::LocalSocketError socketError) { - qWarning() << "ClangCodeModel ConnectionClient LocalSocket Error:" << localSocket.errorString(); + if (socketError != QLocalSocket::ServerNotFoundError) + qWarning() << "ClangCodeModel ConnectionClient LocalSocket Error:" << localSocket.errorString(); } void ConnectionClient::printStandardOutput() { - qWarning() << "ClangBackEnd:" << process_->readAllStandardOutput(); + QTextStream(stdout) << stdOutPrefixer.prefix(process_->readAllStandardOutput()); } void ConnectionClient::printStandardError() { - qWarning() << "ClangBackEnd Error:" << process_->readAllStandardError(); + QTextStream(stderr) << stdErrPrefixer.prefix(process_->readAllStandardError()); } void ConnectionClient::finishProcess() diff --git a/src/libs/clangbackendipc/connectionclient.h b/src/libs/clangbackendipc/connectionclient.h index 01f48d75b49..eaf4b227bf8 100644 --- a/src/libs/clangbackendipc/connectionclient.h +++ b/src/libs/clangbackendipc/connectionclient.h @@ -32,6 +32,7 @@ #define CLANGBACKEND_CONNECTIONCLIENT_H #include "ipcserverproxy.h" +#include "lineprefixer.h" #include @@ -97,7 +98,7 @@ private: void disconnectProcessFinished() const; void connectStandardOutputAndError() const; - void waitUntilSocketIsFlushed() const; + void ensureCommandIsWritten(); private: mutable std::unique_ptr process_; @@ -106,6 +107,9 @@ private: QTimer processAliveTimer; QString processPath_; bool isAliveTimerResetted; + + LinePrefixer stdErrPrefixer; + LinePrefixer stdOutPrefixer; }; } // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/lineprefixer.cpp b/src/libs/clangbackendipc/lineprefixer.cpp new file mode 100644 index 00000000000..0c8c9faa5b4 --- /dev/null +++ b/src/libs/clangbackendipc/lineprefixer.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "lineprefixer.h" + +namespace ClangBackEnd { + +LinePrefixer::LinePrefixer(const QByteArray &prefix) + : m_prefix(prefix) + , m_previousIsEndingWithNewLine(true) +{} + +QByteArray LinePrefixer::prefix(const QByteArray &text) +{ + QByteArray output = text; + + if (m_previousIsEndingWithNewLine) + output.prepend(m_prefix); + + if (output.endsWith('\n')) { + m_previousIsEndingWithNewLine = true; + output.chop(1); + } else { + m_previousIsEndingWithNewLine = false; + } + + output.replace("\n", "\n" + m_prefix); + if (m_previousIsEndingWithNewLine) + output.append('\n'); + + return output; +} + +} // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/lineprefixer.h b/src/libs/clangbackendipc/lineprefixer.h new file mode 100644 index 00000000000..ae8183a0e14 --- /dev/null +++ b/src/libs/clangbackendipc/lineprefixer.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + + +#ifndef PRINTLINESWITHPREFIX_H +#define PRINTLINESWITHPREFIX_H + +#include +#include +#include + +namespace ClangBackEnd { + +class LinePrefixer +{ +public: + LinePrefixer() = delete; + LinePrefixer(const QByteArray &m_prefix); + QByteArray prefix(const QByteArray &text); + +private: + QByteArray m_prefix; + bool m_previousIsEndingWithNewLine; +}; + +} // namespace ClangBackEnd + +#endif // PRINTLINESWITHPREFIX_H diff --git a/src/libs/clangbackendipc/projectpartcontainer.cpp b/src/libs/clangbackendipc/projectpartcontainer.cpp index 692b755eb0a..50b4bcc6a40 100644 --- a/src/libs/clangbackendipc/projectpartcontainer.cpp +++ b/src/libs/clangbackendipc/projectpartcontainer.cpp @@ -82,12 +82,19 @@ bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &se return first.projectPartId_ < second.projectPartId_; } +static Utf8String quotedArguments(const Utf8StringVector &arguments) +{ + const Utf8String quote = Utf8String::fromUtf8("\""); + const Utf8String joined = arguments.join(quote + Utf8String::fromUtf8(" ") + quote); + return quote + joined + quote; +} + QDebug operator<<(QDebug debug, const ProjectPartContainer &container) { debug.nospace() << "ProjectPartContainer(" << container.projectPartId() << "," - << container.arguments() + << quotedArguments(container.arguments()) << ")"; return debug; diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 38093f8b47b..d1ad7226718 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -1021,7 +1021,7 @@ LookupScope *LookupScope::lookupType(const Name *name, Block *block) LookupScope *LookupScope::findType(const Name *name) { ProcessedSet processed; - return d->lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ false, d); + return d->lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ true, d); } LookupScope *Internal::LookupScopePrivate::findBlock_helper( @@ -1830,6 +1830,12 @@ bool CreateBindings::visit(Template *templ) return false; } +bool CreateBindings::visit(ExplicitInstantiation *inst) +{ + Q_UNUSED(inst); + return false; +} + bool CreateBindings::visit(Namespace *ns) { LookupScope *previous = enterLookupScopeBinding(ns); diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index 0308388a3d5..8d4016dbbbb 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -178,6 +178,7 @@ protected: void process(Symbol *root); virtual bool visit(Template *templ); + virtual bool visit(ExplicitInstantiation *inst); virtual bool visit(Namespace *ns); virtual bool visit(Class *klass); virtual bool visit(ForwardClassDeclaration *klass); diff --git a/src/libs/cplusplus/TypeResolver.cpp b/src/libs/cplusplus/TypeResolver.cpp index c837c0f9389..1be33f1410d 100644 --- a/src/libs/cplusplus/TypeResolver.cpp +++ b/src/libs/cplusplus/TypeResolver.cpp @@ -154,6 +154,13 @@ QList TypeResolver::typedefsFromScopeUpToFunctionScope(const Name *n } } enclosingBlockScope = block->enclosingScope(); + if (enclosingBlockScope) { + // For lambda, step beyond the function to its enclosing block + if (Function *enclosingFunction = enclosingBlockScope->asFunction()) { + if (!enclosingFunction->name()) + enclosingBlockScope = enclosingBlockScope->enclosingScope(); + } + } } return results; } diff --git a/src/libs/sqlite/sqlite_dependencies.pri b/src/libs/sqlite/sqlite_dependencies.pri index cb383c8e63c..b55ba604116 100644 --- a/src/libs/sqlite/sqlite_dependencies.pri +++ b/src/libs/sqlite/sqlite_dependencies.pri @@ -1,3 +1,2 @@ QTC_LIB_NAME = Sqlite -INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/3rdparty/sqlite INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/sqlite diff --git a/src/libs/ssh/sshbotanconversions_p.h b/src/libs/ssh/sshbotanconversions_p.h index 31dc4899a72..3257eaf04a4 100644 --- a/src/libs/ssh/sshbotanconversions_p.h +++ b/src/libs/ssh/sshbotanconversions_p.h @@ -96,7 +96,7 @@ inline const char *botanEmsaAlgoName(const QByteArray &rfcAlgoName) return "EMSA1(SHA-1)"; if (rfcAlgoName == SshCapabilities::PubKeyRsa) return "EMSA3(SHA-1)"; - if (rfcAlgoName == SshCapabilities::PubKeyEcdsa) + if (rfcAlgoName == SshCapabilities::PubKeyEcdsa256) return "EMSA1_BSI(SHA-256)"; throw SshClientException(SshInternalError, SSH_TR("Unexpected host key algorithm \"%1\"") .arg(QString::fromLatin1(rfcAlgoName))); @@ -118,11 +118,16 @@ inline const char *botanHMacAlgoName(const QByteArray &rfcAlgoName) inline quint32 botanHMacKeyLen(const QByteArray &rfcAlgoName) { - Q_ASSERT(rfcAlgoName == SshCapabilities::HMacSha1 - || rfcAlgoName == SshCapabilities::HMacSha256); if (rfcAlgoName == SshCapabilities::HMacSha1) return 20; - return 32; + if (rfcAlgoName == SshCapabilities::HMacSha256) + return 32; + if (rfcAlgoName == SshCapabilities::HMacSha384) + return 48; + if (rfcAlgoName == SshCapabilities::HMacSha512) + return 64; + throw SshClientException(SshInternalError, SSH_TR("Unexpected hashing algorithm \"%1\"") + .arg(QString::fromLatin1(rfcAlgoName))); } } // namespace Internal diff --git a/src/libs/ssh/sshcapabilities.cpp b/src/libs/ssh/sshcapabilities.cpp index 2677768c3ab..725f01c1a0e 100644 --- a/src/libs/ssh/sshcapabilities.cpp +++ b/src/libs/ssh/sshcapabilities.cpp @@ -65,9 +65,9 @@ const QList SshCapabilities::KeyExchangeMethods = QList( const QByteArray SshCapabilities::PubKeyDss("ssh-dss"); const QByteArray SshCapabilities::PubKeyRsa("ssh-rsa"); -const QByteArray SshCapabilities::PubKeyEcdsa("ecdsa-sha2-nistp256"); +const QByteArray SshCapabilities::PubKeyEcdsa256("ecdsa-sha2-nistp256"); const QList SshCapabilities::PublicKeyAlgorithms = QList() - << SshCapabilities::PubKeyEcdsa + << SshCapabilities::PubKeyEcdsa256 << SshCapabilities::PubKeyRsa << SshCapabilities::PubKeyDss; @@ -130,5 +130,13 @@ QByteArray SshCapabilities::findBestMatch(const QList &myCapabilitie return commonCapabilities(myCapabilities, serverCapabilities).first(); } +int SshCapabilities::ecdsaIntegerWidthInBytes(const QByteArray &ecdsaAlgo) +{ + if (ecdsaAlgo == PubKeyEcdsa256) + return 32; + throw SshClientException(SshInternalError, SSH_TR("Unexpected ecdsa algorithm \"%1\"") + .arg(QString::fromLatin1(ecdsaAlgo))); +} + } // namespace Internal } // namespace QSsh diff --git a/src/libs/ssh/sshcapabilities_p.h b/src/libs/ssh/sshcapabilities_p.h index a893ccecbe3..88e26067980 100644 --- a/src/libs/ssh/sshcapabilities_p.h +++ b/src/libs/ssh/sshcapabilities_p.h @@ -50,7 +50,7 @@ public: static const QByteArray PubKeyDss; static const QByteArray PubKeyRsa; - static const QByteArray PubKeyEcdsa; + static const QByteArray PubKeyEcdsa256; static const QList PublicKeyAlgorithms; static const QByteArray CryptAlgo3DesCbc; @@ -76,6 +76,8 @@ public: const QList &serverCapabilities); static QByteArray findBestMatch(const QList &myCapabilities, const QList &serverCapabilities); + + static int ecdsaIntegerWidthInBytes(const QByteArray &ecdsaAlgo); }; } // namespace Internal diff --git a/src/libs/ssh/sshincomingpacket.cpp b/src/libs/ssh/sshincomingpacket.cpp index f2101e54dea..ea46d2066be 100644 --- a/src/libs/ssh/sshincomingpacket.cpp +++ b/src/libs/ssh/sshincomingpacket.cpp @@ -30,6 +30,7 @@ #include "sshincomingpacket_p.h" +#include "ssh_global.h" #include "sshbotanconversions_p.h" #include "sshcapabilities_p.h" @@ -169,7 +170,37 @@ SshKeyExchangeInit SshIncomingPacket::extractKeyExchangeInitData() const return exchangeData; } -SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray &pubKeyAlgo) const +static void getHostKeySpecificReplyData(SshKeyExchangeReply &replyData, + const QByteArray &hostKeyAlgo, const QByteArray &input) +{ + quint32 offset = 0; + if (hostKeyAlgo == SshCapabilities::PubKeyDss || hostKeyAlgo == SshCapabilities::PubKeyRsa) { + // DSS: p and q, RSA: e and n + replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); + replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); + + // g and y + if (hostKeyAlgo == SshCapabilities::PubKeyDss) { + replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); + replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); + } + } else { + QSSH_ASSERT_AND_RETURN(hostKeyAlgo == SshCapabilities::PubKeyEcdsa256); + if (SshPacketParser::asString(input, &offset) + != hostKeyAlgo.mid(11)) { // Without "ecdsa-sha2-" prefix. + throw SshPacketParseException(); + } + replyData.q = SshPacketParser::asString(input, &offset); + } +} + +static QByteArray &padToWidth(QByteArray &data, int targetWidth) +{ + return data.prepend(QByteArray(targetWidth - data.count(), 0)); +} + +SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray &kexAlgo, + const QByteArray &hostKeyAlgo) const { Q_ASSERT(isComplete()); Q_ASSERT(type() == SSH_MSG_KEXDH_REPLY); @@ -179,41 +210,32 @@ SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray quint32 topLevelOffset = TypeOffset + 1; replyData.k_s = SshPacketParser::asString(m_data, &topLevelOffset); quint32 k_sOffset = 0; - if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != pubKeyAlgo) + if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != hostKeyAlgo) throw SshPacketParseException(); + getHostKeySpecificReplyData(replyData, hostKeyAlgo, replyData.k_s.mid(k_sOffset)); - if (pubKeyAlgo == SshCapabilities::PubKeyDss || pubKeyAlgo == SshCapabilities::PubKeyRsa) { - - // DSS: p and q, RSA: e and n - replyData.parameters << SshPacketParser::asBigInt(replyData.k_s, &k_sOffset); - replyData.parameters << SshPacketParser::asBigInt(replyData.k_s, &k_sOffset); - - // g and y - if (pubKeyAlgo == SshCapabilities::PubKeyDss) { - replyData.parameters << SshPacketParser::asBigInt(replyData.k_s, &k_sOffset); - replyData.parameters << SshPacketParser::asBigInt(replyData.k_s, &k_sOffset); - } - + if (kexAlgo == SshCapabilities::DiffieHellmanGroup1Sha1) { replyData.f = SshPacketParser::asBigInt(m_data, &topLevelOffset); } else { - Q_ASSERT(pubKeyAlgo == SshCapabilities::PubKeyEcdsa); - if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != pubKeyAlgo.mid(11)) // Without "ecdsa-sha2-" prefix. - throw SshPacketParseException(); - replyData.q = SshPacketParser::asString(replyData.k_s, &k_sOffset); + QSSH_ASSERT_AND_RETURN_VALUE(kexAlgo.startsWith(SshCapabilities::EcdhKexNamePrefix), + SshKeyExchangeReply()); replyData.q_s = SshPacketParser::asString(m_data, &topLevelOffset); } const QByteArray fullSignature = SshPacketParser::asString(m_data, &topLevelOffset); quint32 sigOffset = 0; - if (SshPacketParser::asString(fullSignature, &sigOffset) != pubKeyAlgo) + if (SshPacketParser::asString(fullSignature, &sigOffset) != hostKeyAlgo) throw SshPacketParseException(); replyData.signatureBlob = SshPacketParser::asString(fullSignature, &sigOffset); - if (pubKeyAlgo == SshCapabilities::PubKeyEcdsa) { + if (hostKeyAlgo == SshCapabilities::PubKeyEcdsa256) { // Botan's PK_Verifier wants the signature in this format. quint32 blobOffset = 0; const Botan::BigInt r = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset); const Botan::BigInt s = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset); - replyData.signatureBlob = convertByteArray(Botan::BigInt::encode(r)); - replyData.signatureBlob += convertByteArray(Botan::BigInt::encode(s)); + const int width = SshCapabilities::ecdsaIntegerWidthInBytes(hostKeyAlgo); + QByteArray encodedR = convertByteArray(Botan::BigInt::encode(r)); + replyData.signatureBlob = padToWidth(encodedR, width); + QByteArray encodedS = convertByteArray(Botan::BigInt::encode(s)); + replyData.signatureBlob += padToWidth(encodedS, width); } replyData.k_s.prepend(m_data.mid(TypeOffset + 1, 4)); return replyData; diff --git a/src/libs/ssh/sshincomingpacket_p.h b/src/libs/ssh/sshincomingpacket_p.h index 9ea9d80278a..0b8cb183032 100644 --- a/src/libs/ssh/sshincomingpacket_p.h +++ b/src/libs/ssh/sshincomingpacket_p.h @@ -62,10 +62,10 @@ struct SshKeyExchangeInit struct SshKeyExchangeReply { QByteArray k_s; - QList parameters; // DSS: p, q, g, y. RSA: e, n. + QList hostKeyParameters; // DSS: p, q, g, y. RSA: e, n. + QByteArray q; // For ECDSA host keys only. Botan::BigInt f; // For DH only. QByteArray q_s; // For ECDH only. - QByteArray q; // For ECDH only. QByteArray signatureBlob; }; @@ -164,7 +164,8 @@ public: void reset(); SshKeyExchangeInit extractKeyExchangeInitData() const; - SshKeyExchangeReply extractKeyExchangeReply(const QByteArray &pubKeyAlgo) const; + SshKeyExchangeReply extractKeyExchangeReply(const QByteArray &kexAlgo, + const QByteArray &hostKeyAlgo) const; SshDisconnect extractDisconnect() const; SshUserAuthBanner extractUserAuthBanner() const; SshUserAuthInfoRequestPacket extractUserAuthInfoRequest() const; diff --git a/src/libs/ssh/sshkeyexchange.cpp b/src/libs/ssh/sshkeyexchange.cpp index c553ecc8b22..25da1805c8b 100644 --- a/src/libs/ssh/sshkeyexchange.cpp +++ b/src/libs/ssh/sshkeyexchange.cpp @@ -30,6 +30,7 @@ #include "sshkeyexchange_p.h" +#include "ssh_global.h" #include "sshbotanconversions_p.h" #include "sshcapabilities_p.h" #include "sshsendfacility_p.h" @@ -115,28 +116,8 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit) m_kexAlgoName = SshCapabilities::findBestMatch(SshCapabilities::KeyExchangeMethods, kexInitParams.keyAlgorithms.names); - const QList &commonHostKeyAlgos - = SshCapabilities::commonCapabilities(SshCapabilities::PublicKeyAlgorithms, - kexInitParams.serverHostKeyAlgorithms.names); - const bool ecdh = m_kexAlgoName.startsWith(SshCapabilities::EcdhKexNamePrefix); - foreach (const QByteArray &possibleHostKeyAlgo, commonHostKeyAlgos) { - if (ecdh && possibleHostKeyAlgo == SshCapabilities::PubKeyEcdsa) { - m_serverHostKeyAlgo = possibleHostKeyAlgo; - break; - } - if (!ecdh && (possibleHostKeyAlgo == SshCapabilities::PubKeyDss - || possibleHostKeyAlgo == SshCapabilities::PubKeyRsa)) { - m_serverHostKeyAlgo = possibleHostKeyAlgo; - break; - } - } - if (m_serverHostKeyAlgo.isEmpty()) { - throw SshServerException(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, - "Invalid combination of key exchange and host key algorithms.", - QCoreApplication::translate("SshConnection", - "No matching host key algorithm available for key exchange algorithm \"%1\".") - .arg(QString::fromLatin1(m_kexAlgoName))); - } + m_serverHostKeyAlgo = SshCapabilities::findBestMatch(SshCapabilities::PublicKeyAlgorithms, + kexInitParams.serverHostKeyAlgorithms.names); determineHashingAlgorithm(kexInitParams, true); determineHashingAlgorithm(kexInitParams, false); @@ -152,7 +133,7 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit) kexInitParams.compressionAlgorithmsServerToClient.names); AutoSeeded_RNG rng; - if (ecdh) { + if (m_kexAlgoName.startsWith(SshCapabilities::EcdhKexNamePrefix)) { m_ecdhKey.reset(new ECDH_PrivateKey(rng, EC_Group(botanKeyExchangeAlgoName(m_kexAlgoName)))); m_sendFacility.sendKeyEcdhInitPacket(convertByteArray(m_ecdhKey->public_value())); } else { @@ -169,7 +150,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, { const SshKeyExchangeReply &reply - = dhReply.extractKeyExchangeReply(m_serverHostKeyAlgo); + = dhReply.extractKeyExchangeReply(m_kexAlgoName, m_serverHostKeyAlgo); if (m_dhKey && (reply.f <= 0 || reply.f >= m_dhKey->group_p())) { throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, "Server sent invalid f."); @@ -187,6 +168,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, DH_KA_Operation dhOp(*m_dhKey); SecureVector encodedF = BigInt::encode(reply.f); encodedK = dhOp.agree(encodedF, encodedF.size()); + m_dhKey.reset(nullptr); } else { Q_ASSERT(m_ecdhKey); concatenatedData // Q_C. @@ -194,7 +176,9 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, concatenatedData += AbstractSshPacket::encodeString(reply.q_s); ECDH_KA_Operation ecdhOp(*m_ecdhKey); encodedK = ecdhOp.agree(convertByteArray(reply.q_s), reply.q_s.count()); + m_ecdhKey.reset(nullptr); } + const BigInt k = BigInt::decode(encodedK); m_k = AbstractSshPacket::encodeMpInt(k); // Roundtrip, as Botan encodes BigInts somewhat differently. concatenatedData += m_k; @@ -219,22 +203,22 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, QScopedPointer sigKey; if (m_serverHostKeyAlgo == SshCapabilities::PubKeyDss) { - const DL_Group group(reply.parameters.at(0), reply.parameters.at(1), - reply.parameters.at(2)); + const DL_Group group(reply.hostKeyParameters.at(0), reply.hostKeyParameters.at(1), + reply.hostKeyParameters.at(2)); DSA_PublicKey * const dsaKey - = new DSA_PublicKey(group, reply.parameters.at(3)); + = new DSA_PublicKey(group, reply.hostKeyParameters.at(3)); sigKey.reset(dsaKey); } else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyRsa) { RSA_PublicKey * const rsaKey - = new RSA_PublicKey(reply.parameters.at(1), reply.parameters.at(0)); + = new RSA_PublicKey(reply.hostKeyParameters.at(1), reply.hostKeyParameters.at(0)); sigKey.reset(rsaKey); - } else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa) { - const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(), - m_ecdhKey->domain().get_curve()); - ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(m_ecdhKey->domain(), point); - sigKey.reset(ecdsaKey); } else { - Q_ASSERT(!"Impossible: Neither DSS nor RSA nor ECDSA!"); + QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa256); + const EC_Group domain("secp256r1"); + const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(), + domain.get_curve()); + ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(domain, point); + sigKey.reset(ecdsaKey); } const byte * const botanH = convertByteArray(m_h); @@ -248,8 +232,6 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, checkHostKey(reply.k_s); m_sendFacility.sendNewKeysPacket(); - m_dhKey.reset(nullptr); - m_ecdhKey.reset(nullptr); } QByteArray SshKeyExchange::hashAlgoForKexAlgo() const diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index 47a58da50e5..44ce76feb9a 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -159,7 +159,10 @@ QString ShellCommand::displayName() const if (!d->m_jobs.isEmpty()) { const Internal::ShellCommandPrivate::Job &job = d->m_jobs.at(0); QString result = job.binary.toFileInfo().baseName(); - result[0] = result.at(0).toTitleCase(); + if (!result.isEmpty()) + result[0] = result.at(0).toTitleCase(); + else + result = tr("UNKNOWN"); if (!job.arguments.isEmpty()) result += QLatin1Char(' ') + job.arguments.at(0); diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp index 6159fcfd4e4..424bc49a246 100644 --- a/src/libs/utils/treemodel.cpp +++ b/src/libs/utils/treemodel.cpp @@ -622,6 +622,8 @@ TreeItem::TreeItem(const QStringList &displays, int flags) TreeItem::~TreeItem() { + QTC_CHECK(m_parent == 0); + QTC_CHECK(m_model == 0); removeChildren(); delete m_displays; } @@ -851,6 +853,10 @@ TreeModel::TreeModel(TreeItem *root, QObject *parent) TreeModel::~TreeModel() { + QTC_ASSERT(m_root, return); + QTC_ASSERT(m_root->m_parent == 0, return); + QTC_ASSERT(m_root->m_model == this, return); + m_root->m_model = 0; delete m_root; } @@ -966,7 +972,13 @@ int TreeModel::topLevelItemCount() const void TreeModel::setRootItem(TreeItem *item) { - delete m_root; + QTC_CHECK(m_root); + if (m_root) { + QTC_CHECK(m_root->m_parent == 0); + QTC_CHECK(m_root->m_model == this); + m_root->m_model = 0; + delete m_root; + } m_root = item; item->setModel(this); emit layoutChanged(); @@ -1049,6 +1061,7 @@ TreeItem *TreeModel::takeItem(TreeItem *item) QModelIndex idx = indexForItem(parent); beginRemoveRows(idx, pos, pos); item->m_parent = 0; + item->m_model = 0; parent->m_children.removeAt(pos); endRemoveRows(); return item; diff --git a/src/plugins/analyzerbase/analyzermanager.cpp b/src/plugins/analyzerbase/analyzermanager.cpp index 995203ca2f6..168e65fd2d8 100644 --- a/src/plugins/analyzerbase/analyzermanager.cpp +++ b/src/plugins/analyzerbase/analyzermanager.cpp @@ -155,7 +155,7 @@ public: void handleToolFinished(); void saveToolSettings(Id toolId); void loadToolSettings(Id toolId); - void startTool(); + void startCurrentTool(); void selectToolboxAction(const QString &item); void modeChanged(IMode *mode); void resetLayout(); @@ -173,10 +173,11 @@ public: ActionContainer *m_menu; QComboBox *m_toolBox; QStackedWidget *m_controlsStackWidget; - StatusLabel *m_statusLabel; + QStackedWidget *m_statusLabelsStackWidget; typedef QMap MainWindowSettingsMap; QHash > m_toolWidgets; QHash m_controlsWidgetFromTool; + QHash m_statusLabelsPerTool; MainWindowSettingsMap m_defaultSettings; // list of dock widgets to prevent memory leak @@ -198,7 +199,7 @@ AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager *qq): m_menu(0), m_toolBox(new QComboBox), m_controlsStackWidget(new QStackedWidget), - m_statusLabel(new StatusLabel) + m_statusLabelsStackWidget(new QStackedWidget) { m_toolBox->setObjectName(QLatin1String("AnalyzerManagerToolBox")); connect(m_toolBox, static_cast(&QComboBox::activated), @@ -241,7 +242,8 @@ void AnalyzerManagerPrivate::setupActions() m_startAction = new QAction(tr("Start"), m_menu); m_startAction->setIcon(QIcon(QLatin1String(ANALYZER_CONTROL_START_ICON))); ActionManager::registerAction(m_startAction, "Analyzer.Start"); - connect(m_startAction, &QAction::triggered, this, &AnalyzerManagerPrivate::startTool); + connect(m_startAction, &QAction::triggered, + this, &AnalyzerManagerPrivate::startCurrentTool); m_stopAction = new QAction(tr("Stop"), m_menu); m_stopAction->setEnabled(false); @@ -351,7 +353,7 @@ void AnalyzerManagerPrivate::createModeMainWindow() analyzeToolBarLayout->addWidget(new StyledSeparator); analyzeToolBarLayout->addWidget(m_toolBox); analyzeToolBarLayout->addWidget(m_controlsStackWidget); - analyzeToolBarLayout->addWidget(m_statusLabel); + analyzeToolBarLayout->addWidget(m_statusLabelsStackWidget); analyzeToolBarLayout->addStretch(); auto dock = new QDockWidget(tr("Analyzer Toolbar")); @@ -420,7 +422,7 @@ bool AnalyzerManagerPrivate::showPromptDialog(const QString &title, const QStrin return messageBox.clickedStandardButton() == QDialogButtonBox::Yes; } -void AnalyzerManagerPrivate::startTool() +void AnalyzerManagerPrivate::startCurrentTool() { QTC_ASSERT(m_currentAction, return); m_currentAction->startTool(); @@ -492,6 +494,9 @@ void AnalyzerManagerPrivate::selectAction(AnalyzerAction *action) QTC_CHECK(!m_controlsWidgetFromTool.contains(toolId)); m_controlsWidgetFromTool[toolId] = widget; m_controlsStackWidget->addWidget(widget); + StatusLabel * const toolStatusLabel = new StatusLabel; + m_statusLabelsPerTool[toolId] = toolStatusLabel; + m_statusLabelsStackWidget->addWidget(toolStatusLabel); } foreach (QDockWidget *widget, m_toolWidgets.value(toolId)) activateDock(Qt::DockWidgetArea(widget->property(INITIAL_DOCK_AREA).toInt()), widget); @@ -500,6 +505,7 @@ void AnalyzerManagerPrivate::selectAction(AnalyzerAction *action) QTC_CHECK(m_controlsWidgetFromTool.contains(toolId)); m_controlsStackWidget->setCurrentWidget(m_controlsWidgetFromTool.value(toolId)); + m_statusLabelsStackWidget->setCurrentWidget(m_statusLabelsPerTool.value(toolId)); m_toolBox->setCurrentIndex(toolboxIndex); updateRunActions(); @@ -539,9 +545,8 @@ void AnalyzerManagerPrivate::addAction(AnalyzerAction *action) rebuildToolBox(); connect(action, &QAction::triggered, this, [this, action] { - AnalyzerManager::showMode(); selectAction(action); - startTool(); + action->startTool(); }); } @@ -647,16 +652,15 @@ QDockWidget *AnalyzerManager::createDockWidget(Core::Id toolId, return dockWidget; } -void AnalyzerManager::selectTool(Id actionId) +void AnalyzerManager::selectAction(Id actionId, bool alsoRunIt) { - foreach (AnalyzerAction *action, d->m_actions) - if (action->actionId() == actionId) + foreach (AnalyzerAction *action, d->m_actions) { + if (action->actionId() == actionId) { d->selectAction(action); -} - -void AnalyzerManager::startTool() -{ - d->startTool(); + if (alsoRunIt) + action->startTool(); + } + } } FancyMainWindow *AnalyzerManager::mainWindow() @@ -670,14 +674,16 @@ void AnalyzerManagerPrivate::resetLayout() m_mainWindow->restoreSettings(m_defaultSettings.value(m_currentAction->toolId())); } -void AnalyzerManager::showStatusMessage(const QString &message, int timeoutMS) +void AnalyzerManager::showStatusMessage(Id toolId, const QString &message, int timeoutMS) { - d->m_statusLabel->showStatusMessage(message, timeoutMS); + StatusLabel * const statusLabel = d->m_statusLabelsPerTool.value(toolId); + QTC_ASSERT(statusLabel, return); + statusLabel->showStatusMessage(message, timeoutMS); } -void AnalyzerManager::showPermanentStatusMessage(const QString &message) +void AnalyzerManager::showPermanentStatusMessage(Id toolId, const QString &message) { - showStatusMessage(message, -1); + showStatusMessage(toolId, message, -1); } void AnalyzerManager::showMode() diff --git a/src/plugins/analyzerbase/analyzermanager.h b/src/plugins/analyzerbase/analyzermanager.h index 786589b0733..7b76e09a405 100644 --- a/src/plugins/analyzerbase/analyzermanager.h +++ b/src/plugins/analyzerbase/analyzermanager.h @@ -74,13 +74,12 @@ public: static Utils::FancyMainWindow *mainWindow(); static void showMode(); - static void selectTool(Core::Id actionId); - static void startTool(); + static void selectAction(Core::Id actionId, bool alsoRunIt = false); static void stopTool(); // Convenience functions. - static void showStatusMessage(const QString &message, int timeoutMS = 10000); - static void showPermanentStatusMessage(const QString &message); + static void showStatusMessage(Core::Id toolId, const QString &message, int timeoutMS = 10000); + static void showPermanentStatusMessage(Core::Id toolId, const QString &message); static void handleToolStarted(); static void handleToolFinished(); diff --git a/src/plugins/analyzerbase/analyzerruncontrol.cpp b/src/plugins/analyzerbase/analyzerruncontrol.cpp index 6748220743e..48f6103bccc 100644 --- a/src/plugins/analyzerbase/analyzerruncontrol.cpp +++ b/src/plugins/analyzerbase/analyzerruncontrol.cpp @@ -53,7 +53,6 @@ AnalyzerRunControl::AnalyzerRunControl(const AnalyzerStartParameters &sp, { setIcon(QLatin1String(":/images/analyzer_start_small.png")); - m_runConfig = runConfiguration; m_sp = sp; connect(this, &AnalyzerRunControl::finished, @@ -101,7 +100,7 @@ bool AnalyzerRunControl::isRunning() const QString AnalyzerRunControl::displayName() const { - return m_runConfig ? m_runConfig->displayName() : m_sp.displayName; + return m_sp.displayName; } } // namespace Analyzer diff --git a/src/plugins/analyzerbase/analyzerruncontrol.h b/src/plugins/analyzerbase/analyzerruncontrol.h index 8b294c4c85f..8d436af6e88 100644 --- a/src/plugins/analyzerbase/analyzerruncontrol.h +++ b/src/plugins/analyzerbase/analyzerruncontrol.h @@ -68,9 +68,6 @@ public: virtual void pause() {} virtual void unpause() {} - /// The active run configuration for this engine, might be zero. - ProjectExplorer::RunConfiguration *runConfiguration() const { return m_runConfig; } - /// The start parameters for this engine. const AnalyzerStartParameters &startParameters() const { return m_sp; } @@ -98,8 +95,6 @@ signals: private: bool supportsReRunning() const { return false; } - - ProjectExplorer::RunConfiguration *m_runConfig; AnalyzerStartParameters m_sp; }; } // namespace Analyzer diff --git a/src/plugins/analyzerbase/analyzerstartparameters.h b/src/plugins/analyzerbase/analyzerstartparameters.h index e03f2e92d2a..3eab41f734c 100644 --- a/src/plugins/analyzerbase/analyzerstartparameters.h +++ b/src/plugins/analyzerbase/analyzerstartparameters.h @@ -36,10 +36,11 @@ #include +#include #include #include -#include #include +#include namespace Analyzer { @@ -49,7 +50,7 @@ namespace Analyzer { class ANALYZER_EXPORT AnalyzerStartParameters { public: - ProjectExplorer::RunMode runMode; + Core::Id runMode = ProjectExplorer::Constants::NO_RUN_MODE; QSsh::SshConnectionParameters connParams; ProjectExplorer::ApplicationLauncher::Mode localRunMode = ProjectExplorer::ApplicationLauncher::Gui; diff --git a/src/plugins/analyzerbase/ianalyzertool.cpp b/src/plugins/analyzerbase/ianalyzertool.cpp index 80698e8066f..7aa6ddbfc95 100644 --- a/src/plugins/analyzerbase/ianalyzertool.cpp +++ b/src/plugins/analyzerbase/ianalyzertool.cpp @@ -89,6 +89,7 @@ void AnalyzerAction::startTool() AnalyzerManager::showMode(); TaskHub::clearTasks(Constants::ANALYZERTASK_ID); + AnalyzerManager::showPermanentStatusMessage(toolId(), QString()); if (m_toolPreparer && !m_toolPreparer()) return; diff --git a/src/plugins/analyzerbase/ianalyzertool.h b/src/plugins/analyzerbase/ianalyzertool.h index b87414bffda..f7be88476fb 100644 --- a/src/plugins/analyzerbase/ianalyzertool.h +++ b/src/plugins/analyzerbase/ianalyzertool.h @@ -86,8 +86,8 @@ public: void setToolId(Core::Id id) { m_toolId = id; } void setToolMode(ToolMode mode) { m_toolMode = mode; } - ProjectExplorer::RunMode runMode() const { return m_runMode; } - void setRunMode(ProjectExplorer::RunMode mode) { m_runMode = mode; } + Core::Id runMode() const { return m_runMode; } + void setRunMode(Core::Id mode) { m_runMode = mode; } bool isRunnable(QString *reason = 0) const; /// Creates all widgets used by the tool. @@ -119,7 +119,7 @@ protected: Core::Id m_actionId; Core::Id m_toolId; ToolMode m_toolMode; - ProjectExplorer::RunMode m_runMode; + Core::Id m_runMode; WidgetCreator m_widgetCreator; RunControlCreator m_runControlCreator; ToolStarter m_customToolStarter; diff --git a/src/plugins/android/androidanalyzesupport.cpp b/src/plugins/android/androidanalyzesupport.cpp index 9b80e3ce3c8..ff0dd9af9e6 100644 --- a/src/plugins/android/androidanalyzesupport.cpp +++ b/src/plugins/android/androidanalyzesupport.cpp @@ -52,7 +52,7 @@ namespace Android { namespace Internal { RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfiguration *runConfig, - RunMode runMode) + Core::Id runMode) { Target *target = runConfig->target(); AnalyzerStartParameters params; @@ -61,7 +61,7 @@ RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfigurati params.sysroot = SysRootKitInformation::sysRoot(target->kit()).toString(); // TODO: Not sure if these are the right paths. params.workingDirectory = target->project()->projectDirectory().toString(); - if (runMode == QmlProfilerRunMode) { + if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { QTcpServer server; QTC_ASSERT(server.listen(QHostAddress::LocalHost) || server.listen(QHostAddress::LocalHostIPv6), return 0); @@ -105,15 +105,13 @@ AndroidAnalyzeSupport::AndroidAnalyzeSupport(AndroidRunConfiguration *runConfig, }); connect(runner, &AndroidRunner::remoteErrorOutput, - [this, runControl](const QByteArray &output) { - const QString msg = QString::fromUtf8(output); + [this, runControl](const QString &msg) { runControl->logApplicationMessage(msg, Utils::StdErrFormatSameLine); m_outputParser.processOutput(msg); }); connect(runner, &AndroidRunner::remoteOutput, - [this, runControl](const QByteArray &output) { - const QString msg = QString::fromUtf8(output); + [this, runControl](const QString &msg) { runControl->logApplicationMessage(msg, Utils::StdOutFormatSameLine); m_outputParser.processOutput(msg); }); diff --git a/src/plugins/android/androidanalyzesupport.h b/src/plugins/android/androidanalyzesupport.h index 469dc7193d9..610be9a1e46 100644 --- a/src/plugins/android/androidanalyzesupport.h +++ b/src/plugins/android/androidanalyzesupport.h @@ -51,7 +51,7 @@ public: Analyzer::AnalyzerRunControl *runControl); static ProjectExplorer::RunControl *createAnalyzeRunControl(AndroidRunConfiguration *runConfig, - ProjectExplorer::RunMode runMode); + Core::Id runMode); private: QmlDebug::QmlOutputParser m_outputParser; diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 3d29386dde2..d4911d4f160 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -89,17 +89,10 @@ RunControl *AndroidDebugSupport::createDebugRunControl(AndroidRunConfiguration * params.startMode = AttachToRemoteServer; params.displayName = AndroidManager::packageName(target); params.remoteSetupNeeded = true; - params.runConfiguration = runConfig; - DebuggerRunConfigurationAspect *aspect - = runConfig->extraAspect(); + auto aspect = runConfig->extraAspect(); if (aspect->useCppDebugger()) { - params.languages |= CppLanguage; Kit *kit = target->kit(); - params.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - if (ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - params.toolChainAbi = tc->targetAbi(); params.executable = target->activeBuildConfiguration()->buildDirectory().toString() + QLatin1String("/app_process"); params.skipExecutableValidation = true; params.remoteChannel = runConfig->remoteChannel(); @@ -108,25 +101,20 @@ RunControl *AndroidDebugSupport::createDebugRunControl(AndroidRunConfiguration * params.solibSearchPath.append(qtSoPaths(version)); } if (aspect->useQmlDebugger()) { - params.languages |= QmlLanguage; QTcpServer server; QTC_ASSERT(server.listen(QHostAddress::LocalHost) || server.listen(QHostAddress::LocalHostIPv6), return 0); params.qmlServerAddress = server.serverAddress().toString(); - params.remoteSetupNeeded = true; //TODO: Not sure if these are the right paths. - params.projectSourceDirectory = target->project()->projectDirectory().toString(); Kit *kit = target->kit(); QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit); if (version) { const QString qmlQtDir = version->versionInfo().value(QLatin1String("QT_INSTALL_QML")); params.additionalSearchDirectories = QStringList(qmlQtDir); } - params.projectSourceFiles = target->project()->files(Project::ExcludeGeneratedFiles); - params.projectBuildDirectory = target->activeBuildConfiguration()->buildDirectory().toString(); } - DebuggerRunControl * const debuggerRunControl = createDebuggerRunControl(params, errorMessage); + DebuggerRunControl * const debuggerRunControl = createDebuggerRunControl(params, runConfig, errorMessage); new AndroidDebugSupport(runConfig, debuggerRunControl); return debuggerRunControl; } @@ -171,15 +159,15 @@ AndroidDebugSupport::AndroidDebugSupport(AndroidRunConfiguration *runConfig, }); connect(m_runner, &AndroidRunner::remoteErrorOutput, - [this](const QByteArray &output) { + [this](const QString &output) { QTC_ASSERT(m_runControl, return); - m_runControl->showMessage(QString::fromUtf8(output), AppError); + m_runControl->showMessage(output, AppError); }); connect(m_runner, &AndroidRunner::remoteOutput, - [this](const QByteArray &output) { + [this](const QString &output) { QTC_ASSERT(m_runControl, return); - m_runControl->showMessage(QString::fromUtf8(output), AppOutput); + m_runControl->showMessage(output, AppOutput); }); } diff --git a/src/plugins/android/androidruncontrol.cpp b/src/plugins/android/androidruncontrol.cpp index 15c15b4675c..41893846e2d 100644 --- a/src/plugins/android/androidruncontrol.cpp +++ b/src/plugins/android/androidruncontrol.cpp @@ -42,8 +42,8 @@ namespace Android { namespace Internal { AndroidRunControl::AndroidRunControl(AndroidRunConfiguration *rc) - : RunControl(rc, NormalRunMode) - , m_runner(new AndroidRunner(this, rc, NormalRunMode)) + : RunControl(rc, ProjectExplorer::Constants::NORMAL_RUN_MODE) + , m_runner(new AndroidRunner(this, rc, ProjectExplorer::Constants::NORMAL_RUN_MODE)) , m_running(false) { setIcon(QLatin1String(ProjectExplorer::Constants::ICON_RUN_SMALL)); @@ -60,10 +60,10 @@ void AndroidRunControl::start() emit started(); disconnect(m_runner, 0, this, 0); - connect(m_runner, SIGNAL(remoteErrorOutput(QByteArray)), - SLOT(handleRemoteErrorOutput(QByteArray))); - connect(m_runner, SIGNAL(remoteOutput(QByteArray)), - SLOT(handleRemoteOutput(QByteArray))); + connect(m_runner, SIGNAL(remoteErrorOutput(QString)), + SLOT(handleRemoteErrorOutput(QString))); + connect(m_runner, SIGNAL(remoteOutput(QString)), + SLOT(handleRemoteOutput(QString))); connect(m_runner, SIGNAL(remoteProcessFinished(QString)), SLOT(handleRemoteProcessFinished(QString))); appendMessage(tr("Starting remote process."), Utils::NormalMessageFormat); @@ -84,14 +84,14 @@ void AndroidRunControl::handleRemoteProcessFinished(const QString &error) emit finished(); } -void AndroidRunControl::handleRemoteOutput(const QByteArray &output) +void AndroidRunControl::handleRemoteOutput(const QString &output) { - appendMessage(QString::fromUtf8(output), Utils::StdOutFormatSameLine); + appendMessage(output, Utils::StdOutFormatSameLine); } -void AndroidRunControl::handleRemoteErrorOutput(const QByteArray &output) +void AndroidRunControl::handleRemoteErrorOutput(const QString &output) { - appendMessage(QString::fromUtf8(output), Utils::StdErrFormatSameLine); + appendMessage(output, Utils::StdErrFormatSameLine); } bool AndroidRunControl::isRunning() const diff --git a/src/plugins/android/androidruncontrol.h b/src/plugins/android/androidruncontrol.h index 085bb2d1306..cc0b815f01b 100644 --- a/src/plugins/android/androidruncontrol.h +++ b/src/plugins/android/androidruncontrol.h @@ -54,8 +54,8 @@ public: private slots: void handleRemoteProcessFinished(const QString &error); - void handleRemoteOutput(const QByteArray &output); - void handleRemoteErrorOutput(const QByteArray &output); + void handleRemoteOutput(const QString &output); + void handleRemoteErrorOutput(const QString &output); private: diff --git a/src/plugins/android/androidrunfactories.cpp b/src/plugins/android/androidrunfactories.cpp index 7e8673aa6a0..a0a5e1cf3f9 100644 --- a/src/plugins/android/androidrunfactories.cpp +++ b/src/plugins/android/androidrunfactories.cpp @@ -56,35 +56,30 @@ AndroidRunControlFactory::AndroidRunControlFactory(QObject *parent) { } -bool AndroidRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool AndroidRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != QmlProfilerRunMode) + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN + && mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { return false; + } return qobject_cast(runConfiguration); } RunControl *AndroidRunControlFactory::create(RunConfiguration *runConfig, - RunMode mode, QString *errorMessage) + Core::Id mode, QString *errorMessage) { Q_ASSERT(canRun(runConfig, mode)); AndroidRunConfiguration *rc = qobject_cast(runConfig); Q_ASSERT(rc); - switch (mode) { - case NormalRunMode: + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) return new AndroidRunControl(rc); - case DebugRunMode: + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) return AndroidDebugSupport::createDebugRunControl(rc, errorMessage); - case QmlProfilerRunMode: + if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) return AndroidAnalyzeSupport::createAnalyzeRunControl(rc, mode); - case NoRunMode: - case DebugRunModeWithBreakOnMain: - case CallgrindRunMode: - case MemcheckRunMode: - case MemcheckWithGdbRunMode: - case ClangStaticAnalyzerMode: - case PerfProfilerRunMode: - QTC_CHECK(false); // The other run modes are not supported - } + QTC_CHECK(false); // The other run modes are not supported return 0; } diff --git a/src/plugins/android/androidrunfactories.h b/src/plugins/android/androidrunfactories.h index ec3503c1518..b2940fd93c0 100644 --- a/src/plugins/android/androidrunfactories.h +++ b/src/plugins/android/androidrunfactories.h @@ -53,9 +53,9 @@ public: explicit AndroidRunControlFactory(QObject *parent = 0); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const; + Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); }; diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index d833578a795..c530d008cfb 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -125,21 +125,21 @@ static int socketHandShakePort = MIN_SOCKET_HANDSHAKE_PORT; AndroidRunner::AndroidRunner(QObject *parent, AndroidRunConfiguration *runConfig, - ProjectExplorer::RunMode runMode) + Core::Id runMode) : QThread(parent), m_handShakeMethod(SocketHandShake), m_socket(0), m_customPort(false) { m_tries = 0; Debugger::DebuggerRunConfigurationAspect *aspect = runConfig->extraAspect(); - const bool debuggingMode = runMode == ProjectExplorer::DebugRunMode; + const bool debuggingMode = (runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE || runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN); m_useCppDebugger = debuggingMode && aspect->useCppDebugger(); m_useQmlDebugger = debuggingMode && aspect->useQmlDebugger(); QString channel = runConfig->remoteChannel(); QTC_CHECK(channel.startsWith(QLatin1Char(':'))); m_localGdbServerPort = channel.mid(1).toUShort(); QTC_CHECK(m_localGdbServerPort); - m_useQmlProfiler = runMode == ProjectExplorer::QmlProfilerRunMode; + m_useQmlProfiler = runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE; if (m_useQmlDebugger || m_useQmlProfiler) { QTcpServer server; QTC_ASSERT(server.listen(QHostAddress::LocalHost) @@ -209,6 +209,21 @@ AndroidRunner::AndroidRunner(QObject *parent, } } } + + m_logCatRegExp = QRegExp(QLatin1String("[0-9\\-]*" // date + "\\s+" + "[0-9\\-:.]*"// time + "\\s*" + "(\\d*)" // pid 1. capture + "\\s+" + "\\d*" // unknown + "\\s+" + "(\\w)" // message type 2. capture + "\\s+" + "(.*): " // source 3. capture + "(.*)" // message 4. capture + "[\\n\\r]*" + )); } AndroidRunner::~AndroidRunner() @@ -526,21 +541,35 @@ void AndroidRunner::logcatProcess(const QByteArray &text, QByteArray &buffer, bo buffer.clear(); } - QByteArray pid(QString::fromLatin1("%1):").arg(m_processPID).toLatin1()); - foreach (QByteArray line, lines) { - if (!line.contains(pid)) + QString pidString = QString::number(m_processPID); + foreach (const QByteArray &msg, lines) { + const QString line = QString::fromUtf8(msg).trimmed() + QLatin1Char('\n'); + if (!line.contains(pidString)) continue; - if (line.endsWith('\r')) - line.chop(1); - line.append('\n'); - if (onlyError || line.startsWith("F/") - || line.startsWith("E/") - || line.startsWith("D/Qt") - || line.startsWith("W/")) - emit remoteErrorOutput(line); - else - emit remoteOutput(line); + if (m_logCatRegExp.exactMatch(line)) { + // Android M + if (m_logCatRegExp.cap(1) == pidString) { + const QString &messagetype = m_logCatRegExp.cap(2); + QString output = line.mid(m_logCatRegExp.pos(2)); + if (onlyError + || messagetype == QLatin1String("F") + || messagetype == QLatin1String("E") + || messagetype == QLatin1String("W") + || messagetype == QLatin1String("D")) + emit remoteErrorOutput(output); + else + emit remoteOutput(output); + } + } else { + if (onlyError || line.startsWith(_("F/")) + || line.startsWith(_("E/")) + || line.startsWith(_("D/Qt")) + || line.startsWith(_("W/"))) + emit remoteErrorOutput(line); + else + emit remoteOutput(line); + } } } diff --git a/src/plugins/android/androidrunner.h b/src/plugins/android/androidrunner.h index 1750bba43b4..8bf90f4e8a2 100644 --- a/src/plugins/android/androidrunner.h +++ b/src/plugins/android/androidrunner.h @@ -33,7 +33,7 @@ #include "androidconfigurations.h" -#include +#include #include #include @@ -58,7 +58,7 @@ class AndroidRunner : public QThread public: AndroidRunner(QObject *parent, AndroidRunConfiguration *runConfig, - ProjectExplorer::RunMode runMode); + Core::Id runMode); ~AndroidRunner(); QString displayName() const; @@ -73,8 +73,8 @@ signals: void remoteProcessStarted(int gdbServerPort, int qmlPort); void remoteProcessFinished(const QString &errString = QString()); - void remoteOutput(const QByteArray &output); - void remoteErrorOutput(const QByteArray &output); + void remoteOutput(const QString &output); + void remoteErrorOutput(const QString &output); private slots: void checkPID(); @@ -120,6 +120,7 @@ private: bool m_isBusyBox; QStringList m_selector; QMutex m_mutex; + QRegExp m_logCatRegExp; DebugHandShakeType m_handShakeMethod; QTcpSocket *m_socket; bool m_customPort; diff --git a/src/plugins/baremetal/baremetalruncontrolfactory.cpp b/src/plugins/baremetal/baremetalruncontrolfactory.cpp index e2dea237d49..8a4cb36278e 100644 --- a/src/plugins/baremetal/baremetalruncontrolfactory.cpp +++ b/src/plugins/baremetal/baremetalruncontrolfactory.cpp @@ -71,17 +71,20 @@ BareMetalRunControlFactory::~BareMetalRunControlFactory() { } -bool BareMetalRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool BareMetalRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != DebugRunModeWithBreakOnMain) + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) { return false; + } const QByteArray idStr = runConfiguration->id().name(); return runConfiguration->isEnabled() && idStr.startsWith(BareMetalRunConfiguration::IdPrefix); } RunControl *BareMetalRunControlFactory::create( - RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) + RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { QTC_ASSERT(canRun(runConfiguration, mode), return 0); @@ -119,32 +122,19 @@ RunControl *BareMetalRunControlFactory::create( DebuggerStartParameters sp; - if (const ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - sp.toolChainAbi = tc->targetAbi(); - - if (const Project *project = target->project()) { - sp.projectSourceDirectory = project->projectDirectory().toString(); - sp.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - - if (const BuildConfiguration *bc = target->activeBuildConfiguration()) { - sp.projectBuildDirectory = bc->buildDirectory().toString(); - if (const BuildStepList *bsl = bc->stepList(BareMetalGdbCommandsDeployStep::stepId())) { - foreach (const BuildStep *bs, bsl->steps()) { - const auto ds = qobject_cast(bs); - if (ds) { - if (!sp.commandsAfterConnect.endsWith("\n")) - sp.commandsAfterConnect.append("\n"); - sp.commandsAfterConnect.append(ds->gdbCommands().toLatin1()); - } + if (const BuildConfiguration *bc = target->activeBuildConfiguration()) { + if (const BuildStepList *bsl = bc->stepList(BareMetalGdbCommandsDeployStep::stepId())) { + foreach (const BuildStep *bs, bsl->steps()) { + if (auto ds = qobject_cast(bs)) { + if (!sp.commandsAfterConnect.endsWith("\n")) + sp.commandsAfterConnect.append("\n"); + sp.commandsAfterConnect.append(ds->gdbCommands().toLatin1()); } } } } sp.executable = bin; - sp.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - sp.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - sp.languages |= CppLanguage; sp.processArgs = rc->arguments(); sp.startMode = AttachToRemoteServer; sp.displayName = rc->displayName(); @@ -156,8 +146,7 @@ RunControl *BareMetalRunControlFactory::create( if (p->startupMode() == GdbServerProvider::StartupOnNetwork) sp.remoteSetupNeeded = true; - sp.runConfiguration = rc; - DebuggerRunControl *runControl = createDebuggerRunControl(sp, errorMessage); + DebuggerRunControl *runControl = createDebuggerRunControl(sp, rc, errorMessage); if (runControl && sp.remoteSetupNeeded) { const auto debugSupport = new BareMetalDebugSupport(dev, runControl); Q_UNUSED(debugSupport); diff --git a/src/plugins/baremetal/baremetalruncontrolfactory.h b/src/plugins/baremetal/baremetalruncontrolfactory.h index 68f5e15645a..55d8f4d98ea 100644 --- a/src/plugins/baremetal/baremetalruncontrolfactory.h +++ b/src/plugins/baremetal/baremetalruncontrolfactory.h @@ -47,9 +47,9 @@ class BareMetalRunControlFactory : public ProjectExplorer::IRunControlFactory public: explicit BareMetalRunControlFactory(QObject *parent = 0); ~BareMetalRunControlFactory(); - bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); }; diff --git a/src/plugins/beautifier/abstractsettings.cpp b/src/plugins/beautifier/abstractsettings.cpp index b67e57cc75f..81e6193102f 100644 --- a/src/plugins/beautifier/abstractsettings.cpp +++ b/src/plugins/beautifier/abstractsettings.cpp @@ -82,7 +82,7 @@ bool AbstractSettings::styleExists(const QString &key) const bool AbstractSettings::styleIsReadOnly(const QString &key) { - QFileInfo fi(m_styleDir.absoluteFilePath(key + m_ending)); + const QFileInfo fi(m_styleDir.absoluteFilePath(key + m_ending)); if (!fi.exists()) { // newly added style which was not saved yet., thus it is not read only. //TODO In a later version when we have predefined styles in Core::ICore::resourcePath() diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index bcfb73ec5f0..960a2fdca64 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -142,7 +142,7 @@ QString BeautifierPlugin::format(const QString &text, const Command &command, switch (command.processing()) { case Command::FileProcessing: { // Save text to temporary file - QFileInfo fi(fileName); + const QFileInfo fi(fileName); Utils::TempFileSaver sourceFile(QDir::tempPath() + QLatin1String("/qtc_beautifier_XXXXXXXX.") + fi.suffix()); sourceFile.setAutoRemove(true); @@ -396,7 +396,7 @@ void BeautifierPlugin::formatCurrentFileContinue(QObject *watcher) // Restore folded blocks const QTextDocument *doc = textEditor->document(); foreach (const int blockId, foldedBlocks) { - QTextBlock block = doc->findBlockByNumber(qMax(0, blockId)); + const QTextBlock block = doc->findBlockByNumber(qMax(0, blockId)); if (block.isValid()) TextDocumentLayout::doFoldOrUnfold(block, false); } diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp index e277c86a317..79eee4a1356 100644 --- a/src/plugins/beautifier/clangformat/clangformat.cpp +++ b/src/plugins/beautifier/clangformat/clangformat.cpp @@ -112,11 +112,12 @@ void ClangFormat::formatFile() void ClangFormat::formatSelectedText() { - TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget(); + const TextEditor::TextEditorWidget *widget + = TextEditor::TextEditorWidget::currentTextEditorWidget(); if (!widget) return; - QTextCursor tc = widget->textCursor(); + const QTextCursor tc = widget->textCursor(); if (tc.hasSelection()) { const int offset = tc.selectionStart(); const int length = tc.selectionEnd() - offset; diff --git a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp index f271a2ffa2c..32fb362f05a 100644 --- a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp +++ b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp @@ -69,7 +69,7 @@ ClangFormatOptionsPageWidget::~ClangFormatOptionsPageWidget() void ClangFormatOptionsPageWidget::restore() { ui->command->setPath(m_settings->command()); - int textIndex = ui->predefinedStyle->findText(m_settings->predefinedStyle()); + const int textIndex = ui->predefinedStyle->findText(m_settings->predefinedStyle()); if (textIndex != -1) ui->predefinedStyle->setCurrentIndex(textIndex); ui->formatEntireFileFallback->setChecked(m_settings->formatEntireFileFallback()); diff --git a/src/plugins/beautifier/configurationdialog.cpp b/src/plugins/beautifier/configurationdialog.cpp index 572a7182331..9d010419d36 100644 --- a/src/plugins/beautifier/configurationdialog.cpp +++ b/src/plugins/beautifier/configurationdialog.cpp @@ -137,9 +137,7 @@ QString ConfigurationDialog::value() const void ConfigurationDialog::updateOkButton() { const QString key = ui->name->text().simplified(); - bool exists = false; - if (m_settings && key != m_currentKey) - exists = m_settings->styleExists(key); + const bool exists = m_settings && key != m_currentKey && m_settings->styleExists(key); ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!(key.isEmpty() || exists)); } diff --git a/src/plugins/beautifier/configurationeditor.cpp b/src/plugins/beautifier/configurationeditor.cpp index f435409cfa7..a9b113569c5 100644 --- a/src/plugins/beautifier/configurationeditor.cpp +++ b/src/plugins/beautifier/configurationeditor.cpp @@ -139,7 +139,7 @@ void ConfigurationEditor::setCommentExpression(const QRegExp &rx) bool ConfigurationEditor::eventFilter(QObject *object, QEvent *event) { if (event->type() == QEvent::ShortcutOverride) { - QKeyEvent *key = static_cast(event); + const QKeyEvent *key = static_cast(event); if (key->key() == Qt::Key_Escape) { event->accept(); m_completer->popup()->hide(); @@ -176,7 +176,7 @@ void ConfigurationEditor::keyPressEvent(QKeyEvent *event) QPlainTextEdit::keyPressEvent(event); const int cursorPosition = textCursor().position(); - QTextCursor cursor = cursorForTextUnderCursor(); + const QTextCursor cursor = cursorForTextUnderCursor(); const QString prefix = cursor.selectedText(); if (!isShortcut && (prefix.length() < 2 || cursorPosition != cursor.position())) { diff --git a/src/plugins/beautifier/configurationpanel.cpp b/src/plugins/beautifier/configurationpanel.cpp index cd8a148aca0..01162eeda80 100644 --- a/src/plugins/beautifier/configurationpanel.cpp +++ b/src/plugins/beautifier/configurationpanel.cpp @@ -65,7 +65,7 @@ void ConfigurationPanel::setSettings(AbstractSettings *settings) void ConfigurationPanel::setCurrentConfiguration(const QString &text) { - int textIndex = ui->configurations->findText(text); + const int textIndex = ui->configurations->findText(text); if (textIndex != -1) ui->configurations->setCurrentIndex(textIndex); } @@ -117,7 +117,7 @@ void ConfigurationPanel::populateConfigurations(const QString &key) const QString currentText = (!key.isEmpty()) ? key : ui->configurations->currentText(); ui->configurations->clear(); ui->configurations->addItems(m_settings->styles()); - int textIndex = ui->configurations->findText(currentText); + const int textIndex = ui->configurations->findText(currentText); if (textIndex != -1) ui->configurations->setCurrentIndex(textIndex); updateButtons(); diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp index a501a6c209f..10cbbd9860d 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp @@ -130,7 +130,8 @@ void Uncrustify::formatSelectedText() return; } - TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget(); + const TextEditor::TextEditorWidget *widget + = TextEditor::TextEditorWidget::currentTextEditorWidget(); if (!widget) return; diff --git a/src/plugins/clangcodemodel/clangcompletion.cpp b/src/plugins/clangcodemodel/clangcompletion.cpp index 9d358231c66..25c18b905b6 100644 --- a/src/plugins/clangcodemodel/clangcompletion.cpp +++ b/src/plugins/clangcodemodel/clangcompletion.cpp @@ -299,10 +299,9 @@ namespace Internal { // ----------------------------- // ClangCompletionAssistProvider // ----------------------------- -ClangCompletionAssistProvider::ClangCompletionAssistProvider(IpcCommunicator::Ptr ipcCommunicator) +ClangCompletionAssistProvider::ClangCompletionAssistProvider(IpcCommunicator &ipcCommunicator) : m_ipcCommunicator(ipcCommunicator) { - QTC_CHECK(m_ipcCommunicator); } IAssistProvider::RunType ClangCompletionAssistProvider::runType() const @@ -642,7 +641,7 @@ const TextEditor::TextEditorWidget *ClangCompletionAssistInterface::textEditorWi } ClangCompletionAssistInterface::ClangCompletionAssistInterface( - IpcCommunicator::Ptr ipcCommunicator, + IpcCommunicator &ipcCommunicator, const TextEditorWidget *textEditorWidget, int position, const QString &fileName, @@ -661,7 +660,7 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface( m_unsavedFiles = Utils::createUnsavedFiles(mmi->workingCopy()); } -IpcCommunicator::Ptr ClangCompletionAssistInterface::ipcCommunicator() const +IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const { return m_ipcCommunicator; } @@ -1111,8 +1110,8 @@ void ClangCompletionAssistProcessor::sendFileContent(const QString &projectFileP : modifiedFileContent; const bool hasUnsavedContent = true; // TODO - IpcCommunicator::Ptr ipcCommunicator = m_interface->ipcCommunicator(); - ipcCommunicator->registerFilesForCodeCompletion( + IpcCommunicator &ipcCommunicator = m_interface->ipcCommunicator(); + ipcCommunicator.registerFilesForCodeCompletion( {FileContainer(filePath, projectFilePath, Utf8String::fromByteArray(unsavedContent), @@ -1129,7 +1128,7 @@ void ClangCompletionAssistProcessor::sendCompletionRequest(int position, const QString filePath = m_interface->fileName(); const QString projectFilePath = Utils::projectFilePathForFile(filePath); sendFileContent(projectFilePath, modifiedFileContent); - m_interface->ipcCommunicator()->completeCode(this, filePath, line, column, projectFilePath); + m_interface->ipcCommunicator().completeCode(this, filePath, line, column, projectFilePath); } TextEditor::IAssistProposal *ClangCompletionAssistProcessor::createProposal() const diff --git a/src/plugins/clangcodemodel/clangcompletion.h b/src/plugins/clangcodemodel/clangcompletion.h index 09f551a2f01..4d8ddfcf3fe 100644 --- a/src/plugins/clangcodemodel/clangcompletion.h +++ b/src/plugins/clangcodemodel/clangcompletion.h @@ -60,7 +60,7 @@ class ClangCompletionAssistProvider : public CppTools::CppCompletionAssistProvid Q_OBJECT public: - ClangCompletionAssistProvider(IpcCommunicator::Ptr ipcCommunicator); + ClangCompletionAssistProvider(IpcCommunicator &ipcCommunicator); IAssistProvider::RunType runType() const override; @@ -73,7 +73,7 @@ public: TextEditor::AssistReason reason) const override; private: - IpcCommunicator::Ptr m_ipcCommunicator; + IpcCommunicator &m_ipcCommunicator; }; class ClangAssistProposalItem : public TextEditor::AssistProposalItem @@ -117,7 +117,7 @@ private: class ClangCompletionAssistInterface: public TextEditor::AssistInterface { public: - ClangCompletionAssistInterface(ClangCodeModel::Internal::IpcCommunicator::Ptr ipcCommunicator, + ClangCompletionAssistInterface(ClangCodeModel::Internal::IpcCommunicator &ipcCommunicator, const TextEditor::TextEditorWidget *textEditorWidget, int position, const QString &fileName, @@ -126,7 +126,7 @@ public: const Internal::PchInfo::Ptr &pchInfo, const CPlusPlus::LanguageFeatures &features); - ClangCodeModel::Internal::IpcCommunicator::Ptr ipcCommunicator() const; + ClangCodeModel::Internal::IpcCommunicator &ipcCommunicator() const; const ClangCodeModel::Internal::UnsavedFiles &unsavedFiles() const; bool objcEnabled() const; const CppTools::ProjectPart::HeaderPaths &headerPaths() const; @@ -136,7 +136,7 @@ public: void setHeaderPaths(const CppTools::ProjectPart::HeaderPaths &headerPaths); // For tests private: - ClangCodeModel::Internal::IpcCommunicator::Ptr m_ipcCommunicator; + ClangCodeModel::Internal::IpcCommunicator &m_ipcCommunicator; ClangCodeModel::Internal::UnsavedFiles m_unsavedFiles; QStringList m_options; CppTools::ProjectPart::HeaderPaths m_headerPaths; diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 368236c7666..090a0cf06de 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -137,7 +137,7 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor() projectFilePath = projectPart->projectFile; // OK, Project Part is still loaded QTC_ASSERT(m_modelManagerSupport, return); - m_modelManagerSupport->ipcCommunicator()->unregisterFilesForCodeCompletion( + m_modelManagerSupport->ipcCommunicator().unregisterFilesForCodeCompletion( {ClangBackEnd::FileContainer(filePath(), projectFilePath)}); } @@ -167,6 +167,12 @@ void ClangEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force) m_builtinProcessor.recalculateSemanticInfoDetached(force); } +void ClangEditorDocumentProcessor::semanticRehighlight() +{ + m_semanticHighlighter.updateFormatMapFromFontSettings(); + m_semanticHighlighter.run(); +} + CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo() { return m_builtinProcessor.recalculateSemanticInfo(); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 508c235d1fe..d62ff455d12 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -56,6 +56,7 @@ public: // BaseEditorDocumentProcessor interface void run() override; + void semanticRehighlight() override; void recalculateSemanticInfoDetached(bool force) override; CppTools::SemanticInfo recalculateSemanticInfo() override; CppTools::BaseEditorDocumentParser *parser() override; diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 5a15dad80f3..b829c8fbaa1 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -58,8 +58,7 @@ static CppTools::CppModelManager *cppModelManager() } ModelManagerSupportClang::ModelManagerSupportClang() - : m_ipcCommunicator(new IpcCommunicator) - , m_completionAssistProvider(new ClangCompletionAssistProvider(m_ipcCommunicator)) + : m_completionAssistProvider(m_ipcCommunicator) { QTC_CHECK(!m_instance); m_instance = this; @@ -84,7 +83,7 @@ ModelManagerSupportClang::~ModelManagerSupportClang() CppTools::CppCompletionAssistProvider *ModelManagerSupportClang::completionAssistProvider() { - return m_completionAssistProvider.data(); + return &m_completionAssistProvider; } CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor( @@ -98,7 +97,7 @@ void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *newCurrent) // If we switch away from a cpp editor, update the backend about // the document's unsaved content. if (m_previousCppEditor && m_previousCppEditor->document()->isModified()) { - m_ipcCommunicator->updateUnsavedFileFromCppEditorDocument( + m_ipcCommunicator.updateUnsavedFileFromCppEditorDocument( m_previousCppEditor->document()->filePath().toString()); } @@ -138,20 +137,20 @@ void ModelManagerSupportClang::onCppDocumentReloadFinished(bool success) return; Core::IDocument *document = qobject_cast(sender()); - m_ipcCommunicator->updateUnsavedFileIfNotCurrentDocument(document); + m_ipcCommunicator.updateUnsavedFileIfNotCurrentDocument(document); } void ModelManagerSupportClang::onCppDocumentContentsChanged() { Core::IDocument *document = qobject_cast(sender()); - m_ipcCommunicator->updateUnsavedFileIfNotCurrentDocument(document); + m_ipcCommunicator.updateUnsavedFileIfNotCurrentDocument(document); } void ModelManagerSupportClang::onAbstractEditorSupportContentsUpdated(const QString &filePath, const QByteArray &content) { QTC_ASSERT(!filePath.isEmpty(), return); - m_ipcCommunicator->updateUnsavedFile(filePath, content); + m_ipcCommunicator.updateUnsavedFile(filePath, content); } void ModelManagerSupportClang::onAbstractEditorSupportRemoved(const QString &filePath) @@ -159,7 +158,7 @@ void ModelManagerSupportClang::onAbstractEditorSupportRemoved(const QString &fil QTC_ASSERT(!filePath.isEmpty(), return); if (!cppModelManager()->cppEditorDocument(filePath)) { const QString projectFilePath = Utils::projectFilePathForFile(filePath); - m_ipcCommunicator->unregisterFilesForCodeCompletion( + m_ipcCommunicator.unregisterFilesForCodeCompletion( {ClangBackEnd::FileContainer(filePath, projectFilePath)}); } } @@ -169,12 +168,12 @@ void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *p QTC_ASSERT(project, return); const CppTools::ProjectInfo projectInfo = cppModelManager()->projectInfo(project); QTC_ASSERT(projectInfo.isValid(), return); - m_ipcCommunicator->registerProjectsParts(projectInfo.projectParts()); + m_ipcCommunicator.registerProjectsParts(projectInfo.projectParts()); } void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectFiles) { - m_ipcCommunicator->unregisterProjectPartsForCodeCompletion(projectFiles); + m_ipcCommunicator.unregisterProjectPartsForCodeCompletion(projectFiles); } ModelManagerSupportClang *ModelManagerSupportClang::instance() @@ -182,7 +181,7 @@ ModelManagerSupportClang *ModelManagerSupportClang::instance() return m_instance; } -IpcCommunicator::Ptr ModelManagerSupportClang::ipcCommunicator() +IpcCommunicator &ModelManagerSupportClang::ipcCommunicator() { return m_ipcCommunicator; } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 9ff74440f84..05ea7f74fe1 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -58,7 +58,7 @@ public: CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) override; - IpcCommunicator::Ptr ipcCommunicator(); + IpcCommunicator &ipcCommunicator(); public: // for tests static ModelManagerSupportClang *instance(); @@ -75,8 +75,8 @@ private: void onProjectPartsUpdated(ProjectExplorer::Project *project); void onProjectPartsRemoved(const QStringList &projectFiles); - IpcCommunicator::Ptr m_ipcCommunicator; - QScopedPointer m_completionAssistProvider; + IpcCommunicator m_ipcCommunicator; + ClangCompletionAssistProvider m_completionAssistProvider; QPointer m_previousCppEditor; }; diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index bc2e3341931..582ed43d782 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -58,20 +58,6 @@ namespace Utils { Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun") -namespace { -bool isBlacklisted(const QString &path) -{ - static QStringList blacklistedPaths = QStringList() - << QLatin1String("lib/gcc/i686-apple-darwin"); - - foreach (const QString &blacklisted, blacklistedPaths) - if (path.contains(blacklisted)) - return true; - - return false; -} -} // anonymous namespace - UnsavedFiles createUnsavedFiles(WorkingCopy workingCopy) { // TODO: change the modelmanager to hold one working copy, and amend it every time we ask for one. @@ -132,6 +118,72 @@ static bool maybeIncludeBorlandExtensions() #endif } +class LibClangOptionsBuilder : public CompilerOptionsBuilder +{ +public: + static QStringList build(const ProjectPart::Ptr &pPart, ProjectFile::Kind fileKind) + { + if (pPart.isNull()) + return QStringList(); + + LibClangOptionsBuilder optionsBuilder(pPart); + + if (verboseRunLog().isDebugEnabled()) + optionsBuilder.add(QLatin1String("-v")); + + optionsBuilder.addLanguageOption(fileKind); + optionsBuilder.addOptionsForLanguage(maybeIncludeBorlandExtensions()); + optionsBuilder.addToolchainAndProjectDefines(); + + static const QString resourceDir = getResourceDir(); + if (!resourceDir.isEmpty()) { + optionsBuilder.add(QLatin1String("-nostdlibinc")); + optionsBuilder.add(QLatin1String("-I") + resourceDir); + optionsBuilder.add(QLatin1String("-undef")); + } + + optionsBuilder.addHeaderPathOptions(); + + // Inject header file + static const QString injectedHeader = ICore::instance()->resourcePath() + + QLatin1String("/cplusplus/qt%1-qobjectdefs-injected.h"); + +// if (pPart->qtVersion == ProjectPart::Qt4) { +// builder.addOption(QLatin1String("-include")); +// builder.addOption(injectedHeader.arg(QLatin1Char('4'))); +// } + + if (pPart->qtVersion == ProjectPart::Qt5) { + optionsBuilder.add(QLatin1String("-include")); + optionsBuilder.add(injectedHeader.arg(QLatin1Char('5'))); + } + + if (!pPart->projectConfigFile.isEmpty()) { + optionsBuilder.add(QLatin1String("-include")); + optionsBuilder.add(pPart->projectConfigFile); + } + + optionsBuilder.add(QLatin1String("-fmessage-length=0")); + optionsBuilder.add(QLatin1String("-fdiagnostics-show-note-include-stack")); + optionsBuilder.add(QLatin1String("-fmacro-backtrace-limit=0")); + optionsBuilder.add(QLatin1String("-fretain-comments-from-system-headers")); + // TODO: -Xclang -ferror-limit -Xclang 0 ? + + return optionsBuilder.options(); + } + +private: + LibClangOptionsBuilder(const CppTools::ProjectPart::Ptr &projectPart) + : CompilerOptionsBuilder(projectPart) + { + } + + bool excludeHeaderPath(const QString &path) const override + { + return path.contains(QLatin1String("lib/gcc/i686-apple-darwin")); + } +}; + /** * @brief Creates list of command-line arguments required for correct parsing * @param pPart Null if file isn't part of any project @@ -139,49 +191,7 @@ static bool maybeIncludeBorlandExtensions() */ QStringList createClangOptions(const ProjectPart::Ptr &pPart, ProjectFile::Kind fileKind) { - QStringList result; - if (pPart.isNull()) - return result; - - if (verboseRunLog().isDebugEnabled()) - result << QLatin1String("-v"); - - const bool objcExt = pPart->languageExtensions & ProjectPart::ObjectiveCExtensions; - result << CompilerOptionsBuilder::createLanguageOption(fileKind, objcExt); - result << CompilerOptionsBuilder::createOptionsForLanguage( - pPart->languageVersion, - pPart->languageExtensions, - maybeIncludeBorlandExtensions()); - result << CompilerOptionsBuilder::createDefineOptions(pPart->toolchainDefines); - result << CompilerOptionsBuilder::createDefineOptions(pPart->projectDefines); - - static const QString resourceDir = getResourceDir(); - if (!resourceDir.isEmpty()) { - result << QLatin1String("-nostdlibinc"); - result << (QLatin1String("-I") + resourceDir); - result << QLatin1String("-undef"); - } - - result << CompilerOptionsBuilder::createHeaderPathOptions(pPart->headerPaths, isBlacklisted); - - // Inject header file - static const QString injectedHeader = ICore::instance()->resourcePath() - + QLatin1String("/cplusplus/qt%1-qobjectdefs-injected.h"); -// if (qtVersion == ProjectPart::Qt4) -// opts << QLatin1String("-include") << injectedHeader.arg(QLatin1Char('4')); - if (pPart->qtVersion == ProjectPart::Qt5) - result << QLatin1String("-include") << injectedHeader.arg(QLatin1Char('5')); - - if (!pPart->projectConfigFile.isEmpty()) - result << QLatin1String("-include") << pPart->projectConfigFile; - - result << QLatin1String("-fmessage-length=0"); - result << QLatin1String("-fdiagnostics-show-note-include-stack"); - result << QLatin1String("-fmacro-backtrace-limit=0"); - result << QLatin1String("-fretain-comments-from-system-headers"); - // TODO: -Xclang -ferror-limit -Xclang 0 ? - - return result; + return LibClangOptionsBuilder::build(pPart, fileKind); } /// @return Option to speed up parsing with precompiled header diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 29b74815ddf..f5b000e5f53 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -241,13 +241,12 @@ class ChangeIpcSender public: ChangeIpcSender(IpcSenderInterface *ipcSender) { - m_previousSender = ModelManagerSupportClang::instance()->ipcCommunicator() - ->setIpcSender(ipcSender); + m_previousSender = ModelManagerSupportClang::instance()->ipcCommunicator().setIpcSender(ipcSender); } ~ChangeIpcSender() { - ModelManagerSupportClang::instance()->ipcCommunicator()->setIpcSender(m_previousSender); + ModelManagerSupportClang::instance()->ipcCommunicator().setIpcSender(m_previousSender); } private: @@ -941,9 +940,9 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart() spy.senderLog.clear(); // Kill backend process... - IpcCommunicator::Ptr ipcCommunicator = ModelManagerSupportClang::instance()->ipcCommunicator(); - ipcCommunicator->killBackendProcess(); - QSignalSpy waitForReinitializedBackend(ipcCommunicator.data(), + IpcCommunicator &ipcCommunicator = ModelManagerSupportClang::instance()->ipcCommunicator(); + ipcCommunicator.killBackendProcess(); + QSignalSpy waitForReinitializedBackend(&ipcCommunicator, SIGNAL(backendReinitialized())); QVERIFY(waitForReinitializedBackend.wait()); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 2a6c517f61a..528d7b02260 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -398,7 +398,7 @@ QDebug operator<<(QDebug d, const Context &context) { d << "CONTEXT: "; foreach (Id id, context) - d << " " << id.uniqueIdentifier() << " " << id.toString(); + d << " " << id.toString(); return d; } diff --git a/src/plugins/coreplugin/actionmanager/command.cpp b/src/plugins/coreplugin/actionmanager/command.cpp index afe18114638..d9db3c57faf 100644 --- a/src/plugins/coreplugin/actionmanager/command.cpp +++ b/src/plugins/coreplugin/actionmanager/command.cpp @@ -305,8 +305,7 @@ static QString msgActionWarning(QAction *newAction, Id id, QAction *oldAction) << ": Action "; if (oldAction) str << oldAction->objectName() << '/' << oldAction->text(); - str << " is already registered for context " << id.uniqueIdentifier() << ' ' - << id.toString() << '.'; + str << " is already registered for context " << id.toString() << '.'; return msg; } diff --git a/src/plugins/coreplugin/featureprovider.cpp b/src/plugins/coreplugin/featureprovider.cpp index 3b32e59e151..4e4bc061b8a 100644 --- a/src/plugins/coreplugin/featureprovider.cpp +++ b/src/plugins/coreplugin/featureprovider.cpp @@ -86,8 +86,7 @@ \brief The FeatureSet class is a set of available or required feature sets. This class behaves similarly to QFlags. However, instead of enums, Features - relies on string ids - and is therefore extendable. + relies on string ids and is therefore extendable. \sa Core::Feature \sa Core::IWizard @@ -106,3 +105,39 @@ Returns true if all \a features are available. */ + +Core::Feature Core::Feature::versionedFeature(const QByteArray &prefix, int major, int minor) +{ + if (major < 0) + return Feature::fromName(prefix); + + QByteArray result = prefix + '.'; + result += QString::number(major).toLatin1(); + + if (minor < 0) + return Feature::fromName(result); + return Feature::fromName(result + '.' + QString::number(minor).toLatin1()); +} + +Core::FeatureSet Core::FeatureSet::versionedFeatures(const QByteArray &prefix, int major, int minor) +{ + FeatureSet result; + result |= Feature::fromName(prefix); + + if (major < 0) + return result; + + const QByteArray majorStr = QString::number(major).toLatin1(); + const QByteArray featureMajor = prefix + majorStr; + const QByteArray featureDotMajor = prefix + '.' + majorStr; + + result |= Feature::fromName(featureMajor) | Feature::fromName(featureDotMajor); + + for (int i = 0; i <= minor; ++i) { + const QByteArray minorStr = QString::number(i).toLatin1(); + result |= Feature::fromName(featureMajor + '.' + minorStr) + | Feature::fromName(featureDotMajor + '.' + minorStr); + } + + return result; +} diff --git a/src/plugins/coreplugin/featureprovider.h b/src/plugins/coreplugin/featureprovider.h index 8155653fa10..fc16ac6bdc6 100644 --- a/src/plugins/coreplugin/featureprovider.h +++ b/src/plugins/coreplugin/featureprovider.h @@ -55,32 +55,34 @@ public: class CORE_EXPORT Feature : public Id { public: - Feature(Id id) : Id(id) {} + Feature() = default; + template Feature(const char(&ch)[N]) : Id(ch) { } + + static Feature fromString(const QString &str) { return Feature(Id::fromString(str)); } + static Feature fromName(const QByteArray &ba) { return Feature(Id::fromName(ba)); } + + static Feature versionedFeature(const QByteArray &prefix, int major = -1, int minor = -1); + +private: + explicit Feature(const Id id) : Id(id) { } }; class CORE_EXPORT FeatureSet : private QSet { public: - FeatureSet() {} - - FeatureSet(Id id) + explicit FeatureSet(Feature id) { if (id.isValid()) insert(id); } - FeatureSet(const FeatureSet &other) : QSet(other) {} + FeatureSet() = default; + FeatureSet(const FeatureSet &other) = default; + FeatureSet &operator=(const FeatureSet &other) = default; - FeatureSet &operator=(const FeatureSet &other) - { - QSet::operator=(other); - return *this; - } + static FeatureSet versionedFeatures(const QByteArray &prefix, int major, int minor = -1); - bool isEmpty() const - { - return QSet::isEmpty(); - } + using QSet::isEmpty; bool contains(const Feature &feature) const { @@ -144,7 +146,7 @@ public: { FeatureSet features; foreach (const QString &i, list) - features |= Feature(Id::fromString(i)); + features |= Feature::fromString(i); return features; } }; diff --git a/src/plugins/coreplugin/modemanager.cpp b/src/plugins/coreplugin/modemanager.cpp index a4565c34138..a9b7e59d8fd 100644 --- a/src/plugins/coreplugin/modemanager.cpp +++ b/src/plugins/coreplugin/modemanager.cpp @@ -44,13 +44,11 @@ #include +#include #include #include #include -#include -#include - namespace Core { /*! @@ -70,7 +68,6 @@ struct ModeManagerPrivate QMap m_actions; QVector m_modes; QVector m_modeCommands; - QSignalMapper *m_signalMapper; Context m_addedContexts; int m_oldCurrent; bool m_modeSelectorVisible; @@ -96,7 +93,6 @@ ModeManager::ModeManager(Internal::MainWindow *mainWindow, d = new ModeManagerPrivate(); d->m_mainWindow = mainWindow; d->m_modeStack = modeStack; - d->m_signalMapper = new QSignalMapper(this); d->m_oldCurrent = -1; d->m_actionBar = new Internal::FancyActionBar(modeStack); d->m_modeStack->addCornerWidget(d->m_actionBar); @@ -105,7 +101,6 @@ ModeManager::ModeManager(Internal::MainWindow *mainWindow, connect(d->m_modeStack, SIGNAL(currentAboutToShow(int)), SLOT(currentTabAboutToChange(int))); connect(d->m_modeStack, SIGNAL(currentChanged(int)), SLOT(currentTabChanged(int))); - connect(d->m_signalMapper, SIGNAL(mapped(int)), this, SLOT(slotActivateMode(int))); } void ModeManager::init() @@ -139,12 +134,6 @@ IMode *ModeManager::mode(Id id) return 0; } -void ModeManager::slotActivateMode(int id) -{ - m_instance->activateMode(Id::fromUniqueIdentifier(id)); - ICore::raiseWindow(d->m_modeStack); -} - void ModeManager::activateMode(Id id) { const int index = indexOf(id); @@ -190,8 +179,12 @@ void ModeManager::objectAdded(QObject *obj) currentCmd->setKeySequence(currentCmd->defaultKeySequence()); } - d->m_signalMapper->setMapping(action, mode->id().uniqueIdentifier()); - connect(action, SIGNAL(triggered()), d->m_signalMapper, SLOT(map())); + Id id = mode->id(); + connect(action, &QAction::triggered, [id] { + m_instance->activateMode(id); + ICore::raiseWindow(d->m_modeStack); + }); + connect(mode, SIGNAL(enabledStateChanged(bool)), m_instance, SLOT(enabledStateChanged())); } diff --git a/src/plugins/coreplugin/modemanager.h b/src/plugins/coreplugin/modemanager.h index 77d2e31f6c6..4b34fab385b 100644 --- a/src/plugins/coreplugin/modemanager.h +++ b/src/plugins/coreplugin/modemanager.h @@ -75,7 +75,6 @@ signals: void currentModeChanged(Core::IMode *mode, Core::IMode *oldMode = 0); private slots: - void slotActivateMode(int id); void objectAdded(QObject *obj); void aboutToRemoveObject(QObject *obj); void currentTabAboutToChange(int index); diff --git a/src/plugins/cpaster/frontend/frontend.pro b/src/plugins/cpaster/frontend/frontend.pro index ea810e3a607..4f0f39b45cc 100644 --- a/src/plugins/cpaster/frontend/frontend.pro +++ b/src/plugins/cpaster/frontend/frontend.pro @@ -1,4 +1,3 @@ -TEMPLATE = app TARGET=cpaster QTC_LIB_DEPENDS += \ @@ -7,16 +6,11 @@ QTC_LIB_DEPENDS += \ QTC_PLUGIN_DEPENDS += \ coreplugin -include(../../../../qtcreator.pri) -include(../../../rpath.pri) +include(../../../qtcreatortool.pri) -CONFIG += console -CONFIG -= app_bundle QT += network -QMAKE_RPATHDIR *= $$IDE_PLUGIN_PATH - -DESTDIR=$$IDE_LIBEXEC_PATH +linux-*: QMAKE_LFLAGS += -Wl,-z,origin \'-Wl,-rpath,\$\$ORIGIN/$$relative_path($$IDE_PLUGIN_PATH, $$DESTDIR)\' HEADERS = ../protocol.h \ ../cpasterconstants.h \ diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index cf309c2969e..c04630a0793 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -229,7 +229,7 @@ void CppEditorWidget::finalizeInitializationAfterDuplication(TextEditorWidget *o if (cppEditorWidget->isSemanticInfoValidExceptLocalUses()) updateSemanticInfo(cppEditorWidget->semanticInfo()); d->m_cppEditorOutline->update(); - const ExtraSelectionKind selectionKind = CodeWarningsSelection; + const Id selectionKind = CodeWarningsSelection; setExtraSelections(selectionKind, cppEditorWidget->extraSelections(selectionKind)); } @@ -723,6 +723,14 @@ FollowSymbolUnderCursor *CppEditorWidget::followSymbolUnderCursorDelegate() return d->m_followSymbolUnderCursor.data(); } +void CppEditorWidget::encourageApply() +{ + if (d->m_localRenaming.encourageApply()) + return; + + TextEditorWidget::encourageApply(); +} + void CppEditorWidget::abortDeclDefLink() { if (!d->m_declDefLink) diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 41002e77790..489a04216d7 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -83,6 +83,8 @@ public: FollowSymbolUnderCursor *followSymbolUnderCursorDelegate(); // exposed for tests + void encourageApply() override; + public slots: void paste() override; void cut() override; diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index dec8995138a..77bffc7338c 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -169,6 +169,8 @@ void CppEditorDocument::applyFontSettings() } } TextDocument::applyFontSettings(); // rehighlights and updates additional formats + if (m_processor) + m_processor->semanticRehighlight(); } void CppEditorDocument::invalidateFormatterCache() diff --git a/src/plugins/cppeditor/cpplocalrenaming.cpp b/src/plugins/cppeditor/cpplocalrenaming.cpp index ab267df0b82..733005b8d66 100644 --- a/src/plugins/cppeditor/cpplocalrenaming.cpp +++ b/src/plugins/cppeditor/cpplocalrenaming.cpp @@ -210,6 +210,14 @@ bool CppLocalRenaming::handleKeyPressEvent(QKeyEvent *e) return true; } +bool CppLocalRenaming::encourageApply() +{ + if (!isActive()) + return false; + finishRenameChange(); + return true; +} + QTextEdit::ExtraSelection &CppLocalRenaming::renameSelection() { return m_selections[m_renameSelectionIndex]; diff --git a/src/plugins/cppeditor/cpplocalrenaming.h b/src/plugins/cppeditor/cpplocalrenaming.h index de6fd9ecf94..b23e4c5f5db 100644 --- a/src/plugins/cppeditor/cpplocalrenaming.h +++ b/src/plugins/cppeditor/cpplocalrenaming.h @@ -61,6 +61,8 @@ public: // to BaseTextEditorWidget::keyPressEvent() bool handleKeyPressEvent(QKeyEvent *e); + bool encourageApply(); + public slots: void updateSelectionsForVariableUnderCursor(const QList &selections); diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index 908cd9782a8..8054d866e58 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -60,6 +60,7 @@ public: // Function interface to implement virtual void run() = 0; + virtual void semanticRehighlight() = 0; virtual void recalculateSemanticInfoDetached(bool force) = 0; virtual CppTools::SemanticInfo recalculateSemanticInfo() = 0; virtual CPlusPlus::Snapshot snapshot() = 0; diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp index af0efebc8f7..12bfe1531c3 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp +++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp @@ -182,6 +182,14 @@ void BuiltinEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force) m_semanticInfoUpdater.updateDetached(source); } +void BuiltinEditorDocumentProcessor::semanticRehighlight() +{ + if (m_semanticHighlighter && m_semanticInfoUpdater.semanticInfo().doc) { + m_semanticHighlighter->updateFormatMapFromFontSettings(); + m_semanticHighlighter->run(); + } +} + SemanticInfo BuiltinEditorDocumentProcessor::recalculateSemanticInfo() { const auto source = createSemanticInfoSource(false); diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.h b/src/plugins/cpptools/builtineditordocumentprocessor.h index 9e18020975d..396ba1bf1a7 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.h +++ b/src/plugins/cpptools/builtineditordocumentprocessor.h @@ -52,6 +52,7 @@ public: // BaseEditorDocumentProcessor interface void run() override; void recalculateSemanticInfoDetached(bool force) override; + void semanticRehighlight() override; CppTools::SemanticInfo recalculateSemanticInfo() override; BaseEditorDocumentParser *parser() override; CPlusPlus::Snapshot snapshot() override; diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 3bf0904c652..b4140d90656 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -796,6 +796,21 @@ void CppToolsPlugin::test_completion_data() << QLatin1String("Data") << QLatin1String("dataMember")); + QTest::newRow("explicit_instantiation") << _( + "template\n" + "struct Foo { T bar; };\n" + "\n" + "template class Foo;\n" + "\n" + "void func()\n" + "{\n" + " Foo foo;\n" + " @\n" + "}\n" + ) << _("foo.") << (QStringList() + << QLatin1String("Foo") + << QLatin1String("bar")); + QTest::newRow("use_global_identifier_as_base_class: derived as global and base as global") << _( "struct Global\n" "{\n" @@ -1551,6 +1566,29 @@ void CppToolsPlugin::test_completion_data() << QLatin1String("C") << QLatin1String("m")); + QTest::newRow("type_and_using_declaration: type in nested namespace and using in global") << _( + "namespace Ns {\n" + "namespace Nested {\n" + "struct Foo\n" + "{\n" + " void func();\n" + " int m_bar;\n" + "};\n" + "}\n" + "}\n" + "\n" + "using namespace Ns::Nested;\n" + "\n" + "namespace Ns\n" + "{\n" + "void Foo::func()\n" + "{\n" + " @\n" + "}\n" + "}\n" + ) << _("m_") << (QStringList() + << QLatin1String("m_bar")); + QTest::newRow("instantiate_template_with_anonymous_class") << _( "template \n" "struct S\n" @@ -2524,6 +2562,21 @@ void CppToolsPlugin::test_completion_data() ) << _("ar") << (QStringList() << QLatin1String("arg1")); + QTest::newRow("local_typedef_access_in_lambda") << _( + "struct Foo { int bar; };\n" + "\n" + "void func()\n" + "{\n" + " typedef Foo F;\n" + " []() {\n" + " F f;\n" + " @\n" + " };\n" + "}\n" + ) << _("f.") << (QStringList() + << QLatin1String("Foo") + << QLatin1String("bar")); + QTest::newRow("default_arguments_for_class_templates_and_base_class_QTCREATORBUG-12605") << _( "struct Foo { int foo; };\n" "template \n" diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index a529c464fab..01132b9ebbc 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -988,14 +988,14 @@ void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) // Save paths const ProjectInfo projectInfo = d->m_projectToProjectsInfo.value(project, ProjectInfo()); - QTC_CHECK(projectInfo.isValid()); projectFilePaths = pathsOfAllProjectParts(projectInfo); d->m_projectToProjectsInfo.remove(project); recalculateFileToProjectParts(); } - emit projectPartsRemoved(projectFilePaths); + if (!projectFilePaths.isEmpty()) + emit projectPartsRemoved(projectFilePaths); delayedGC(); } diff --git a/src/plugins/cpptools/cppprojects.cpp b/src/plugins/cpptools/cppprojects.cpp index ee5ae0156ab..17e197c1cfe 100644 --- a/src/plugins/cpptools/cppprojects.cpp +++ b/src/plugins/cpptools/cppprojects.cpp @@ -113,6 +113,7 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc, } toolchainDefines = tc->predefinedMacros(commandLineFlags); + toolchainType = tc->type(); updateLanguageFeatures(); } @@ -501,21 +502,50 @@ void ProjectPartBuilder::createProjectPart(const QStringList &theSources, } -QStringList CompilerOptionsBuilder::createHeaderPathOptions( - const ProjectPart::HeaderPaths &headerPaths, - IsBlackListed isBlackListed, const QString &toolchainType) +CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart::Ptr &projectPart) + : m_projectPart(projectPart) +{ +} + +QStringList CompilerOptionsBuilder::options() const +{ + return m_options; +} + +void CompilerOptionsBuilder::add(const QString &option) +{ + m_options.append(option); +} + +QString CompilerOptionsBuilder::defineLineToDefineOption(const QByteArray &defineLine) +{ + QByteArray str = defineLine.mid(8); + int spaceIdx = str.indexOf(' '); + const QString option = defineOption(); + const bool hasValue = spaceIdx != -1; + QString arg = option + QLatin1String(str.left(hasValue ? spaceIdx : str.size()) + '='); + if (hasValue) + arg += QLatin1String(str.mid(spaceIdx + 1)); + return arg; +} + +void CompilerOptionsBuilder::addDefine(const QByteArray &defineLine) +{ + m_options.append(defineLineToDefineOption(defineLine)); +} + +void CompilerOptionsBuilder::addHeaderPathOptions() { typedef ProjectPart::HeaderPath HeaderPath; - const QString defaultPrefix - = QLatin1String(toolchainType == QLatin1String("msvc") ? "/I" : "-I"); + const QString defaultPrefix = includeOption(); QStringList result; - foreach (const HeaderPath &headerPath , headerPaths) { + foreach (const HeaderPath &headerPath , m_projectPart->headerPaths) { if (headerPath.path.isEmpty()) continue; - if (isBlackListed && isBlackListed(headerPath.path)) + if (excludeHeaderPath(headerPath.path)) continue; QString prefix; @@ -533,64 +563,24 @@ QStringList CompilerOptionsBuilder::createHeaderPathOptions( result.append(prefix + headerPath.path); } - return result; + m_options.append(result); } -QStringList CompilerOptionsBuilder::createDefineOptions(const QByteArray &defines, - bool toolchainDefines, - const QString &toolchainType) +void CompilerOptionsBuilder::addToolchainAndProjectDefines() { - QByteArray extendedDefines = defines; + QByteArray extendedDefines = m_projectPart->toolchainDefines + m_projectPart->projectDefines; QStringList result; - // In gcc headers, lots of built-ins are referenced that clang does not understand. - // Therefore, prevent the inclusion of the header that references them. Of course, this - // will break if code actually requires stuff from there, but that should be the less common - // case. - if (toolchainType == QLatin1String("mingw") || toolchainType == QLatin1String("gcc")) - extendedDefines += "#define _X86INTRIN_H_INCLUDED\n"; - foreach (QByteArray def, extendedDefines.split('\n')) { - if (def.isEmpty()) + if (def.isEmpty() || excludeDefineLine(def)) continue; - // This is a quick fix for QTCREATORBUG-11501. - // TODO: do a proper fix, see QTCREATORBUG-11709. - if (def.startsWith("#define __cplusplus")) - continue; - - // TODO: verify if we can pass compiler-defined macros when also passing -undef. - if (toolchainDefines) { - //### FIXME: the next 3 check shouldn't be needed: we probably don't want to get the compiler-defined defines in. - if (!def.startsWith("#define ")) - continue; - if (def.startsWith("#define _")) - continue; - if (def.startsWith("#define OBJC_NEW_PROPERTIES")) - continue; - } - - // gcc 4.9 has: - // #define __has_include(STR) __has_include__(STR) - // #define __has_include_next(STR) __has_include_next__(STR) - // The right-hand sides are gcc built-ins that clang does not understand, and they'd - // override clang's own (non-macro, it seems) definitions of the symbols on the left-hand - // side. - if (toolchainType == QLatin1String("gcc") && def.contains("has_include")) - continue; - - QByteArray str = def.mid(8); - int spaceIdx = str.indexOf(' '); - const QString option = QLatin1String(toolchainType == QLatin1String("msvc") ? "/D" : "-D"); - const bool hasValue = spaceIdx != -1; - QString arg = option + QLatin1String(str.left(hasValue ? spaceIdx : str.size()) + '='); - if (hasValue) - arg += QLatin1String(str.mid(spaceIdx + 1)); - if (!result.contains(arg)) - result.append(arg); + const QString defineOption = defineLineToDefineOption(def); + if (!result.contains(defineOption)) + result.append(defineOption); } - return result; + m_options.append(result); } static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt) @@ -650,42 +640,19 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc return opts; } -static QStringList createLanguageOptionMsvc(ProjectFile::Kind fileKind) +void CompilerOptionsBuilder::addLanguageOption(ProjectFile::Kind fileKind) { - QStringList opts; - switch (fileKind) { - case ProjectFile::CHeader: - case ProjectFile::CSource: - opts << QLatin1String("/TC"); - break; - case ProjectFile::CXXHeader: - case ProjectFile::CXXSource: - opts << QLatin1String("/TP"); - break; - default: - break; - } - return opts; + const bool objcExt = m_projectPart->languageExtensions & ProjectPart::ObjectiveCExtensions; + const QStringList options = createLanguageOptionGcc(fileKind, objcExt); + m_options.append(options); } -QStringList CompilerOptionsBuilder::createLanguageOption(ProjectFile::Kind fileKind, bool objcExt, - const QString &toolchainType) -{ - return toolchainType == QLatin1String("msvc") ? createLanguageOptionMsvc(fileKind) - : createLanguageOptionGcc(fileKind, objcExt); -} - -QStringList CompilerOptionsBuilder::createOptionsForLanguage( - ProjectPart::LanguageVersion languageVersion, - ProjectPart::LanguageExtensions languageExtensions, - bool checkForBorlandExtensions, - const QString &toolchainType) +void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions) { QStringList opts; - if (toolchainType == QLatin1String("msvc")) - return opts; - bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions; - switch (languageVersion) { + const ProjectPart::LanguageExtensions languageExtensions = m_projectPart->languageExtensions; + const bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions; + switch (m_projectPart->languageVersion) { case ProjectPart::C89: opts << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89")); break; @@ -718,5 +685,41 @@ QStringList CompilerOptionsBuilder::createOptionsForLanguage( if (checkForBorlandExtensions && (languageExtensions & ProjectPart::BorlandExtensions)) opts << QLatin1String("-fborland-extensions"); - return opts; + m_options.append(opts); +} + +QString CompilerOptionsBuilder::includeOption() const +{ + return QLatin1String("-I"); +} + +QString CompilerOptionsBuilder::defineOption() const +{ + return QLatin1String("-D"); +} + +bool CompilerOptionsBuilder::excludeDefineLine(const QByteArray &defineLine) const +{ + // This is a quick fix for QTCREATORBUG-11501. + // TODO: do a proper fix, see QTCREATORBUG-11709. + if (defineLine.startsWith("#define __cplusplus")) + return true; + + // gcc 4.9 has: + // #define __has_include(STR) __has_include__(STR) + // #define __has_include_next(STR) __has_include_next__(STR) + // The right-hand sides are gcc built-ins that clang does not understand, and they'd + // override clang's own (non-macro, it seems) definitions of the symbols on the left-hand + // side. + const bool isGccToolchain = m_projectPart->toolchainType == QLatin1String("gcc"); + if (isGccToolchain && defineLine.contains("has_include")) + return true; + + return false; +} + +bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const +{ + Q_UNUSED(headerPath); + return false; } diff --git a/src/plugins/cpptools/cppprojects.h b/src/plugins/cpptools/cppprojects.h index 0851803511c..e2dd1db2a23 100644 --- a/src/plugins/cpptools/cppprojects.h +++ b/src/plugins/cpptools/cppprojects.h @@ -130,6 +130,7 @@ public: // fields QString projectConfigFile; // currently only used by the Generic Project Manager QByteArray projectDefines; QByteArray toolchainDefines; + QString toolchainType; QList headerPaths; QStringList precompiledHeaders; LanguageVersion languageVersion; @@ -214,21 +215,34 @@ private: class CPPTOOLS_EXPORT CompilerOptionsBuilder { public: - typedef std::function IsBlackListed; - static QStringList createHeaderPathOptions(const ProjectPart::HeaderPaths &headerPaths, - IsBlackListed isBlackListed = IsBlackListed(), - const QString &toolchainType = QLatin1String("clang")); + CompilerOptionsBuilder(const ProjectPart::Ptr &projectPart); + virtual ~CompilerOptionsBuilder() {} - static QStringList createDefineOptions(const QByteArray &defines, - bool toolchainDefines = false, - const QString &toolchainType = QLatin1String("clang")); + QStringList options() const; - static QStringList createLanguageOption(ProjectFile::Kind fileKind, bool objcExt, - const QString &toolchainType = QLatin1String("clang")); - static QStringList createOptionsForLanguage(ProjectPart::LanguageVersion languageVersion, - ProjectPart::LanguageExtensions languageExtensions, - bool checkForBorlandExtensions = true, - const QString &toolchainType = QLatin1String("clang")); + // Add custom options + void add(const QString &option); + void addDefine(const QByteArray &defineLine); + + // Add options based on project part + void addHeaderPathOptions(); + void addToolchainAndProjectDefines(); + virtual void addLanguageOption(ProjectFile::Kind fileKind); + virtual void addOptionsForLanguage(bool checkForBorlandExtensions = true); + +protected: + virtual bool excludeDefineLine(const QByteArray &defineLine) const; + virtual bool excludeHeaderPath(const QString &headerPath) const; + + virtual QString defineOption() const; + virtual QString includeOption() const; + + const ProjectPart::Ptr m_projectPart; + +private: + QString defineLineToDefineOption(const QByteArray &defineLine); + + QStringList m_options; }; } // namespace CppTools diff --git a/src/plugins/cpptools/semantichighlighter.cpp b/src/plugins/cpptools/semantichighlighter.cpp index 13199596293..c7e93f944ef 100644 --- a/src/plugins/cpptools/semantichighlighter.cpp +++ b/src/plugins/cpptools/semantichighlighter.cpp @@ -54,10 +54,6 @@ SemanticHighlighter::SemanticHighlighter(TextEditor::TextDocument *baseTextDocum , m_revision(0) { QTC_CHECK(m_baseTextDocument); - - connect(baseTextDocument, &TextEditor::TextDocument::fontSettingsChanged, - this, &SemanticHighlighter::onDocumentFontSettingsChanged); - updateFormatMapFromFontSettings(); } @@ -92,12 +88,6 @@ void SemanticHighlighter::run() m_watcher->setFuture(m_highlightingRunner()); } -void SemanticHighlighter::onDocumentFontSettingsChanged() -{ - updateFormatMapFromFontSettings(); - run(); -} - void SemanticHighlighter::onHighlighterResultAvailable(int from, int to) { if (documentRevision() != m_revision) diff --git a/src/plugins/cpptools/semantichighlighter.h b/src/plugins/cpptools/semantichighlighter.h index 6cc81b9ba0c..d00db6e9dad 100644 --- a/src/plugins/cpptools/semantichighlighter.h +++ b/src/plugins/cpptools/semantichighlighter.h @@ -73,12 +73,11 @@ public: ~SemanticHighlighter(); void setHighlightingRunner(HighlightingRunner highlightingRunner); + void updateFormatMapFromFontSettings(); void run(); private slots: - void onDocumentFontSettingsChanged(); - void onHighlighterResultAvailable(int from, int to); void onHighlighterFinished(); @@ -87,7 +86,6 @@ private: void disconnectWatcher(); unsigned documentRevision() const; - void updateFormatMapFromFontSettings(); private: TextEditor::TextDocument *m_baseTextDocument; diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 27fd6f79314..069634d81fe 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -267,14 +267,14 @@ static inline bool validMode(DebuggerStartMode sm) } // Accessed by RunControlFactory -DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QString *errorMessage) +DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QStringList *errors) { if (HostOsInfo::isWindowsHost()) { if (validMode(rp.startMode)) return new CdbEngine(rp); - *errorMessage = QLatin1String("Internal error: Invalid start parameters passed for thee CDB engine."); + errors->append(CdbEngine::tr("Internal error: Invalid start parameters passed for the CDB engine.")); } else { - *errorMessage = QString::fromLatin1("Unsupported debug mode"); + errors->append(CdbEngine::tr("Unsupported CDB host system.")); } return 0; } @@ -1396,9 +1396,10 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters) str << '"'; } } - if (!partialUpdate || isWatch) { - // Perform watches synchronization + // Perform watches synchronization only for full updates + if (!partialUpdate) str << blankSeparator << "-W"; + if (!partialUpdate || isWatch) { const WatcherHash watcherHash = WatchHandler::watcherNames(); if (!watcherHash.isEmpty()) { const WatcherHash::const_iterator cend = watcherHash.constEnd(); @@ -1778,8 +1779,8 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response) void CdbEngine::handleLocals(const CdbResponse &response, bool partialUpdate) { + watchHandler()->notifyUpdateFinished(); if (response.success) { - watchHandler()->notifyUpdateFinished(); if (boolSetting(VerboseLog)) showMessage(QLatin1String("Locals: ") + QString::fromLatin1(response.extensionReply), LogDebug); @@ -2499,6 +2500,8 @@ void CdbEngine::parseOutputLine(QByteArray line) currentCommand->response.command.constData(), currentCommand->token, currentCommand->response.builtinReply.size(), m_builtinCommandQueue.size() - 1); QTC_ASSERT(token == currentCommand->token, return; ); + if (boolSetting(VerboseLog)) + showMessage(QLatin1String(currentCommand->response.builtinReply.join(' ')), LogMisc); if (currentCommand->handler) { currentCommand->handler(currentCommand->response); } diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 34b59bbb4f6..9e6417e0ed5 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -358,7 +358,7 @@ void StartApplicationDialog::updateState() d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(okEnabled); } -bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp) +bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit **kit) { const bool attachRemote = rp->startMode == AttachToRemoteServer; const QString settingsGroup = QLatin1String("DebugMode"); @@ -409,11 +409,6 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp) settings->endGroup(); } - Kit *kit = dialog.d->kitChooser->currentKit(); - QTC_ASSERT(kit, return false); - bool res = fillParametersFromKit(rp, kit); - QTC_ASSERT(res, return false); - rp->executable = newParameters.localExecutable; const QString inputAddress = dialog.d->serverAddressEdit->text(); if (!inputAddress.isEmpty()) @@ -430,10 +425,13 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp) rp->serverStartScript = newParameters.serverStartScript; rp->debugInfoLocation = newParameters.debugInfoLocation; - IDevice::ConstPtr dev = DeviceKitInformation::device(kit); + Kit *k = dialog.d->kitChooser->currentKit(); + IDevice::ConstPtr dev = DeviceKitInformation::device(k); bool isLocal = !dev || (dev->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); if (!attachRemote) rp->startMode = isLocal ? StartExternal : StartRemoteProcess; + if (kit) + *kit = k; return true; } diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h index 5503944df78..ac262c962af 100644 --- a/src/plugins/debugger/debuggerdialogs.h +++ b/src/plugins/debugger/debuggerdialogs.h @@ -85,7 +85,7 @@ public: explicit StartApplicationDialog(QWidget *parent); ~StartApplicationDialog(); - static bool run(QWidget *parent, DebuggerRunParameters *rp); + static bool run(QWidget *parent, DebuggerRunParameters *rp, ProjectExplorer::Kit **kit); private slots: void historyIndexChanged(int); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 9f68494136e..2ecefdc7078 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -92,22 +92,6 @@ enum { debug = 0 }; #include #endif -/////////////////////////////////////////////////////////////////////// -// -// DebuggerRunParameters -// -/////////////////////////////////////////////////////////////////////// - -DebuggerRunParameters::DebuggerRunParameters() - : isSnapshot(false), - testCase(0) -{} - -void DebuggerRunParameters::initialize(const DebuggerStartParameters &sp) -{ - DebuggerStartParameters::operator=(sp); -} - // VariableManager Prefix const char PrefixDebugExecutable[] = "DebuggedExecutable"; diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 84808627bcf..4a09e07a0a9 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -83,28 +83,36 @@ class ThreadId; class DebuggerRunParameters : public DebuggerStartParameters { public: - DebuggerRunParameters(); + DebuggerRunParameters() {} - void initialize(const DebuggerStartParameters &sp); + DebuggerEngineType masterEngineType = NoEngineType; + DebuggerEngineType cppEngineType = NoEngineType; + DebuggerLanguages languages = AnyLanguage; + bool breakOnMain = false; + bool multiProcess = false; // Whether to set detach-on-fork off. + + QString debuggerCommand; QString coreFile; QString overrideStartScript; // Used in attach to core and remote debugging QString startMessage; // First status message shown. - QByteArray remoteSourcesDir; - QString remoteMountPoint; QMap sourcePathMap; QString debugInfoLocation; // Gdb "set-debug-file-directory". QStringList debugSourceLocation; // Gdb "directory" QString serverStartScript; - QString localMountDir; ProjectExplorer::IDevice::ConstPtr device; - bool isSnapshot; // Set if created internally. + QString sysRoot; + bool isSnapshot = false; // Set if created internally. + ProjectExplorer::Abi toolChainAbi; + + QString projectSourceDirectory; + QStringList projectSourceFiles; // Used by AttachCrashedExternal. QString crashParameter; // For Debugger testing. - int testCase; + int testCase = 0; }; class UpdateParameters @@ -427,12 +435,9 @@ private: DebuggerEnginePrivate *d; }; -DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QString *errorMessage); - -bool fillParametersFromKit(DebuggerStartParameters *sp, const ProjectExplorer::Kit *kit, QString *errorMessage = 0); - -DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp); +DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QStringList *errors); +DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp, const ProjectExplorer::Kit *kit); } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 74f194b475c..a79bef2e8c5 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -810,7 +810,7 @@ public slots: void handleExecStep() { if (currentEngine()->state() == DebuggerNotReady) { - ProjectExplorerPlugin::runStartupProject(DebugRunModeWithBreakOnMain); + ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN); } else { currentEngine()->resetLocation(); if (boolSetting(OperateByInstruction)) @@ -823,7 +823,7 @@ public slots: void handleExecNext() { if (currentEngine()->state() == DebuggerNotReady) { - ProjectExplorerPlugin::runStartupProject(DebugRunModeWithBreakOnMain); + ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN); } else { currentEngine()->resetLocation(); if (boolSetting(OperateByInstruction)) @@ -957,7 +957,7 @@ public: DebuggerMainWindow *m_mainWindow; Id m_previousMode; - QList m_scheduledStarts; + QVector> m_scheduledStarts; ProxyAction *m_visibleStartAction; ProxyAction *m_hiddenStopAction; @@ -1183,13 +1183,11 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, } } } - if (!fillParametersFromKit(&rp, kit, errorMessage)) - return false; if (rp.startMode == StartExternal) { rp.displayName = tr("Executable file \"%1\"").arg(rp.executable); rp.startMessage = tr("Debugging file %1.").arg(rp.executable); } - m_scheduledStarts.append(rp); + m_scheduledStarts.append(QPair(rp, kit)); return true; } // -wincrashevent :. A handle used for @@ -1204,8 +1202,6 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, return false; } DebuggerRunParameters rp; - if (!fillParametersFromKit(&rp, findUniversalCdbKit(), errorMessage)) - return false; rp.startMode = AttachCrashedExternal; rp.crashParameter = it->section(QLatin1Char(':'), 0, 0); rp.attachPID = it->section(QLatin1Char(':'), 1, 1).toULongLong(); @@ -1216,7 +1212,7 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, "does not match the pattern :.").arg(*it, option); return false; } - m_scheduledStarts.append(rp); + m_scheduledStarts.append(QPair(rp, findUniversalCdbKit())); return true; } @@ -1310,7 +1306,7 @@ void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project) m_continueAction->setEnabled(false); m_exitAction->setEnabled(false); QString whyNot; - const bool canRun = ProjectExplorerPlugin::canRun(project, DebugRunMode, &whyNot); + const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE, &whyNot); m_startAction->setEnabled(canRun); m_startAction->setToolTip(whyNot); m_debugWithoutDeployAction->setEnabled(canRun); @@ -1320,8 +1316,9 @@ void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project) void DebuggerPluginPrivate::startAndDebugApplication() { DebuggerRunParameters rp; - if (StartApplicationDialog::run(ICore::dialogParent(), &rp)) - createAndScheduleRun(rp); + Kit *kit; + if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit)) + createAndScheduleRun(rp, kit); } void DebuggerPluginPrivate::attachCore() @@ -1349,8 +1346,6 @@ void DebuggerPluginPrivate::attachCore() QString display = dlg.useLocalCoreFile() ? dlg.localCoreFile() : dlg.remoteCoreFile(); DebuggerRunParameters rp; - bool res = fillParametersFromKit(&rp, dlg.kit()); - QTC_ASSERT(res, return); rp.masterEngineType = DebuggerKitInformation::engineType(dlg.kit()); rp.executable = dlg.localExecutableFile(); rp.coreFile = dlg.localCoreFile(); @@ -1358,7 +1353,7 @@ void DebuggerPluginPrivate::attachCore() rp.startMode = AttachCore; rp.closeMode = DetachAtClose; rp.overrideStartScript = dlg.overrideStartScript(); - createAndScheduleRun(rp); + createAndScheduleRun(rp, dlg.kit()); } void DebuggerPluginPrivate::startRemoteCdbSession() @@ -1367,8 +1362,6 @@ void DebuggerPluginPrivate::startRemoteCdbSession() DebuggerRunParameters rp; Kit *kit = findUniversalCdbKit(); QTC_ASSERT(kit, return); - bool res = fillParametersFromKit(&rp, kit); - QTC_ASSERT(res, return); rp.startMode = AttachToRemoteServer; rp.closeMode = KillAtClose; StartRemoteCdbDialog dlg(ICore::dialogParent()); @@ -1380,17 +1373,18 @@ void DebuggerPluginPrivate::startRemoteCdbSession() return; rp.remoteChannel = dlg.connection(); setConfigValue(connectionKey, rp.remoteChannel); - createAndScheduleRun(rp); + createAndScheduleRun(rp, kit); } void DebuggerPluginPrivate::attachToRemoteServer() { DebuggerRunParameters rp; + Kit *kit; rp.startMode = AttachToRemoteServer; - if (StartApplicationDialog::run(ICore::dialogParent(), &rp)) { + if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit)) { rp.closeMode = KillAtClose; rp.serverStartScript.clear(); - createAndScheduleRun(rp); + createAndScheduleRun(rp, kit); } } @@ -1488,15 +1482,13 @@ DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit, } DebuggerRunParameters rp; - bool res = fillParametersFromKit(&rp, kit); - QTC_ASSERT(res, return 0); rp.attachPID = process.pid; rp.displayName = tr("Process %1").arg(process.pid); rp.executable = process.exe; rp.startMode = AttachExternal; rp.closeMode = DetachAtClose; rp.continueAfterAttach = contAfterAttach; - return createAndScheduleRun(rp); + return createAndScheduleRun(rp, kit); } void DebuggerPlugin::attachExternalApplication(RunControl *rc) @@ -1511,9 +1503,7 @@ void DebuggerPlugin::attachExternalApplication(RunControl *rc) if (const RunConfiguration *runConfiguration = rc->runConfiguration()) if (const Target *target = runConfiguration->target()) kit = target->kit(); - bool res = fillParametersFromKit(&rp, kit); - QTC_ASSERT(res, return); - createAndScheduleRun(rp); + createAndScheduleRun(rp, kit); } void DebuggerPluginPrivate::attachToQmlPort() @@ -1536,8 +1526,6 @@ void DebuggerPluginPrivate::attachToQmlPort() Kit *kit = dlg.kit(); QTC_ASSERT(kit, return); - bool res = fillParametersFromKit(&rp, kit); - QTC_ASSERT(res, return); setConfigValue("LastQmlServerPort", dlg.port()); setConfigValue("LastProfile", kit->id().toSetting()); @@ -1568,8 +1556,7 @@ void DebuggerPluginPrivate::attachToQmlPort() rp.projectSourceDirectory = !projects.isEmpty() ? projects.first()->projectDirectory().toString() : QString(); rp.projectSourceFiles = sourceFiles; - rp.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - createAndScheduleRun(rp); + createAndScheduleRun(rp, kit); } void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value) @@ -1582,8 +1569,8 @@ void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &valu void DebuggerPluginPrivate::runScheduled() { - foreach (const DebuggerRunParameters &rp, m_scheduledStarts) - createAndScheduleRun(rp); + for (int i = 0, n = m_scheduledStarts.size(); i != n; ++i) + createAndScheduleRun(m_scheduledStarts.at(i).first, m_scheduledStarts.at(i).second); } void DebuggerPluginPrivate::editorOpened(IEditor *editor) @@ -1991,7 +1978,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_localsAndExpressionsWindow->setShowLocals(false); } else if (state == DebuggerFinished) { Project *project = SessionManager::startupProject(); - const bool canRun = ProjectExplorerPlugin::canRun(project, DebugRunMode); + const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE); // We don't want to do anything anymore. m_interruptAction->setEnabled(false); m_continueAction->setEnabled(false); @@ -2093,7 +2080,7 @@ void DebuggerPluginPrivate::updateDebugActions() Project *project = SessionManager::startupProject(); QString whyNot; - const bool canRun = ProjectExplorerPlugin::canRun(project, DebugRunMode, &whyNot); + const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE, &whyNot); m_startAction->setEnabled(canRun); m_startAction->setToolTip(whyNot); m_debugWithoutDeployAction->setEnabled(canRun); @@ -2102,7 +2089,7 @@ void DebuggerPluginPrivate::updateDebugActions() if (m_snapshotHandler->currentIndex() < 0) { QString toolTip; const bool canRunAndBreakMain - = ProjectExplorerPlugin::canRun(project, DebugRunModeWithBreakOnMain, &toolTip); + = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN, &toolTip); m_stepAction->setEnabled(canRunAndBreakMain); m_nextAction->setEnabled(canRunAndBreakMain); if (canRunAndBreakMain) { @@ -2303,24 +2290,14 @@ static QString formatStartParameters(DebuggerRunParameters &sp) str << "PID: " << sp.attachPID << ' ' << sp.crashParameter << '\n'; if (!sp.projectSourceDirectory.isEmpty()) { str << "Project: " << QDir::toNativeSeparators(sp.projectSourceDirectory); - if (!sp.projectBuildDirectory.isEmpty()) - str << " (built: " << QDir::toNativeSeparators(sp.projectBuildDirectory) - << ')'; - str << '\n'; str << "Addtional Search Directories:" << sp.additionalSearchDirectories.join(QLatin1Char(' ')) << '\n'; } if (!sp.qmlServerAddress.isEmpty()) str << "QML server: " << sp.qmlServerAddress << ':' << sp.qmlServerPort << '\n'; - if (!sp.remoteChannel.isEmpty()) { + if (!sp.remoteChannel.isEmpty()) str << "Remote: " << sp.remoteChannel << '\n'; - if (!sp.remoteSourcesDir.isEmpty()) - str << "Remote sources: " << sp.remoteSourcesDir << '\n'; - if (!sp.remoteMountPoint.isEmpty()) - str << "Remote mount point: " << sp.remoteMountPoint - << " Local: " << sp.localMountDir << '\n'; - } str << "Sysroot: " << sp.sysRoot << '\n'; str << "Debug Source Location: " << sp.debugSourceLocation.join(QLatin1Char(':')) << '\n'; return rc; @@ -2615,11 +2592,11 @@ void DebuggerPluginPrivate::extensionsInitialized() debuggerIcon.addFile(QLatin1String(":/projectexplorer/images/debugger_start.png")); act->setIcon(debuggerIcon); act->setText(tr("Start Debugging")); - connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(DebugRunMode); }); + connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE); }); act = m_debugWithoutDeployAction = new QAction(this); act->setText(tr("Start Debugging Without Deployment")); - connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(DebugRunMode, true); }); + connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, true); }); act = m_startAndDebugApplicationAction = new QAction(this); act->setText(tr("Start and Debug External Application...")); @@ -3375,7 +3352,7 @@ void DebuggerPluginPrivate::testUnloadProject() void DebuggerPluginPrivate::testRunProject(const DebuggerRunParameters &rp, const TestCallBack &cb) { m_testCallbacks.append(cb); - RunControl *rc = createAndScheduleRun(rp); + RunControl *rc = createAndScheduleRun(rp, 0); connect(rc, &RunControl::finished, this, &DebuggerPluginPrivate::testRunControlFinished); } diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index c06ab172b7d..b02ddb7291c 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -69,15 +69,19 @@ enum { debug = 0 }; namespace Debugger { namespace Internal { -DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QString *error); +DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QStringList *error); +const auto *DebugRunMode = ProjectExplorer::Constants::DEBUG_RUN_MODE; +const auto *DebugRunModeWithBreakOnMain = ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN; + DebuggerEngine *createGdbEngine(const DebuggerRunParameters &rp); DebuggerEngine *createPdbEngine(const DebuggerRunParameters &rp); DebuggerEngine *createQmlEngine(const DebuggerRunParameters &rp); -DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &rp, QString *error); +DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &rp, QStringList *error); DebuggerEngine *createLldbEngine(const DebuggerRunParameters &rp); } // namespace Internal + static const char *engineTypeName(DebuggerEngineType et) { switch (et) { @@ -136,6 +140,9 @@ QString DebuggerRunControl::displayName() const void DebuggerRunControl::start() { + TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO); + TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME); + QTC_ASSERT(m_engine, return); // User canceled input dialog asking for executable when working on library project. if (m_engine->runParameters().startMode == StartInternal @@ -273,14 +280,290 @@ void DebuggerRunControl::abortDebugger() m_engine->abortDebugger(); } +/////////////////////////////////////////////////////////////////////// +// +// DebuggerRunControlCreator +// +/////////////////////////////////////////////////////////////////////// + + +namespace Internal { + +class DebuggerRunControlCreator +{ +public: + DebuggerRunControlCreator() {} + + // Life cycle: Initialize from StartParameters, enrich by automatically + // detectable pieces, construct an Engine and a RunControl. + void initialize(const DebuggerStartParameters &sp); + void enrich(const RunConfiguration *runConfig, const Kit *kit); + void createRunControl(Core::Id runMode = DebugRunMode); + QString fullError() const { return m_errors.join(QLatin1Char('\n')); } + + // Result. + DebuggerRunParameters m_rp; + + // Scratch data. + const Kit *m_kit = 0; + const RunConfiguration *m_runConfig = 0; + DebuggerRunConfigurationAspect *m_debuggerAspect = 0; + Target *m_target = 0; + Project *m_project = 0; + + QStringList m_errors; + DebuggerRunControl *m_runControl = 0; +}; + +void DebuggerRunControlCreator::initialize(const DebuggerStartParameters &sp) +{ + m_rp.DebuggerStartParameters::operator=(sp); +} + +void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const Kit *kit) +{ + QTC_ASSERT(!m_kit, return); + QTC_ASSERT(!m_runConfig, return); + + // Find RunConfiguration. + if (!m_runConfig) + m_runConfig = runConfig; + + // Extract as much as possible from available RunConfiguration. + if (auto localRc = qobject_cast(m_runConfig)) { + m_rp.executable = localRc->executable(); + m_rp.processArgs = localRc->commandLineArguments(); + m_rp.useTerminal = localRc->runMode() == ApplicationLauncher::Console; + // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...) + m_rp.workingDirectory = FileUtils::normalizePathName(localRc->workingDirectory()); + } + + // Find a Kit and Target. Either could be missing. + if (m_runConfig) + m_target = m_runConfig->target(); + + if (!m_kit) + m_kit = kit; + + if (!m_kit) { + if (m_target) + m_kit = m_target->kit(); + } + + // We might have get an executable from a local PID. + if (m_rp.executable.isEmpty()) { + foreach (const DeviceProcessItem &p, DeviceProcessList::localProcesses()) + if (p.pid == m_rp.attachPID) + m_rp.executable = p.exe; + } + + if (!m_kit) { + // This code can only be reached when starting via the command line + // (-debug pid or executable) or attaching from runconfiguration + // without specifying a kit. Try to find a kit via ABI. + QList abis; + if (m_rp.toolChainAbi.isValid()) { + abis.push_back(m_rp.toolChainAbi); + } else if (!m_rp.executable.isEmpty()) { + abis = Abi::abisOfBinary(FileName::fromString(m_rp.executable)); + } + + if (!abis.isEmpty()) { + // Try exact abis. + m_kit = KitManager::find(std::function([abis](const Kit *k) -> bool { + if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) + return abis.contains(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(k); + return false; + })); + if (!m_kit) { + // Or something compatible. + m_kit = KitManager::find(std::function([abis](const Kit *k) -> bool { + if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) + foreach (const Abi &a, abis) + if (a.isCompatibleWith(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(k)) + return true; + return false; + })); + } + } + } + + if (!m_kit) + m_kit = KitManager::defaultKit(); + + // We really should have a kit now. + if (!m_kit) { + m_errors.append(DebuggerKitInformation::tr("No kit found.")); + return; + } + + if (m_runConfig) { + if (auto envAspect = m_runConfig->extraAspect()) + m_rp.environment = envAspect->environment(); + } + + if (ToolChain *tc = ToolChainKitInformation::toolChain(m_kit)) + m_rp.toolChainAbi = tc->targetAbi(); + + if (m_target) + m_project = m_target->project(); + + if (m_project && m_rp.projectSourceDirectory.isEmpty()) + m_rp.projectSourceDirectory = m_project->projectDirectory().toString(); + + if (m_project && m_rp.projectSourceFiles.isEmpty()) + m_rp.projectSourceFiles = m_project->files(Project::ExcludeGeneratedFiles); + + // validate debugger if C++ debugging is enabled + if (m_rp.languages & CppLanguage) { + const QList tasks = DebuggerKitInformation::validateDebugger(m_kit); + if (!tasks.isEmpty()) { + foreach (const Task &t, tasks) + m_errors.append(t.description); + return; + } + } + + m_rp.cppEngineType = DebuggerKitInformation::engineType(m_kit); + m_rp.sysRoot = SysRootKitInformation::sysRoot(m_kit).toString(); + m_rp.debuggerCommand = DebuggerKitInformation::debuggerCommand(m_kit).toString(); + m_rp.device = DeviceKitInformation::device(m_kit); + + if (m_project) { + m_rp.projectSourceDirectory = m_project->projectDirectory().toString(); + m_rp.projectSourceFiles = m_project->files(Project::ExcludeGeneratedFiles); + } + + if (m_runConfig) + m_debuggerAspect = m_runConfig->extraAspect(); + + if (m_debuggerAspect) { + m_rp.multiProcess = m_debuggerAspect->useMultiProcess(); + + if (m_debuggerAspect->useCppDebugger()) + m_rp.languages |= CppLanguage; + + if (m_debuggerAspect->useQmlDebugger()) { + m_rp.languages |= QmlLanguage; + if (m_rp.device && m_rp.device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) { + QTcpServer server; + const bool canListen = server.listen(QHostAddress::LocalHost) + || server.listen(QHostAddress::LocalHostIPv6); + if (!canListen) { + m_errors.append(DebuggerPlugin::tr("Not enough free ports for QML debugging.") + QLatin1Char(' ')); + return; + } + m_rp.qmlServerAddress = server.serverAddress().toString(); + m_rp.qmlServerPort = server.serverPort(); + + // Makes sure that all bindings go through the JavaScript engine, so that + // breakpoints are actually hit! + const QString optimizerKey = _("QML_DISABLE_OPTIMIZER"); + if (!m_rp.environment.hasKey(optimizerKey)) + m_rp.environment.set(optimizerKey, _("1")); + + QtcProcess::addArg(&m_rp.processArgs, QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_rp.qmlServerPort)); + } + } + } + + if (m_rp.displayName.isEmpty() && m_runConfig) + m_rp.displayName = m_runConfig->displayName(); + + if (m_rp.masterEngineType == NoEngineType) { + if (m_rp.executable.endsWith(_(".py")) + || m_rp.executable == _("/usr/bin/python") + || m_rp.executable == _("/usr/bin/python3")) { + m_rp.masterEngineType = PdbEngineType; + } + } + + if (!boolSetting(AutoEnrichParameters)) { + const QString sysroot = m_rp.sysRoot; + if (m_rp.debugInfoLocation.isEmpty()) + m_rp.debugInfoLocation = sysroot + QLatin1String("/usr/lib/debug"); + if (m_rp.debugSourceLocation.isEmpty()) { + QString base = sysroot + QLatin1String("/usr/src/debug/"); + m_rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/corelib")); + m_rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/gui")); + m_rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/network")); + } + } + + if (m_rp.masterEngineType == NoEngineType && m_debuggerAspect) { + const bool useCppDebugger = m_debuggerAspect->useCppDebugger() && (m_rp.languages & CppLanguage); + const bool useQmlDebugger = m_debuggerAspect->useQmlDebugger() && (m_rp.languages & QmlLanguage); + + if (useQmlDebugger) { + if (useCppDebugger) + m_rp.masterEngineType = QmlCppEngineType; + else + m_rp.masterEngineType = QmlEngineType; + } + } + + if (m_rp.masterEngineType == NoEngineType) + m_rp.masterEngineType = m_rp.cppEngineType; + + if (m_rp.device && m_rp.connParams.port == 0) + m_rp.connParams = m_rp.device->sshParameters(); + + // Could have been set from command line. + if (m_rp.remoteChannel.isEmpty()) + m_rp.remoteChannel = m_rp.connParams.host + QLatin1Char(':') + QString::number(m_rp.connParams.port); + + if (m_rp.startMode == NoStartMode) + m_rp.startMode = StartInternal; +} + +// Re-used for Combined C++/QML engine. +DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QStringList *errors) +{ + switch (et) { + case GdbEngineType: + return createGdbEngine(rp); + case CdbEngineType: + return createCdbEngine(rp, errors); + case PdbEngineType: + return createPdbEngine(rp); + case QmlEngineType: + return createQmlEngine(rp); + case LldbEngineType: + return createLldbEngine(rp); + case QmlCppEngineType: + return createQmlCppEngine(rp, errors); + default: + if (errors) + errors->append(DebuggerPlugin::tr("Unknown debugger type \"%1\"").arg(_(engineTypeName(et)))); + } + return 0; +} + +void DebuggerRunControlCreator::createRunControl(Core::Id runMode) +{ + if (runMode == DebugRunModeWithBreakOnMain) + m_rp.breakOnMain = true; + + DebuggerEngine *engine = createEngine(m_rp.masterEngineType, m_rp, &m_errors); + if (!engine) { + m_errors.append(DebuggerPlugin::tr("Unable to create a debugger engine of the type \"%1\""). + arg(_(engineTypeName(m_rp.masterEngineType)))); + m_rp.startMode = NoStartMode; + return; + } + + m_runControl = new DebuggerRunControl(const_cast(m_runConfig), engine); + + if (!m_runControl) + m_rp.startMode = NoStartMode; +} + //////////////////////////////////////////////////////////////////////// // // DebuggerRunControlFactory // //////////////////////////////////////////////////////////////////////// -namespace Internal { - class DebuggerRunControlFactory : public IRunControlFactory { public: @@ -289,9 +572,22 @@ public: {} RunControl *create(RunConfiguration *runConfig, - RunMode mode, QString *errorMessage) override; + Core::Id mode, QString *errorMessage) override + { + QTC_ASSERT(runConfig, return 0); + QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0); - bool canRun(RunConfiguration *runConfig, RunMode mode) const override + // We cover only local setup here. Remote setups are handled by the + // RunControl factories in the target specific plugins. + DebuggerRunControlCreator creator; + creator.enrich(runConfig, 0); + creator.createRunControl(mode); + if (errorMessage) + *errorMessage = creator.fullError(); + return creator.m_runControl; + } + + bool canRun(RunConfiguration *runConfig, Core::Id mode) const override { return (mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain) && qobject_cast(runConfig); @@ -303,307 +599,56 @@ public: } }; -} // namespace Internal - -bool fillParametersFromRunConfiguration - (DebuggerStartParameters *sp, const RunConfiguration *runConfig, QString *errorMessage) -{ - QTC_ASSERT(runConfig, return false); - EnvironmentAspect *environmentAspect = runConfig->extraAspect(); - QTC_ASSERT(environmentAspect, return false); - - Target *target = runConfig->target(); - Kit *kit = target ? target->kit() : KitManager::defaultKit(); - if (!fillParametersFromKit(sp, kit, errorMessage)) - return false; - sp->environment = environmentAspect->environment(); - - if (target) { - if (const Project *project = target->project()) { - sp->projectSourceDirectory = project->projectDirectory().toString(); - if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration()) - sp->projectBuildDirectory = buildConfig->buildDirectory().toString(); - sp->projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - } - } - - DebuggerRunConfigurationAspect *debuggerAspect = runConfig->extraAspect(); - QTC_ASSERT(debuggerAspect, return false); - sp->multiProcess = debuggerAspect->useMultiProcess(); - - if (debuggerAspect->useCppDebugger()) - sp->languages |= CppLanguage; - - if (debuggerAspect->useQmlDebugger()) { - const IDevice::ConstPtr device = DeviceKitInformation::device(runConfig->target()->kit()); - QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return sp); - QTcpServer server; - const bool canListen = server.listen(QHostAddress::LocalHost) - || server.listen(QHostAddress::LocalHostIPv6); - if (!canListen) { - if (errorMessage) - *errorMessage = DebuggerPlugin::tr("Not enough free ports for QML debugging.") + QLatin1Char(' '); - return sp; - } - sp->qmlServerAddress = server.serverAddress().toString(); - sp->qmlServerPort = server.serverPort(); - sp->languages |= QmlLanguage; - - // Makes sure that all bindings go through the JavaScript engine, so that - // breakpoints are actually hit! - const QString optimizerKey = _("QML_DISABLE_OPTIMIZER"); - if (!sp->environment.hasKey(optimizerKey)) - sp->environment.set(optimizerKey, _("1")); - - QtcProcess::addArg(&sp->processArgs, QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(sp->qmlServerPort)); - } - - sp->startMode = StartInternal; - sp->displayName = runConfig->displayName(); - - return true; -} - -namespace Internal { - -bool fillParametersFromLocalRunConfiguration - (DebuggerRunParameters *rp, const RunConfiguration *runConfig, QString *errorMessage) -{ - if (!fillParametersFromRunConfiguration(rp, runConfig, errorMessage)) - return false; - - auto rc = qobject_cast(runConfig); - QTC_ASSERT(rc, return false); - // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...) - rp->workingDirectory = FileUtils::normalizePathName(rc->workingDirectory()); - - rp->executable = rc->executable(); - if (rp->executable.isEmpty()) - return false; - - rp->processArgs = rc->commandLineArguments(); - rp->useTerminal = rc->runMode() == ApplicationLauncher::Console; - - return true; -} - -RunControl *DebuggerRunControlFactory::create - (RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) -{ - QTC_ASSERT(runConfiguration, return 0); - QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0); - - // We cover only local setup here. Remote setups are handled by the - // RunControl factories in the target specific plugins. - DebuggerRunParameters rp; - bool res = fillParametersFromLocalRunConfiguration(&rp, runConfiguration, errorMessage); - if (rp.startMode == NoStartMode) - return 0; - - QTC_ASSERT(res, return 0); - - if (mode == DebugRunModeWithBreakOnMain) - rp.breakOnMain = true; - - rp.runConfiguration = runConfiguration; - return createDebuggerRunControlInternal(rp, errorMessage); -} - QObject *createDebuggerRunControlFactory(QObject *parent) { return new DebuggerRunControlFactory(parent); } -DebuggerRunControl *createDebuggerRunControlInternal(const DebuggerRunParameters &rp0, QString *errorMessage) +//////////////////////////////////////////////////////////////////////// +// +// Externally visible helper. +// +//////////////////////////////////////////////////////////////////////// + +/** + * Used for direct "special" starts from actions in the debugger plugin. + */ +DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp, const Kit *kit) { - QTC_ASSERT(rp0.runConfiguration, return 0); - const Target *target = rp0.runConfiguration->target(); - QTC_ASSERT(target, return 0); - - DebuggerRunParameters rp = rp0; - TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO); - TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME); - - if (!boolSetting(AutoEnrichParameters)) { - const QString sysroot = rp.sysRoot; - if (rp.debugInfoLocation.isEmpty()) - rp.debugInfoLocation = sysroot + QLatin1String("/usr/lib/debug"); - if (rp.debugSourceLocation.isEmpty()) { - QString base = sysroot + QLatin1String("/usr/src/debug/"); - rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/corelib")); - rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/gui")); - rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/network")); - } - } - - if (rp.masterEngineType == NoEngineType) { - if (rp.executable.endsWith(_(".py")) - || rp.executable == _("/usr/bin/python") - || rp.executable == _("/usr/bin/python3")) { - rp.masterEngineType = PdbEngineType; - } else { - if (!fillParametersFromKit(&rp, target->kit(), errorMessage)) - return 0; - auto aspect = rp.runConfiguration->extraAspect(); - const bool useCppDebugger = aspect->useCppDebugger() && (rp.languages & CppLanguage); - const bool useQmlDebugger = aspect->useQmlDebugger() && (rp.languages & QmlLanguage); - if (useQmlDebugger) { - if (useCppDebugger) - rp.masterEngineType = QmlCppEngineType; - else - rp.masterEngineType = QmlEngineType; - } else { - rp.masterEngineType = rp.cppEngineType; - } - } - } - - rp.device = DeviceKitInformation::device(target->kit()); - if (rp.device && rp.connParams.port == 0) - rp.connParams = rp.device->sshParameters(); - - // Could have been set from command line. - if (rp.remoteChannel.isEmpty()) - rp.remoteChannel = rp.connParams.host + QLatin1Char(':') + QString::number(rp.connParams.port); - - QString error; - DebuggerEngine *engine = createEngine(rp.masterEngineType, rp, &error); - if (!engine) { - Core::ICore::showWarningWithOptions(DebuggerRunControl::tr("Debugger"), error); - if (errorMessage) - *errorMessage = error; - return 0; - } - return new DebuggerRunControl(rp.runConfiguration, engine); -} - -DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp) -{ - QString errorMessage; - DebuggerRunControl *rc = createDebuggerRunControlInternal(rp, &errorMessage); - if (!rc) { - ProjectExplorerPlugin::showRunErrorMessage(errorMessage); + DebuggerRunControlCreator creator; + creator.m_rp = rp; + creator.enrich(0, kit); + creator.createRunControl(DebugRunMode); + if (!creator.m_runControl) { + ProjectExplorerPlugin::showRunErrorMessage(creator.fullError()); return 0; } Internal::showMessage(rp.startMessage, 0); - ProjectExplorerPlugin::startRunControl(rc, DebugRunMode); - return rc; -} - -static QString executableForPid(qint64 pid) -{ - foreach (const DeviceProcessItem &p, DeviceProcessList::localProcesses()) - if (p.pid == pid) - return p.exe; - return QString(); -} - -bool fillParametersFromKit(DebuggerStartParameters *sp, const Kit *kit, QString *errorMessage /* = 0 */) -{ - if (!kit) { - // This code can only be reached when starting via the command line - // (-debug pid or executable) or attaching from runconfiguration - // without specifying a kit. Try to find a kit via ABI. - QList abis; - if (sp->toolChainAbi.isValid()) { - abis.push_back(sp->toolChainAbi); - } else { - // Try via executable. - if (sp->executable.isEmpty() - && (sp->startMode == AttachExternal || sp->startMode == AttachCrashedExternal)) { - sp->executable = executableForPid(sp->attachPID); - } - if (!sp->executable.isEmpty()) - abis = Abi::abisOfBinary(FileName::fromString(sp->executable)); - } - if (!abis.isEmpty()) { - // Try exact abis. - kit = KitManager::find(std::function([abis](const Kit *k) -> bool { - if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) { - return abis.contains(tc->targetAbi()) - && DebuggerKitInformation::isValidDebugger(k); - } - return false; - })); - if (!kit) { - // Or something compatible. - kit = KitManager::find(std::function([abis](const Kit *k) -> bool { - if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) - foreach (const Abi &a, abis) - if (a.isCompatibleWith(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(k)) - return true; - return false; - })); - } - } - if (!kit) - kit = KitManager::defaultKit(); - } - - // Verify that debugger and profile are valid - if (!kit) { - sp->startMode = NoStartMode; - if (errorMessage) - *errorMessage = DebuggerKitInformation::tr("No kit found."); - return false; - } - // validate debugger if C++ debugging is enabled - if (sp->languages & CppLanguage) { - const QList tasks = DebuggerKitInformation::validateDebugger(kit); - if (!tasks.isEmpty()) { - sp->startMode = NoStartMode; - if (errorMessage) { - foreach (const Task &t, tasks) { - if (errorMessage->isEmpty()) - errorMessage->append(QLatin1Char('\n')); - errorMessage->append(t.description); - } - } - return false; - } - } - sp->cppEngineType = DebuggerKitInformation::engineType(kit); - sp->sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - sp->debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - - ToolChain *tc = ToolChainKitInformation::toolChain(kit); - if (tc) - sp->toolChainAbi = tc->targetAbi(); - - return true; -} - -DebuggerEngine *createEngine(DebuggerEngineType et, - const DebuggerRunParameters &rp, QString *errorMessage) -{ - switch (et) { - case GdbEngineType: - return createGdbEngine(rp); - case CdbEngineType: - return createCdbEngine(rp, errorMessage); - case PdbEngineType: - return createPdbEngine(rp); - case QmlEngineType: - return createQmlEngine(rp); - case LldbEngineType: - return createLldbEngine(rp); - case QmlCppEngineType: - return createQmlCppEngine(rp, errorMessage); - default: - break; - } - *errorMessage = DebuggerPlugin::tr("Unable to create a debugger engine of the type \"%1\""). - arg(_(engineTypeName(et))); - return 0; + ProjectExplorerPlugin::startRunControl(creator.m_runControl, DebugRunMode); + return creator.m_runControl; // Only used for tests. } } // namespace Internal -DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, QString *errorMessage) +/** + * Main entry point for target plugins. + */ +DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, + RunConfiguration *runConfig, + QString *errorMessage, + Core::Id runMode) { - DebuggerRunParameters rp; - rp.initialize(sp); - return createDebuggerRunControlInternal(rp, errorMessage); + DebuggerRunControlCreator creator; + creator.initialize(sp); + creator.enrich(runConfig, 0); + creator.createRunControl(runMode); + if (errorMessage) + *errorMessage = creator.fullError(); + if (!creator.m_runControl) { + Core::ICore::showWarningWithOptions(DebuggerRunControl::tr("Debugger"), creator.fullError()); + return 0; + } + return creator.m_runControl; } } // namespace Debugger diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index 0bc345e7338..f7b8e850382 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -43,18 +43,14 @@ class DebuggerStartParameters; class DebuggerRunControl; namespace Internal { -class DebuggerRunParameters; -DebuggerRunControl *createDebuggerRunControlInternal(const DebuggerRunParameters &, QString *); +class DebuggerEngine; +class DebuggerRunControlCreator; } DEBUGGER_EXPORT DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, - QString *errorMessage); - -DEBUGGER_EXPORT bool fillParametersFromRunConfiguration(DebuggerStartParameters *sp, - const ProjectExplorer::RunConfiguration *runConfig, - QString *errorMessage); - -namespace Internal { class DebuggerEngine; } + ProjectExplorer::RunConfiguration *runConfig, + QString *errorMessage, + Core::Id runMode = ProjectExplorer::Constants::DEBUG_RUN_MODE); class DEBUGGER_EXPORT DebuggerRunControl : public ProjectExplorer::RunControl @@ -92,8 +88,7 @@ signals: private: void handleFinished(); - friend DebuggerRunControl *Debugger::Internal::createDebuggerRunControlInternal( - const Internal::DebuggerRunParameters &rp, QString *errorMessage); + friend class Internal::DebuggerRunControlCreator; DebuggerRunControl(ProjectExplorer::RunConfiguration *runConfig, Internal::DebuggerEngine *engine); diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h index b36b10e8437..4ab295396a6 100644 --- a/src/plugins/debugger/debuggerstartparameters.h +++ b/src/plugins/debugger/debuggerstartparameters.h @@ -72,78 +72,49 @@ public: class DEBUGGER_EXPORT DebuggerStartParameters { public: - DebuggerStartParameters() - : masterEngineType(NoEngineType), - cppEngineType(NoEngineType), - runConfiguration(0), - attachPID(-1), - useTerminal(false), - breakOnMain(false), - continueAfterAttach(false), - multiProcess(false), - languages(AnyLanguage), - qmlServerAddress(QLatin1String("127.0.0.1")), - qmlServerPort(Constants::QML_DEFAULT_DEBUG_SERVER_PORT), - remoteSetupNeeded(false), - useContinueInsteadOfRun(false), - startMode(NoStartMode), - closeMode(KillAtClose), - useCtrlCStub(false), - skipExecutableValidation(false) - {} + DebuggerStartParameters() {} - DebuggerEngineType masterEngineType; - DebuggerEngineType cppEngineType; - QString sysRoot; - QString deviceSymbolsRoot; - QString debuggerCommand; - ProjectExplorer::Abi toolChainAbi; - QPointer runConfiguration; + DebuggerStartMode startMode = NoStartMode; + DebuggerCloseMode closeMode = KillAtClose; - QString platform; QString executable; QString displayName; // Used in the Snapshots view. QString processArgs; Utils::Environment environment; QString workingDirectory; - qint64 attachPID; - bool useTerminal; - bool breakOnMain; - bool continueAfterAttach; - bool multiProcess; - DebuggerLanguages languages; + qint64 attachPID = InvalidPid; + QStringList solibSearchPath; + bool useTerminal = false; // Used by Qml debugging. QString qmlServerAddress; quint16 qmlServerPort; - QString projectSourceDirectory; - QStringList additionalSearchDirectories; - QString projectBuildDirectory; - QStringList projectSourceFiles; - // Used by remote debugging. + // Used by general remote debugging. QString remoteChannel; QSsh::SshConnectionParameters connParams; - bool remoteSetupNeeded; + bool remoteSetupNeeded = false; // Used by baremetal plugin QByteArray commandsForReset; // commands used for resetting the inferior - bool useContinueInsteadOfRun; // if connected to a hw debugger run is not possible but continue is used + bool useContinueInsteadOfRun = false; // if connected to a hw debugger run is not possible but continue is used QByteArray commandsAfterConnect; // additional commands to post after connection to debug target // Used by Valgrind QVector expectedSignals; - QStringList solibSearchPath; - DebuggerStartMode startMode; - DebuggerCloseMode closeMode; - // For QNX debugging QString remoteExecutable; - bool useCtrlCStub; + bool useCtrlCStub = false; // Used by Android to avoid false positives on warnOnRelease - bool skipExecutableValidation; + bool skipExecutableValidation = false; + QStringList additionalSearchDirectories; + + // Used by iOS. + QString platform; + QString deviceSymbolsRoot; + bool continueAfterAttach = false; }; } // namespace Debugger diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 5d20589e022..f5dc8efa93b 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1811,7 +1811,8 @@ QString GdbEngine::cleanupFullName(const QString &fileName) // Gdb running on windows often delivers "fullnames" which // (a) have no drive letter and (b) are not normalized. if (Abi::hostAbi().os() == Abi::WindowsOS) { - QTC_ASSERT(!fileName.isEmpty(), return QString()); + if (fileName.isEmpty()) + return QString(); QFileInfo fi(fileName); if (fi.isReadable()) cleanFilePath = QDir::cleanPath(fi.absoluteFilePath()); @@ -3525,7 +3526,7 @@ void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response, const QStri } rp.displayName = function + _(": ") + QDateTime::currentDateTime().toString(); rp.isSnapshot = true; - createAndScheduleRun(rp); + createAndScheduleRun(rp, 0); } else { QByteArray msg = response.data["msg"].data(); AsynchronousMessageBox::critical(tr("Snapshot Creation Error"), diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index 9f1bed9d6a0..617f087791c 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -58,11 +58,11 @@ namespace Internal { // /////////////////////////////////////////////////////////////////////// -GdbRemoteServerEngine::GdbRemoteServerEngine(const DebuggerRunParameters &startParameters) - : GdbEngine(startParameters), m_startAttempted(false) +GdbRemoteServerEngine::GdbRemoteServerEngine(const DebuggerRunParameters &runParameters) + : GdbEngine(runParameters), m_startAttempted(false) { if (HostOsInfo::isWindowsHost()) - m_gdbProc.setUseCtrlCStub(startParameters.useCtrlCStub); // This is only set for QNX/BlackBerry + m_gdbProc.setUseCtrlCStub(runParameters.useCtrlCStub); // This is only set for QNX/BlackBerry connect(&m_uploadProc, static_cast(&QProcess::error), this, &GdbRemoteServerEngine::uploadProcError); diff --git a/src/plugins/debugger/gdb/startgdbserverdialog.cpp b/src/plugins/debugger/gdb/startgdbserverdialog.cpp index 0dd3290cd3d..c9acf9e8978 100644 --- a/src/plugins/debugger/gdb/startgdbserverdialog.cpp +++ b/src/plugins/debugger/gdb/startgdbserverdialog.cpp @@ -213,8 +213,6 @@ void GdbServerStarter::attach(int port) } DebuggerRunParameters rp; - bool res = fillParametersFromKit(&rp, d->kit); - QTC_ASSERT(res, return); rp.masterEngineType = GdbEngineType; rp.connParams.port = port; rp.remoteChannel = rp.connParams.host + QLatin1Char(':') + QString::number(rp.connParams.port); @@ -222,7 +220,7 @@ void GdbServerStarter::attach(int port) rp.executable = localExecutable; rp.startMode = AttachToRemoteServer; rp.closeMode = KillAtClose; - createAndScheduleRun(rp); + createAndScheduleRun(rp, d->kit); } void GdbServerStarter::handleProcessClosed(int status) diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index 69d905acf4d..160720465ae 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -60,10 +60,9 @@ enum { debug = 0 }; } \ } while (0) -DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &sp, - QString *errorMessage) +DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &sp, QStringList *errors) { - QmlCppEngine *newEngine = new QmlCppEngine(sp, errorMessage); + QmlCppEngine *newEngine = new QmlCppEngine(sp, errors); if (newEngine->cppEngine()) return newEngine; delete newEngine; @@ -77,14 +76,17 @@ DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &sp, // //////////////////////////////////////////////////////////////////////// -QmlCppEngine::QmlCppEngine(const DebuggerRunParameters &rp, QString *errorMessage) +QmlCppEngine::QmlCppEngine(const DebuggerRunParameters &rp, QStringList *errors) : DebuggerEngine(rp) { setObjectName(QLatin1String("QmlCppEngine")); m_qmlEngine = new QmlEngine(rp, this); - m_cppEngine = createEngine(rp.cppEngineType, rp, errorMessage); + QStringList innerErrors; + m_cppEngine = createEngine(rp.cppEngineType, rp, &innerErrors); if (!m_cppEngine) { - *errorMessage = tr("The slave debugging engine required for combined QML/C++-Debugging could not be created: %1").arg(*errorMessage); + errors->append(tr("The slave debugging engine required for combined " + "QML/C++-Debugging could not be created: %1") + .arg(innerErrors.join(QLatin1Char('\n')))); return; } m_cppEngine->setMasterEngine(this); diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index dfb1f2b86b3..9985b747783 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -43,7 +43,7 @@ class QmlCppEngine : public DebuggerEngine Q_OBJECT public: - QmlCppEngine(const DebuggerRunParameters &sp, QString *errorMessage); + QmlCppEngine(const DebuggerRunParameters &sp, QStringList *errors); ~QmlCppEngine(); bool canDisplayTooltip() const; diff --git a/src/plugins/designer/cpp/formclasswizard.cpp b/src/plugins/designer/cpp/formclasswizard.cpp index e728b4c2caa..558d92d6d1a 100644 --- a/src/plugins/designer/cpp/formclasswizard.cpp +++ b/src/plugins/designer/cpp/formclasswizard.cpp @@ -43,7 +43,7 @@ namespace Internal { FormClassWizard::FormClassWizard() { - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QWIDGETS)); + setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QWIDGETS)); } QString FormClassWizard::headerSuffix() const diff --git a/src/plugins/designer/cpp/formclasswizarddialog.cpp b/src/plugins/designer/cpp/formclasswizarddialog.cpp index afd5a3ebc50..9f8924b872c 100644 --- a/src/plugins/designer/cpp/formclasswizarddialog.cpp +++ b/src/plugins/designer/cpp/formclasswizarddialog.cpp @@ -72,7 +72,7 @@ bool FormClassWizardDialog::validateCurrentPage() void FormClassWizardDialog::initializePage(int id) { - QWizard::initializePage(id); + Core::BaseFileWizard::initializePage(id); // Switching from form to class page: store XML template and set a suitable // class name in the class page based on the form base class if (id == ClassPageId) { diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 762e056f7f6..2730fa108ad 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -596,7 +596,7 @@ static inline void msgCannotRun(const QStringList &args, const QString &workingD const char *GitClient::stashNamePrefix = "stash@{"; -GitClient::GitClient() : VcsBase::VcsBaseClientImpl(this, new GitSettings), +GitClient::GitClient() : VcsBase::VcsBaseClientImpl(new GitSettings), m_cachedGitVersion(0), m_disableEditor(false) { @@ -1739,7 +1739,8 @@ QStringList GitClient::synchronousSubmoduleStatus(const QString &workingDirector // get submodule status arguments << QLatin1String("submodule") << QLatin1String("status"); - if (!vcsFullySynchronousExec(workingDirectory, arguments, &outputTextData, &errorText)) { + if (!vcsFullySynchronousExec(workingDirectory, arguments, &outputTextData, &errorText, + silentFlags)) { msgCannotRun(tr("Cannot retrieve submodule status of \"%1\": %2") .arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText)), errorMessage); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index e59b17a4527..b3f433dce56 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -241,11 +241,21 @@ QAction *GitPlugin::createRepositoryAction(ActionContainer *ac, QAction *GitPlugin::createRepositoryAction(ActionContainer *ac, const QString &text, Id id, const Context &context, bool addToLocator, - const char *pluginSlot, const QKeySequence &keys) + const std::function &callback, const QKeySequence &keys) { QAction *action = createRepositoryAction(ac, text, id, context, addToLocator, keys); - connect(action, SIGNAL(triggered()), this, pluginSlot); - action->setData(id.uniqueIdentifier()); + connect(action, &QAction::triggered, this, callback); + return action; +} + +QAction *GitPlugin::createChangeRelatedRepositoryAction(ActionContainer *ac, + const QString &text, Id id, + const Context &context, bool addToLocator, + const std::function &callback, + const QKeySequence &keys) +{ + QAction *action = createRepositoryAction(ac, text, id, context, addToLocator, keys); + connect(action, &QAction::triggered, this, [callback, id] { callback(id); }); return action; } @@ -360,18 +370,16 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitContainer->addMenu(localRepositoryMenu); createRepositoryAction(localRepositoryMenu, tr("Diff"), "Git.DiffRepository", - context, true, SLOT(diffRepository())); + context, true, [this] { diffRepository(); }); createRepositoryAction(localRepositoryMenu, tr("Log"), "Git.LogRepository", - context, true, - SLOT(logRepository())); + context, true, [this] { logRepository(); }); createRepositoryAction(localRepositoryMenu, tr("Reflog"), "Git.ReflogRepository", - context, true, - SLOT(reflogRepository())); + context, true, [this] { reflogRepository(); }); createRepositoryAction(localRepositoryMenu, tr("Clean..."), "Git.CleanRepository", - context, true, SLOT(cleanRepository())); + context, true, [this] { cleanRepository(); }); createRepositoryAction(localRepositoryMenu, tr("Status"), "Git.StatusRepository", context, true, &GitClient::status); @@ -380,75 +388,75 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) localRepositoryMenu->addSeparator(context); createRepositoryAction(localRepositoryMenu, tr("Commit..."), "Git.Commit", - context, true, SLOT(startCommit()), + context, true, [this] { startCommit(); }, QKeySequence(UseMacShortcuts ? tr("Meta+G,Meta+C") : tr("Alt+G,Alt+C"))); createRepositoryAction(localRepositoryMenu, tr("Amend Last Commit..."), "Git.AmendCommit", - context, true, SLOT(startAmendCommit())); + context, true, [this] { startAmendCommit(); }); m_fixupCommitAction = createRepositoryAction(localRepositoryMenu, tr("Fixup Previous Commit..."), "Git.FixupCommit", - context, true, SLOT(startFixupCommit())); + context, true, [this] { startFixupCommit(); }); // -------------- localRepositoryMenu->addSeparator(context); createRepositoryAction(localRepositoryMenu, tr("Reset..."), "Git.Reset", - context, true, SLOT(resetRepository())); + context, true, [this] { resetRepository(); }); m_interactiveRebaseAction = createRepositoryAction(localRepositoryMenu, tr("Interactive Rebase..."), "Git.InteractiveRebase", - context, true, SLOT(startRebase())); + context, true, [this] { startRebase(); }); m_submoduleUpdateAction = createRepositoryAction(localRepositoryMenu, tr("Update Submodules"), "Git.SubmoduleUpdate", - context, true, SLOT(updateSubmodules())); + context, true, [this] { updateSubmodules(); }); m_abortMergeAction = createRepositoryAction(localRepositoryMenu, tr("Abort Merge"), "Git.MergeAbort", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_abortRebaseAction = createRepositoryAction(localRepositoryMenu, tr("Abort Rebase"), "Git.RebaseAbort", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_abortCherryPickAction = createRepositoryAction(localRepositoryMenu, tr("Abort Cherry Pick"), "Git.CherryPickAbort", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_abortRevertAction = createRepositoryAction(localRepositoryMenu, tr("Abort Revert"), "Git.RevertAbort", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_continueRebaseAction = createRepositoryAction(localRepositoryMenu, tr("Continue Rebase"), "Git.RebaseContinue", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_continueCherryPickAction = createRepositoryAction(localRepositoryMenu, tr("Continue Cherry Pick"), "Git.CherryPickContinue", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_continueRevertAction = createRepositoryAction(localRepositoryMenu, tr("Continue Revert"), "Git.RevertContinue", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); // -------------- localRepositoryMenu->addSeparator(context); createRepositoryAction(localRepositoryMenu, tr("Branches..."), "Git.BranchList", - context, true, SLOT(branchList())); + context, true, [this] { branchList(); }); // -------------- localRepositoryMenu->addSeparator(context); @@ -465,12 +473,12 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) "Git.ApplyCurrentFilePatch", context, true); - connect(m_applyCurrentFilePatchAction, SIGNAL(triggered()), this, - SLOT(applyCurrentFilePatch())); + connect(m_applyCurrentFilePatchAction, &QAction::triggered, + this, &GitPlugin::applyCurrentFilePatch); createRepositoryAction(patchMenu, tr("Apply from File..."), "Git.ApplyPatch", - context, true, SLOT(promptApplyPatch())); + context, true, [this] { promptApplyPatch(); }); // "Stash" menu ActionContainer *stashMenu = ActionManager::createMenu("Git.StashMenu"); @@ -479,27 +487,27 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) createRepositoryAction(stashMenu, tr("Stashes..."), "Git.StashList", - context, false, SLOT(stashList())); + context, false, [this] { stashList(); }); stashMenu->addSeparator(context); QAction *action = createRepositoryAction(stashMenu, tr("Stash"), "Git.Stash", - context, true, SLOT(stash())); + context, true, [this] { stash(); }); action->setToolTip(tr("Saves the current state of your work and resets the repository.")); action = createRepositoryAction(stashMenu, tr("Stash Unstaged Files"), "Git.StashUnstaged", - context, true, SLOT(stashUnstaged())); + context, true, [this] { stashUnstaged(); }); action->setToolTip(tr("Saves the current state of your unstaged files and resets the repository " "to its staged state.")); action = createRepositoryAction(stashMenu, tr("Take Snapshot..."), "Git.StashSnapshot", - context, true, SLOT(stashSnapshot())); + context, true, [this] { stashSnapshot(); }); action->setToolTip(tr("Saves the current state of your work.")); stashMenu->addSeparator(context); action = createRepositoryAction(stashMenu, tr("Stash Pop"), "Git.StashPop", - context, true, SLOT(stashPop())); + context, true, [this] { stashPop(); }); action->setToolTip(tr("Restores changes saved to the stash list using \"Stash\".")); @@ -513,13 +521,13 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitContainer->addMenu(remoteRepositoryMenu); createRepositoryAction(remoteRepositoryMenu, tr("Fetch"), "Git.Fetch", - context, true, SLOT(fetch())); + context, true, [this] { fetch(); }); createRepositoryAction(remoteRepositoryMenu, tr("Pull"), "Git.Pull", - context, true, SLOT(pull())); + context, true, [this] { pull(); }); createRepositoryAction(remoteRepositoryMenu, tr("Push"), "Git.Push", - context, true, SLOT(push())); + context, true, [this] { push(); }); // -------------- remoteRepositoryMenu->addSeparator(context); @@ -542,30 +550,31 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) createRepositoryAction(remoteRepositoryMenu, tr("Manage Remotes..."), "Git.RemoteList", - context, false, SLOT(remoteList())); + context, false, [this] { remoteList(); }); /* \"Remote Repository" menu */ // -------------- /* Actions only in locator */ - createRepositoryAction(0, tr("Show..."), "Git.Show", - context, true, SLOT(startChangeRelatedAction())); + const auto startChangeRelated = [this](Id id) { startChangeRelatedAction(id); }; + createChangeRelatedRepositoryAction(0, tr("Show..."), "Git.Show", + context, true, startChangeRelated); - createRepositoryAction(0, tr("Revert..."), "Git.Revert", - context, true, SLOT(startChangeRelatedAction())); + createChangeRelatedRepositoryAction(0, tr("Revert..."), "Git.Revert", + context, true, startChangeRelated); - createRepositoryAction(0, tr("Cherry Pick..."), "Git.CherryPick", - context, true, SLOT(startChangeRelatedAction())); + createChangeRelatedRepositoryAction(0, tr("Cherry Pick..."), "Git.CherryPick", + context, true, startChangeRelated); - createRepositoryAction(0, tr("Checkout..."), "Git.Checkout", - context, true, SLOT(startChangeRelatedAction())); + createChangeRelatedRepositoryAction(0, tr("Checkout..."), "Git.Checkout", + context, true, startChangeRelated); createRepositoryAction(0, tr("Rebase..."), "Git.Rebase", - context, true, SLOT(branchList())); + context, true, [this] { branchList(); }); createRepositoryAction(0, tr("Merge..."), "Git.Merge", - context, true, SLOT(branchList())); + context, true, [this] { branchList(); }); /* \Actions only in locator */ @@ -590,7 +599,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitToolsMenu->addSeparator(context); createRepositoryAction(gitToolsMenu, tr("Git Gui"), "Git.GitGui", - context, true, SLOT(gitGui())); + context, true, [this] { gitGui(); }); // -------------- gitToolsMenu->addSeparator(context); @@ -603,7 +612,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) m_mergeToolAction = createRepositoryAction(gitToolsMenu, tr("Merge Tool"), "Git.MergeTool", - context, true, SLOT(startMergeTool())); + context, true, [this] { startMergeTool(); }); /* \"Git Tools" menu */ @@ -611,7 +620,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitContainer->addSeparator(context); createRepositoryAction(gitContainer, tr("Actions on Commits..."), "Git.ChangeActions", - context, false, SLOT(startChangeRelatedAction())); + context, false, [this] { startChangeRelatedAction("Git.ChangeActions"); }); m_createRepositryAction = new QAction(tr("Create Repository..."), this); Command *createRepositoryCommand = ActionManager::registerAction( @@ -624,7 +633,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) m_submitCurrentAction = new QAction(VcsBaseSubmitEditor::submitIcon(), tr("Commit"), this); Command *command = ActionManager::registerAction(m_submitCurrentAction, Constants::SUBMIT_CURRENT, submitContext); command->setAttribute(Command::CA_UpdateText); - connect(m_submitCurrentAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog())); + connect(m_submitCurrentAction, &QAction::triggered, this, &GitPlugin::submitCurrentLog); m_diffSelectedFilesAction = new QAction(VcsBaseSubmitEditor::diffIcon(), tr("Diff &Selected Files"), this); ActionManager::registerAction(m_diffSelectedFilesAction, Constants::DIFF_SELECTED, submitContext); @@ -635,10 +644,10 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) m_redoAction = new QAction(tr("&Redo"), this); ActionManager::registerAction(m_redoAction, Core::Constants::REDO, submitContext); - connect(VcsManager::instance(), SIGNAL(repositoryChanged(QString)), - this, SLOT(updateContinueAndAbortCommands())); - connect(VcsManager::instance(), SIGNAL(repositoryChanged(QString)), - this, SLOT(updateBranches(QString)), Qt::QueuedConnection); + connect(VcsManager::instance(), &VcsManager::repositoryChanged, + this, &GitPlugin::updateContinueAndAbortCommands); + connect(VcsManager::instance(), &VcsManager::repositoryChanged, + this, &GitPlugin::updateBranches, Qt::QueuedConnection); Utils::MimeDatabase::addMimeTypes(QLatin1String(RC_GIT_MIME_XML)); @@ -804,14 +813,12 @@ void GitPlugin::startRebase() m_gitClient->interactiveRebase(topLevel, dialog.commit(), false); } -void GitPlugin::startChangeRelatedAction() +void GitPlugin::startChangeRelatedAction(const Id &id) { const VcsBasePluginState state = currentState(); if (!state.hasTopLevel()) return; - QAction *action = qobject_cast(sender()); - Id id = action ? Id::fromUniqueIdentifier(action->data().toInt()) : Id(); ChangeSelectionDialog dialog(state.topLevel(), id, ICore::mainWindow()); int result = dialog.exec(); diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index d2219a535be..5ed7b29e674 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -33,6 +33,8 @@ #include "gitsettings.h" +#include + #include #include @@ -40,6 +42,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QFile; class QAction; @@ -108,7 +112,7 @@ private slots: void undoUnstagedFileChanges(); void resetRepository(); void startRebase(); - void startChangeRelatedAction(); + void startChangeRelatedAction(const Core::Id &id); void stageFile(); void unstageFile(); void gitkForCurrentFile(); @@ -178,8 +182,13 @@ private: QAction *createRepositoryAction(Core::ActionContainer *ac, const QString &text, Core::Id id, const Core::Context &context, - bool addToLocator, const char *pluginSlot, + bool addToLocator, const std::function &callback, const QKeySequence &keys = QKeySequence()); + QAction *createChangeRelatedRepositoryAction(Core::ActionContainer *ac, + const QString &text, Core::Id id, + const Core::Context &context, + bool addToLocator, const std::function &callback, + const QKeySequence &keys = QKeySequence()); QAction *createRepositoryAction(Core::ActionContainer *ac, const QString &text, Core::Id id, const Core::Context &context, @@ -229,8 +238,6 @@ private: QString m_submitRepository; QString m_commitMessageFileName; bool m_submitActionTriggered; - - GitSettings m_settings; }; } // namespace Git diff --git a/src/plugins/imageviewer/imageviewerfile.cpp b/src/plugins/imageviewer/imageviewerfile.cpp index 479dfa94f9a..663f94a1f7b 100644 --- a/src/plugins/imageviewer/imageviewerfile.cpp +++ b/src/plugins/imageviewer/imageviewerfile.cpp @@ -97,7 +97,6 @@ Core::IDocument::OpenResult ImageViewerFile::open(QString *errorString, const QS Core::IDocument::OpenResult ImageViewerFile::openImpl(QString *errorString, const QString &fileName) { cleanUp(); - m_type = TypeInvalid; if (!QFileInfo(fileName).isReadable()) return OpenResult::ReadError; @@ -112,14 +111,16 @@ Core::IDocument::OpenResult ImageViewerFile::openImpl(QString *errorString, cons #ifndef QT_NO_SVG if (format.startsWith("svg")) { - m_type = TypeSvg; m_tempSvgItem = new QGraphicsSvgItem(fileName); QRectF bound = m_tempSvgItem->boundingRect(); if (bound.width() == 0 && bound.height() == 0) { + delete m_tempSvgItem; + m_tempSvgItem = 0; if (errorString) *errorString = tr("Failed to read SVG image."); return OpenResult::CannotHandle; } + m_type = TypeSvg; emit imageSizeChanged(QSize()); } else #endif @@ -133,14 +134,15 @@ Core::IDocument::OpenResult ImageViewerFile::openImpl(QString *errorString, cons m_isPaused = false; // force update setPaused(true); } else { - m_type = TypePixmap; m_pixmap = new QPixmap(fileName); if (m_pixmap->isNull()) { if (errorString) *errorString = tr("Failed to read image."); delete m_pixmap; + m_pixmap = 0; return OpenResult::CannotHandle; } + m_type = TypePixmap; emit imageSizeChanged(m_pixmap->size()); } @@ -242,10 +244,14 @@ void ImageViewerFile::updateVisibility() void ImageViewerFile::cleanUp() { delete m_pixmap; + m_pixmap = 0; delete m_movie; + m_movie = 0; #ifndef QT_NO_SVG delete m_tempSvgItem; + m_tempSvgItem = 0; #endif + m_type = TypeInvalid; } bool ImageViewerFile::save(QString *errorString, const QString &fileName, bool autoSave) diff --git a/src/plugins/ios/iosanalyzesupport.cpp b/src/plugins/ios/iosanalyzesupport.cpp index 9f5bb0000d6..ce593c9b94d 100644 --- a/src/plugins/ios/iosanalyzesupport.cpp +++ b/src/plugins/ios/iosanalyzesupport.cpp @@ -84,7 +84,7 @@ RunControl *IosAnalyzeSupport::createAnalyzeRunControl(IosRunConfiguration *runC if (device.isNull()) return 0; AnalyzerStartParameters params; - params.runMode = QmlProfilerRunMode; + params.runMode = ProjectExplorer::Constants::QML_PROFILER_RUN_MODE; params.sysroot = SysRootKitInformation::sysRoot(target->kit()).toString(); params.debuggee = runConfig->localExecutable().toUserOutput(); params.debuggeeArgs = Utils::QtcProcess::joinArgs(runConfig->commandLineArguments()); diff --git a/src/plugins/ios/iosdebugsupport.cpp b/src/plugins/ios/iosdebugsupport.cpp index 00708c64fd4..d6c2ebab011 100644 --- a/src/plugins/ios/iosdebugsupport.cpp +++ b/src/plugins/ios/iosdebugsupport.cpp @@ -77,8 +77,6 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi IDevice::ConstPtr device = DeviceKitInformation::device(target->kit()); if (device.isNull()) return 0; - QmakeProject *project = static_cast(target->project()); - Kit *kit = target->kit(); DebuggerStartParameters params; if (device->type() == Core::Id(Ios::Constants::IOS_DEVICE_TYPE)) { @@ -116,20 +114,12 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi } params.displayName = runConfig->applicationName(); params.remoteSetupNeeded = true; - if (!params.breakOnMain) - params.continueAfterAttach = true; - params.runConfiguration = runConfig; + params.continueAfterAttach = true; - DebuggerRunConfigurationAspect *aspect - = runConfig->extraAspect(); + auto aspect = runConfig->extraAspect(); bool cppDebug = aspect->useCppDebugger(); bool qmlDebug = aspect->useQmlDebugger(); if (cppDebug) { - params.languages |= CppLanguage; - params.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - if (ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - params.toolChainAbi = tc->targetAbi(); params.executable = runConfig->localExecutable().toString(); params.remoteChannel = QLatin1String("connect://localhost:0"); @@ -161,16 +151,11 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); } } - if (qmlDebug) { - params.languages |= QmlLanguage; - params.projectSourceDirectory = project->projectDirectory().toString(); - params.projectSourceFiles = project->files(QmakeProject::ExcludeGeneratedFiles); - params.projectBuildDirectory = project->rootQmakeProjectNode()->buildDir(); - if (!cppDebug) - params.startMode = AttachToRemoteServer; + if (qmlDebug && !cppDebug) { + params.startMode = AttachToRemoteServer; } - DebuggerRunControl * const debuggerRunControl = createDebuggerRunControl(params, errorMessage); + DebuggerRunControl *debuggerRunControl = createDebuggerRunControl(params, runConfig, errorMessage); if (debuggerRunControl) new IosDebugSupport(runConfig, debuggerRunControl, cppDebug, qmlDebug); return debuggerRunControl; diff --git a/src/plugins/ios/iosruncontrol.cpp b/src/plugins/ios/iosruncontrol.cpp index 3144574e3e4..7edeb14661f 100644 --- a/src/plugins/ios/iosruncontrol.cpp +++ b/src/plugins/ios/iosruncontrol.cpp @@ -41,7 +41,7 @@ namespace Ios { namespace Internal { IosRunControl::IosRunControl(IosRunConfiguration *rc) - : RunControl(rc, NormalRunMode) + : RunControl(rc, ProjectExplorer::Constants::NORMAL_RUN_MODE) , m_runner(new IosRunner(this, rc, false, false)) , m_running(false) { diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp index f2671539050..a160e3d53dd 100644 --- a/src/plugins/ios/iosrunfactories.cpp +++ b/src/plugins/ios/iosrunfactories.cpp @@ -159,16 +159,20 @@ IosRunControlFactory::IosRunControlFactory(QObject *parent) } bool IosRunControlFactory::canRun(RunConfiguration *runConfiguration, - RunMode mode) const + Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != QmlProfilerRunMode - && mode != DebugRunModeWithBreakOnMain) + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN + && mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { return false; + } + return qobject_cast(runConfiguration); } RunControl *IosRunControlFactory::create(RunConfiguration *runConfig, - RunMode mode, QString *errorMessage) + Core::Id mode, QString *errorMessage) { Q_ASSERT(canRun(runConfig, mode)); IosRunConfiguration *rc = qobject_cast(runConfig); @@ -181,9 +185,9 @@ RunControl *IosRunControlFactory::create(RunConfiguration *runConfig, activeRunControl->stop(); m_activeRunControls.remove(devId); } - if (mode == NormalRunMode) + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) res = new Ios::Internal::IosRunControl(rc); - else if (mode == QmlProfilerRunMode) + else if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) res = IosAnalyzeSupport::createAnalyzeRunControl(rc, errorMessage); else res = IosDebugSupport::createDebugRunControl(rc, errorMessage); diff --git a/src/plugins/ios/iosrunfactories.h b/src/plugins/ios/iosrunfactories.h index 51b566c294d..79238c741c2 100644 --- a/src/plugins/ios/iosrunfactories.h +++ b/src/plugins/ios/iosrunfactories.h @@ -81,9 +81,9 @@ public: explicit IosRunControlFactory(QObject *parent = 0); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const override; + Core::Id mode) const override; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage) override; private: mutable QMap > m_activeRunControls; diff --git a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp index a9a93bf8686..86e9c3658e9 100644 --- a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp +++ b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp @@ -461,10 +461,8 @@ static inline FeatureSet readRequiredFeatures(const QXmlStreamReader &reader) QString value = reader.attributes().value(QLatin1String(featuresRequiredC)).toString(); QStringList stringList = value.split(QLatin1Char(','), QString::SkipEmptyParts); FeatureSet features; - foreach (const QString &string, stringList) { - Feature feature(Id::fromString(string)); - features |= feature; - } + foreach (const QString &string, stringList) + features |= Feature::fromString(string); return features; } diff --git a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp index 5a7f282bd2a..c371a437a8a 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp @@ -169,7 +169,7 @@ QVariant DeviceManagerModel::data(const QModelIndex &index, int role) const return QVariant(); const IDevice::ConstPtr dev = device(index.row()); if (role == Qt::UserRole) - return dev->id().uniqueIdentifier(); + return dev->id().toSetting(); QString name; if (d->deviceManager->defaultDevice(dev->type()) == dev) name = tr("%1 (default for %2)").arg(dev->displayName(), dev->displayType()); diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp index 3e125ecacb6..ec31a2dab8d 100644 --- a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp @@ -47,7 +47,6 @@ #include #include -#include #include #include @@ -95,12 +94,9 @@ DeviceSettingsWidget::DeviceSettingsWidget(QWidget *parent) m_deviceManager(DeviceManager::cloneInstance()), m_deviceManagerModel(new DeviceManagerModel(m_deviceManager, this)), m_nameValidator(new NameValidator(m_deviceManager, this)), - m_additionalActionsMapper(new QSignalMapper(this)), m_configWidget(0) { initGui(); - connect(m_additionalActionsMapper, SIGNAL(mapped(int)), - SLOT(handleAdditionalActionRequest(int))); connect(m_deviceManager, SIGNAL(deviceUpdated(Core::Id)), SLOT(handleDeviceUpdated(Core::Id))); } @@ -302,8 +298,8 @@ void DeviceSettingsWidget::currentDeviceChanged(int index) foreach (Id actionId, device->actionIds()) { QPushButton * const button = new QPushButton(device->displayNameForActionId(actionId)); m_additionalActionButtons << button; - connect(button, SIGNAL(clicked()), m_additionalActionsMapper, SLOT(map())); - m_additionalActionsMapper->setMapping(button, actionId.uniqueIdentifier()); + connect(button, &QAbstractButton::clicked, this, + [this, actionId] { handleAdditionalActionRequest(actionId); }); m_ui->buttonsLayout->insertWidget(m_ui->buttonsLayout->count() - 1, button); } @@ -322,12 +318,12 @@ void DeviceSettingsWidget::clearDetails() m_ui->autoDetectionValueLabel->clear(); } -void DeviceSettingsWidget::handleAdditionalActionRequest(int actionId) +void DeviceSettingsWidget::handleAdditionalActionRequest(Id actionId) { const IDevice::Ptr device = m_deviceManager->mutableDevice(currentDevice()->id()); QTC_ASSERT(device, return); updateDeviceFromUi(); - device->executeAction(Id::fromUniqueIdentifier(actionId), this); + device->executeAction(actionId, this); // Widget must be set up from scratch, because the action could have changed random attributes. currentDeviceChanged(currentIndex()); diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h index 564457a71ae..9a21dea44af 100644 --- a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h +++ b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h @@ -38,7 +38,6 @@ #include QT_BEGIN_NAMESPACE -class QSignalMapper; class QPushButton; QT_END_NAMESPACE @@ -69,11 +68,11 @@ private slots: void deviceNameEditingFinished(); void setDefaultDevice(); void testDevice(); - void handleAdditionalActionRequest(int actionId); void handleProcessListRequested(); private: void initGui(); + void handleAdditionalActionRequest(Core::Id actionId); void displayCurrent(); void setDeviceInfoWidgetsEnabled(bool enable); IDevice::ConstPtr currentDevice() const; @@ -88,7 +87,6 @@ private: DeviceManagerModel * const m_deviceManagerModel; NameValidator * const m_nameValidator; QList m_additionalActionButtons; - QSignalMapper * const m_additionalActionsMapper; IDeviceWidget *m_configWidget; }; diff --git a/src/plugins/projectexplorer/journaldwatcher.cpp b/src/plugins/projectexplorer/journaldwatcher.cpp index 29af127bf64..1ea4587addc 100644 --- a/src/plugins/projectexplorer/journaldwatcher.cpp +++ b/src/plugins/projectexplorer/journaldwatcher.cpp @@ -157,8 +157,10 @@ const QByteArray &JournaldWatcher::machineId() static QByteArray id; if (id.isEmpty()) { sd_id128 sdId; - if (sd_id128_get_machine(&sdId) == 0) - id = QByteArray(reinterpret_cast(sdId.bytes), 16); + if (sd_id128_get_machine(&sdId) == 0) { + id.resize(32); + sd_id128_to_string(sdId, id.data()); + } } return id; } @@ -209,6 +211,9 @@ void JournaldWatcher::handleEntry() if (!d->m_notifier) return; + if (sd_journal_process(d->m_journalContext) != SD_JOURNAL_APPEND) + return; + LogEntry logEntry; forever { logEntry = d->retrieveEntry(); @@ -225,6 +230,7 @@ void JournaldWatcher::handleEntry() quint64 pidNum = pid.isEmpty() ? 0 : QString::fromLatin1(pid).toInt(); QString message = QString::fromUtf8(logEntry.value(QByteArrayLiteral("MESSAGE"))); + message.append(QLatin1Char('\n')); // Add newline. emit journaldOutput(pidNum, message); } diff --git a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp index 647384cec80..af2641351c2 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp @@ -145,7 +145,7 @@ FeatureSet JsonKitsPage::evaluate(const QVectorexpander())) - features |= f.feature; + features |= Feature::fromString(wiz->expander()->expand(f.feature)); } return features; } @@ -167,7 +167,7 @@ QVector JsonKitsPage::parseFeatures(const QVar foreach (const QVariant &element, data.toList()) { if (element.type() == QVariant::String) { - result.append({ Id::fromString(element.toString()), QVariant(true) }); + result.append({ element.toString(), QVariant(true) }); } else if (element.type() == QVariant::Map) { const QVariantMap obj = element.toMap(); const QString feature = obj.value(QLatin1String(KEY_FEATURE)).toString(); @@ -177,7 +177,7 @@ QVector JsonKitsPage::parseFeatures(const QVar return QVector(); } - result.append({ Id::fromString(feature), obj.value(QLatin1String(KEY_CONDITION), true) }); + result.append({ feature, obj.value(QLatin1String(KEY_CONDITION), true) }); } else { if (errorMessage) *errorMessage = tr("Feature list element is not a string or object."); diff --git a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h index c2e56112268..ac9dd50a221 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h @@ -57,11 +57,11 @@ public: class ConditionalFeature { public: - ConditionalFeature() : feature(Core::Id()) { } - ConditionalFeature(const Core::Feature &f, const QVariant &c) : feature(f), condition(c) + ConditionalFeature() = default; + ConditionalFeature(const QString &f, const QVariant &c) : feature(f), condition(c) { } - Core::Feature feature; + QString feature; QVariant condition; }; static QVector parseFeatures(const QVariant &data, diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizard.h b/src/plugins/projectexplorer/jsonwizard/jsonwizard.h index edc61009858..7809879b9f4 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizard.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizard.h @@ -98,8 +98,8 @@ signals: void allDone(const JsonWizard::GeneratorFiles &files); // emitted just after the wizard is done with the files. They are ready to be opened. public slots: - void accept(); - void reject(); + void accept() override; + void reject() override; private slots: void handleNewPages(int pageId); diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index 0d4a5eb9842..19ef2a939b2 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -346,7 +346,7 @@ Core::FeatureSet DeviceTypeKitInformation::availableFeatures(const Kit *k) const Core::Id id = DeviceTypeKitInformation::deviceTypeId(k); Core::FeatureSet result; if (id.isValid()) - result |= Core::Feature(Core::Id::fromString(QString::fromLatin1("DeviceType.") + id.toString())); + result |= Core::Feature::fromString(QString::fromLatin1("DeviceType.") + id.toString()); return result; } diff --git a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp index 1aaa02a0672..c146bddd668 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp @@ -228,7 +228,7 @@ DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *workin = ExtensionSystem::PluginManager::getObjects(); foreach (IDeviceFactory *factory, factories) { foreach (Id id, factory->availableCreationIds()) - m_comboBox->addItem(factory->displayNameForId(id), id.uniqueIdentifier()); + m_comboBox->addItem(factory->displayNameForId(id), id.toSetting()); } m_comboBox->setToolTip(toolTip()); @@ -263,7 +263,7 @@ void DeviceTypeInformationConfigWidget::refresh() if (!devType.isValid()) m_comboBox->setCurrentIndex(-1); for (int i = 0; i < m_comboBox->count(); ++i) { - if (m_comboBox->itemData(i).toInt() == devType.uniqueIdentifier()) { + if (m_comboBox->itemData(i) == devType.toSetting()) { m_comboBox->setCurrentIndex(i); break; } @@ -277,7 +277,7 @@ void DeviceTypeInformationConfigWidget::makeReadOnly() void DeviceTypeInformationConfigWidget::currentTypeChanged(int idx) { - Id type = idx < 0 ? Id() : Id::fromUniqueIdentifier(m_comboBox->itemData(idx).toInt()); + Id type = idx < 0 ? Id() : Id::fromSetting(m_comboBox->itemData(idx)); DeviceTypeKitInformation::setDeviceTypeId(m_kit, type); } diff --git a/src/plugins/projectexplorer/localapplicationruncontrol.cpp b/src/plugins/projectexplorer/localapplicationruncontrol.cpp index a1596b34b99..1ce1869c7c7 100644 --- a/src/plugins/projectexplorer/localapplicationruncontrol.cpp +++ b/src/plugins/projectexplorer/localapplicationruncontrol.cpp @@ -48,12 +48,12 @@ LocalApplicationRunControlFactory::~LocalApplicationRunControlFactory() { } -bool LocalApplicationRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool LocalApplicationRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - return mode == NormalRunMode && qobject_cast(runConfiguration); + return mode == Constants::NORMAL_RUN_MODE && qobject_cast(runConfiguration); } -RunControl *LocalApplicationRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *LocalApplicationRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { Q_UNUSED(errorMessage) QTC_ASSERT(canRun(runConfiguration, mode), return 0); @@ -72,7 +72,7 @@ RunControl *LocalApplicationRunControlFactory::create(RunConfiguration *runConfi // ApplicationRunControl -LocalApplicationRunControl::LocalApplicationRunControl(RunConfiguration *rc, RunMode mode) +LocalApplicationRunControl::LocalApplicationRunControl(RunConfiguration *rc, Core::Id mode) : RunControl(rc, mode), m_runMode(ApplicationLauncher::Console), m_running(false) { setIcon(QLatin1String(Constants::ICON_RUN_SMALL)); diff --git a/src/plugins/projectexplorer/localapplicationruncontrol.h b/src/plugins/projectexplorer/localapplicationruncontrol.h index dca6a02dd36..40cd52439fa 100644 --- a/src/plugins/projectexplorer/localapplicationruncontrol.h +++ b/src/plugins/projectexplorer/localapplicationruncontrol.h @@ -43,8 +43,8 @@ class LocalApplicationRunControlFactory : public IRunControlFactory public: LocalApplicationRunControlFactory (); ~LocalApplicationRunControlFactory(); - bool canRun(RunConfiguration *runConfiguration, RunMode mode) const; - RunControl* create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage); + bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const; + RunControl* create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage); }; } // namespace Internal @@ -53,7 +53,7 @@ class PROJECTEXPLORER_EXPORT LocalApplicationRunControl : public RunControl { Q_OBJECT public: - LocalApplicationRunControl(RunConfiguration *runConfiguration, RunMode mode); + LocalApplicationRunControl(RunConfiguration *runConfiguration, Core::Id mode); ~LocalApplicationRunControl(); void start(); StopResult stop(); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 7f297bbc653..3bfd73b1e16 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -203,12 +203,12 @@ public: void deploy(QList); int queue(QList, QList stepIds); void updateContextMenuActions(); - void executeRunConfiguration(RunConfiguration *, RunMode mode); + void executeRunConfiguration(RunConfiguration *, Core::Id mode); QPair buildSettingsEnabledForSession(); QPair buildSettingsEnabled(Project *pro); void addToRecentProjects(const QString &fileName, const QString &displayName); - void startRunControl(RunControl *runControl, RunMode runMode); + void startRunControl(RunControl *runControl, Core::Id runMode); void updateActions(); void updateContext(); @@ -350,9 +350,9 @@ public: QString m_lastOpenDirectory; QPointer m_delayedRunConfiguration; - QList> m_delayedRunConfigurationForRun; + QList> m_delayedRunConfigurationForRun; bool m_shouldHaveRunConfiguration; - RunMode m_runMode; + Core::Id m_runMode; QString m_projectFilterString; MiniProjectTargetSelector * m_targetSelector; ProjectExplorerSettings m_projectExplorerSettings; @@ -373,7 +373,7 @@ public: ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() : m_shouldHaveRunConfiguration(false), - m_runMode(NoRunMode), + m_runMode(Constants::NO_RUN_MODE), m_projectsMode(0), m_kitManager(0), m_toolChainManager(0), @@ -1901,7 +1901,7 @@ void ProjectExplorerPluginPrivate::buildStateChanged(Project * pro) } // NBS TODO implement more than one runner -static IRunControlFactory *findRunControlFactory(RunConfiguration *config, RunMode mode) +static IRunControlFactory *findRunControlFactory(RunConfiguration *config, Core::Id mode) { return ExtensionSystem::PluginManager::getObject( [&config, &mode](IRunControlFactory *factory) { @@ -1909,7 +1909,7 @@ static IRunControlFactory *findRunControlFactory(RunConfiguration *config, RunMo }); } -void ProjectExplorerPluginPrivate::executeRunConfiguration(RunConfiguration *runConfiguration, RunMode runMode) +void ProjectExplorerPluginPrivate::executeRunConfiguration(RunConfiguration *runConfiguration, Core::Id runMode) { if (!runConfiguration->isConfigured()) { QString errorMessage; @@ -1947,18 +1947,18 @@ void ProjectExplorerPlugin::showRunErrorMessage(const QString &errorMessage) QMessageBox::critical(ICore::mainWindow(), errorMessage.isNull() ? tr("Unknown error") : tr("Could Not Run"), errorMessage); } -void ProjectExplorerPlugin::startRunControl(RunControl *runControl, RunMode runMode) +void ProjectExplorerPlugin::startRunControl(RunControl *runControl, Core::Id runMode) { dd->startRunControl(runControl, runMode); } -void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl, RunMode runMode) +void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl, Core::Id runMode) { m_outputPane->createNewOutputWindow(runControl); m_outputPane->flash(); // one flash for starting m_outputPane->showTabFor(runControl); - bool popup = (runMode == NormalRunMode && dd->m_projectExplorerSettings.showRunOutput) - || ((runMode == DebugRunMode || runMode == DebugRunModeWithBreakOnMain) + bool popup = (runMode == Constants::NORMAL_RUN_MODE && dd->m_projectExplorerSettings.showRunOutput) + || ((runMode == Constants::DEBUG_RUN_MODE || runMode == Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) && m_projectExplorerSettings.showDebugOutput); m_outputPane->setBehaviorOnOutput(runControl, popup ? AppOutputPane::Popup : AppOutputPane::Flash); runControl->start(); @@ -2001,13 +2001,13 @@ void ProjectExplorerPluginPrivate::buildQueueFinished(bool success) } m_delayedRunConfiguration = 0; m_shouldHaveRunConfiguration = false; - m_runMode = NoRunMode; + m_runMode = Constants::NO_RUN_MODE; } void ProjectExplorerPluginPrivate::runConfigurationConfigurationFinished() { RunConfiguration *rc = qobject_cast(sender()); - RunMode runMode = NoRunMode; + Core::Id runMode = Constants::NO_RUN_MODE; for (int i = 0; i < m_delayedRunConfigurationForRun.size(); ++i) { if (m_delayedRunConfigurationForRun.at(i).first == rc) { runMode = m_delayedRunConfigurationForRun.at(i).second; @@ -2015,7 +2015,7 @@ void ProjectExplorerPluginPrivate::runConfigurationConfigurationFinished() break; } } - if (runMode != NoRunMode && rc->isConfigured()) + if (runMode != Constants::NO_RUN_MODE && rc->isConfigured()) executeRunConfiguration(rc, runMode); } @@ -2368,12 +2368,12 @@ void ProjectExplorerPluginPrivate::cleanSession() void ProjectExplorerPluginPrivate::handleRunProject() { - m_instance->runStartupProject(NormalRunMode); + m_instance->runStartupProject(Constants::NORMAL_RUN_MODE); } void ProjectExplorerPluginPrivate::runProjectWithoutDeploy() { - m_instance->runStartupProject(NormalRunMode, true); + m_instance->runStartupProject(Constants::NORMAL_RUN_MODE, true); } void ProjectExplorerPluginPrivate::runProjectContextMenu() @@ -2381,7 +2381,7 @@ void ProjectExplorerPluginPrivate::runProjectContextMenu() Node *node = ProjectTree::currentNode(); ProjectNode *projectNode = node ? node->asProjectNode() : 0; if (projectNode == ProjectTree::currentProject()->rootProjectNode() || !projectNode) { - m_instance->runProject(ProjectTree::currentProject(), NormalRunMode); + m_instance->runProject(ProjectTree::currentProject(), Constants::NORMAL_RUN_MODE); } else { QAction *act = qobject_cast(sender()); if (!act) @@ -2389,7 +2389,7 @@ void ProjectExplorerPluginPrivate::runProjectContextMenu() RunConfiguration *rc = act->data().value(); if (!rc) return; - m_instance->runRunConfiguration(rc, NormalRunMode); + m_instance->runRunConfiguration(rc, Constants::NORMAL_RUN_MODE); } } @@ -2493,7 +2493,7 @@ static bool hasDeploySettings(Project *pro) }); } -void ProjectExplorerPlugin::runProject(Project *pro, RunMode mode, const bool forceSkipDeploy) +void ProjectExplorerPlugin::runProject(Project *pro, Core::Id mode, const bool forceSkipDeploy) { if (!pro) return; @@ -2503,13 +2503,13 @@ void ProjectExplorerPlugin::runProject(Project *pro, RunMode mode, const bool fo runRunConfiguration(rc, mode, forceSkipDeploy); } -void ProjectExplorerPlugin::runStartupProject(RunMode runMode, bool forceSkipDeploy) +void ProjectExplorerPlugin::runStartupProject(Core::Id runMode, bool forceSkipDeploy) { runProject(SessionManager::startupProject(), runMode, forceSkipDeploy); } void ProjectExplorerPlugin::runRunConfiguration(RunConfiguration *rc, - RunMode runMode, + Core::Id runMode, const bool forceSkipDeploy) { if (!rc->isEnabled()) @@ -2680,7 +2680,7 @@ void ProjectExplorerPluginPrivate::updateDeployActions() emit m_instance->updateRunActions(); } -bool ProjectExplorerPlugin::canRun(Project *project, RunMode runMode, QString *whyNot) +bool ProjectExplorerPlugin::canRun(Project *project, Core::Id runMode, QString *whyNot) { if (!project) { if (whyNot) @@ -2747,7 +2747,7 @@ void ProjectExplorerPluginPrivate::slotUpdateRunActions() { Project *project = SessionManager::startupProject(); QString whyNot; - const bool state = ProjectExplorerPlugin::canRun(project, NormalRunMode, &whyNot); + const bool state = ProjectExplorerPlugin::canRun(project, Constants::NORMAL_RUN_MODE, &whyNot); m_runAction->setEnabled(state); m_runAction->setToolTip(whyNot); m_runWithoutDeployAction->setEnabled(state); @@ -3216,6 +3216,7 @@ void ProjectExplorerPluginPrivate::updateSessionMenu() const QString activeSession = SessionManager::activeSession(); foreach (const QString &session, SessionManager::sessions()) { QAction *act = ag->addAction(session); + act->setData(session); act->setCheckable(true); if (session == activeSession) act->setChecked(true); @@ -3226,7 +3227,7 @@ void ProjectExplorerPluginPrivate::updateSessionMenu() void ProjectExplorerPluginPrivate::setSession(QAction *action) { - QString session = action->text(); + QString session = action->data().toString(); if (session != SessionManager::activeSession()) SessionManager::loadSession(session); } diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index e548268f712..61d86e65aaa 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -33,6 +33,7 @@ #include "projectexplorer_export.h" #include "projectexplorerconstants.h" +#include "runconfiguration.h" #include @@ -88,7 +89,7 @@ public: static void setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes); static Internal::ProjectExplorerSettings projectExplorerSettings(); - static void startRunControl(RunControl *runControl, RunMode runMode); + static void startRunControl(RunControl *runControl, Core::Id runMode); static void showRunErrorMessage(const QString &errorMessage); // internal public for FlatModel @@ -97,10 +98,10 @@ public: static bool coreAboutToClose(); static QList > recentProjects(); - static bool canRun(Project *pro, RunMode runMode, QString *whyNot = 0); - static void runProject(Project *pro, RunMode, const bool forceSkipDeploy = false); - static void runStartupProject(RunMode runMode, bool forceSkipDeploy = false); - static void runRunConfiguration(RunConfiguration *rc, RunMode runMode, + static bool canRun(Project *pro, Core::Id runMode, QString *whyNot = 0); + static void runProject(Project *pro, Core::Id, const bool forceSkipDeploy = false); + static void runStartupProject(Core::Id runMode, bool forceSkipDeploy = false); + static void runRunConfiguration(RunConfiguration *rc, Core::Id runMode, const bool forceSkipDeploy = false); static void addExistingFiles(FolderNode *projectNode, const QStringList &filePaths); @@ -128,7 +129,7 @@ signals: // or the file list of a specific project has changed. void fileListChanged(); - void aboutToExecuteProject(ProjectExplorer::Project *project, RunMode runMode); + void aboutToExecuteProject(ProjectExplorer::Project *project, Core::Id runMode); void recentProjectsChanged(); void settingsChanged(); diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 37a346332ca..c6ec2b89cf8 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -267,22 +267,14 @@ const char SHOW_FILE_FILTER_DEFAULT[] = "*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; * const char PAGE_ID_PREFIX[] = "PE.Wizard.Page."; const char GENERATOR_ID_PREFIX[] = "PE.Wizard.Generator."; +// RunMode +const char NO_RUN_MODE[]="RunConfiguration.NoRunMode"; +const char NORMAL_RUN_MODE[]="RunConfiguration.NormalRunMode"; +const char QML_PROFILER_RUN_MODE[]="RunConfiguration.QmlProfilerRunMode"; +const char DEBUG_RUN_MODE[]="RunConfiguration.DebugRunMode"; +const char DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN[]="RunConfiguration.DebugRunModeWithBreakOnMain"; + } // namespace Constants - -// Run modes -enum RunMode { - NoRunMode, - NormalRunMode, - DebugRunMode, - DebugRunModeWithBreakOnMain, - QmlProfilerRunMode, - CallgrindRunMode, - MemcheckRunMode, - MemcheckWithGdbRunMode, - ClangStaticAnalyzerMode, - PerfProfilerRunMode -}; - } // namespace ProjectExplorer #endif // PROJECTEXPLORERCONSTANTS_H diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp index b2127f430ac..932943394f8 100644 --- a/src/plugins/projectexplorer/projectwizardpage.cpp +++ b/src/plugins/projectexplorer/projectwizardpage.cpp @@ -535,7 +535,10 @@ IVersionControl *ProjectWizardPage::currentVersionControl() void ProjectWizardPage::setFiles(const QStringList &fileNames) { - m_commonDirectory = Utils::commonPath(fileNames); + if (fileNames.count() == 1) + m_commonDirectory = QFileInfo(fileNames.first()).absolutePath(); + else + m_commonDirectory = Utils::commonPath(fileNames); QString fileMessage; { QTextStream str(&fileMessage); diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 12f044677e4..8c3fdf8254c 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -51,7 +51,7 @@ #include #endif -using namespace ProjectExplorer; +namespace ProjectExplorer { /*! \class ProjectExplorer::ProcessHandle @@ -515,7 +515,7 @@ IRunConfigurationAspect *IRunControlFactory::createRunConfigurationAspect(RunCon than it needs to be. */ -RunControl::RunControl(RunConfiguration *runConfiguration, RunMode mode) +RunControl::RunControl(RunConfiguration *runConfiguration, Core::Id mode) : m_runMode(mode), m_runConfiguration(runConfiguration), m_outputFormatter(0) { if (runConfiguration) { @@ -537,7 +537,7 @@ Utils::OutputFormatter *RunControl::outputFormatter() return m_outputFormatter; } -RunMode RunControl::runMode() const +Core::Id RunControl::runMode() const { return m_runMode; } @@ -663,3 +663,5 @@ void RunControl::appendMessage(const QString &msg, Utils::OutputFormat format) { emit appendMessage(this, msg, format); } + +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 43890d3ad99..ff511a84a79 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -253,8 +253,8 @@ public: explicit IRunControlFactory(QObject *parent = 0); virtual ~IRunControlFactory(); - virtual bool canRun(RunConfiguration *runConfiguration, RunMode mode) const = 0; - virtual RunControl *create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) = 0; + virtual bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const = 0; + virtual RunControl *create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) = 0; virtual IRunConfigurationAspect *createRunConfigurationAspect(RunConfiguration *rc); }; @@ -283,7 +283,7 @@ public: AsynchronousStop // Stop sequence has been started }; - RunControl(RunConfiguration *runConfiguration, RunMode mode); + RunControl(RunConfiguration *runConfiguration, Core::Id mode); virtual ~RunControl(); virtual void start() = 0; @@ -304,7 +304,7 @@ public: bool sameRunConfiguration(const RunControl *other) const; Utils::OutputFormatter *outputFormatter(); - RunMode runMode() const; + Core::Id runMode() const; public slots: void bringApplicationToForeground(qint64 pid); @@ -328,7 +328,7 @@ protected: private: QString m_displayName; - RunMode m_runMode; + Core::Id m_runMode; QString m_icon; const QPointer m_runConfiguration; Utils::OutputFormatter *m_outputFormatter; diff --git a/src/plugins/projectexplorer/task.cpp b/src/plugins/projectexplorer/task.cpp index eabf8063e18..2f83d14e512 100644 --- a/src/plugins/projectexplorer/task.cpp +++ b/src/plugins/projectexplorer/task.cpp @@ -137,9 +137,9 @@ bool operator<(const Task &a, const Task &b) // Can't happen return true; } else { - if (a.category.uniqueIdentifier() < b.category.uniqueIdentifier()) + if (a.category < b.category) return true; - if (b.category.uniqueIdentifier() < a.category.uniqueIdentifier()) + if (b.category < a.category) return false; return a.taskId < b.taskId; } diff --git a/src/plugins/projectexplorer/taskmodel.cpp b/src/plugins/projectexplorer/taskmodel.cpp index d3605c03471..bcfbcf802ac 100644 --- a/src/plugins/projectexplorer/taskmodel.cpp +++ b/src/plugins/projectexplorer/taskmodel.cpp @@ -85,7 +85,7 @@ bool TaskModel::hasFile(const QModelIndex &index) const void TaskModel::addCategory(Core::Id categoryId, const QString &categoryName) { - QTC_ASSERT(categoryId.uniqueIdentifier(), return); + QTC_ASSERT(categoryId.isValid(), return); CategoryData data; data.displayName = categoryName; m_categories.insert(categoryId, data); @@ -93,12 +93,12 @@ void TaskModel::addCategory(Core::Id categoryId, const QString &categoryName) QList TaskModel::tasks(Core::Id categoryId) const { - if (categoryId.uniqueIdentifier() == 0) + if (!categoryId.isValid()) return m_tasks; QList taskList; foreach (const Task &t, m_tasks) { - if (t.category.uniqueIdentifier() == categoryId.uniqueIdentifier()) + if (t.category == categoryId) taskList.append(t); } return taskList; @@ -170,7 +170,7 @@ void TaskModel::clearTasks(Core::Id categoryId) { typedef QHash::ConstIterator IdCategoryConstIt; - if (categoryId.uniqueIdentifier() == 0) { + if (!categoryId.isValid()) { if (m_tasks.count() == 0) return; beginRemoveRows(QModelIndex(), 0, m_tasks.count() -1); diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index a7e34151254..d069a50f6df 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -384,7 +384,7 @@ void TaskWindow::clearTasks(Core::Id categoryId) void TaskWindow::setCategoryVisibility(Core::Id categoryId, bool visible) { - if (categoryId.uniqueIdentifier() == 0) + if (!categoryId.isValid()) return; QList categories = d->m_filter->filteredCategories(); diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index 4484ed14a9c..eab59f24f62 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -406,7 +406,7 @@ private: class PythonRunControl : public RunControl { public: - PythonRunControl(PythonRunConfiguration *runConfiguration, RunMode mode); + PythonRunControl(PythonRunConfiguration *runConfiguration, Core::Id mode); void start(); StopResult stop(); @@ -1098,16 +1098,16 @@ bool PythonProjectNode::renameFile(const QString &filePath, const QString &newFi class PythonRunControlFactory : public IRunControlFactory { public: - bool canRun(RunConfiguration *runConfiguration, RunMode mode) const; - RunControl *create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage); + bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const; + RunControl *create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage); }; -bool PythonRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool PythonRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - return mode == NormalRunMode && dynamic_cast(runConfiguration); + return mode == ProjectExplorer::Constants::NORMAL_RUN_MODE && dynamic_cast(runConfiguration); } -RunControl *PythonRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *PythonRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { Q_UNUSED(errorMessage) QTC_ASSERT(canRun(runConfiguration, mode), return 0); @@ -1116,7 +1116,7 @@ RunControl *PythonRunControlFactory::create(RunConfiguration *runConfiguration, // PythonRunControl -PythonRunControl::PythonRunControl(PythonRunConfiguration *rc, RunMode mode) +PythonRunControl::PythonRunControl(PythonRunConfiguration *rc, Core::Id mode) : RunControl(rc, mode), m_running(false) { setIcon(QLatin1String(ProjectExplorer::Constants::ICON_RUN_SMALL)); diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp index c499e2e38a9..3b176e1db06 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp @@ -190,7 +190,7 @@ AddLibraryWizard::LibraryKind LibraryTypePage::libraryKind() const ///////////// DetailsPage::DetailsPage(AddLibraryWizard *parent) - : QWizardPage(parent), m_libraryWizard(parent), m_libraryDetailsController(0) + : QWizardPage(parent), m_libraryWizard(parent) { m_libraryDetailsWidget = new Ui::LibraryDetailsWidget(); m_libraryDetailsWidget->setupUi(this); diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.h b/src/plugins/qmakeprojectmanager/addlibrarywizard.h index 624eff7e6dd..ab92fa98da2 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.h +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.h @@ -93,9 +93,9 @@ public: signals: private: - LibraryTypePage *m_libraryTypePage; - DetailsPage *m_detailsPage; - SummaryPage *m_summaryPage; + LibraryTypePage *m_libraryTypePage = nullptr; + DetailsPage *m_detailsPage = nullptr; + SummaryPage *m_summaryPage = nullptr; QString m_proFile; }; @@ -109,10 +109,10 @@ public: AddLibraryWizard::LibraryKind libraryKind() const; private: - QRadioButton *m_internalRadio; - QRadioButton *m_externalRadio; - QRadioButton *m_systemRadio; - QRadioButton *m_packageRadio; + QRadioButton *m_internalRadio = nullptr; + QRadioButton *m_externalRadio = nullptr; + QRadioButton *m_systemRadio = nullptr; + QRadioButton *m_packageRadio = nullptr; }; class DetailsPage : public QWizardPage @@ -126,8 +126,8 @@ public: private: AddLibraryWizard *m_libraryWizard; - Ui::LibraryDetailsWidget *m_libraryDetailsWidget; - LibraryDetailsController *m_libraryDetailsController; + Ui::LibraryDetailsWidget *m_libraryDetailsWidget = nullptr; + LibraryDetailsController *m_libraryDetailsController = nullptr; }; class SummaryPage : public QWizardPage @@ -138,9 +138,9 @@ public: virtual void initializePage(); QString snippet() const; private: - AddLibraryWizard *m_libraryWizard; - QLabel *m_summaryLabel; - QLabel *m_snippetLabel; + AddLibraryWizard *m_libraryWizard = nullptr; + QLabel *m_summaryLabel = nullptr; + QLabel *m_snippetLabel = nullptr; QString m_snippet; }; diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizard.cpp b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizard.cpp index d0308aff001..480d585e545 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizard.cpp +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizard.cpp @@ -52,7 +52,7 @@ CustomWidgetWizard::CustomWidgetWizard() setDisplayName(tr("Qt Custom Designer Widget")); setDescription(tr("Creates a Qt Custom Designer Widget or a Custom Widget Collection.")); setIcon(QIcon(QLatin1String(":/wizards/images/gui.png"))); - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QWIDGETS)); + setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QWIDGETS)); } Core::BaseFileWizard *CustomWidgetWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp index d9a2515f5a9..37c66380cb9 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp @@ -83,9 +83,7 @@ static Utils::FileName pathFromId(Core::Id id) DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *parent, Core::Id id) : LocalApplicationRunConfiguration(parent, id), - m_proFilePath(pathFromId(id)), - m_runMode(ApplicationLauncher::Gui), - m_isUsingDyldImageSuffix(false) + m_proFilePath(pathFromId(id)) { addExtraAspect(new ProjectExplorer::LocalEnvironmentAspect(this)); @@ -174,10 +172,7 @@ void DesktopQmakeRunConfiguration::ctor() DesktopQmakeRunConfigurationWidget::DesktopQmakeRunConfigurationWidget(DesktopQmakeRunConfiguration *qmakeRunConfiguration, QWidget *parent) : QWidget(parent), - m_qmakeRunConfiguration(qmakeRunConfiguration), - m_ignoreChange(false), - m_usingDyldImageSuffix(0), - m_isShown(false) + m_qmakeRunConfiguration(qmakeRunConfiguration) { QVBoxLayout *vboxTopLayout = new QVBoxLayout(this); vboxTopLayout->setMargin(0); diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h index d1e23c20372..6778ec6d0a8 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h @@ -128,11 +128,11 @@ private: Utils::FileName m_proFilePath; // Full path to the Application Pro File // Cached startup sub project information - ProjectExplorer::ApplicationLauncher::Mode m_runMode; - bool m_isUsingDyldImageSuffix; + ProjectExplorer::ApplicationLauncher::Mode m_runMode = ProjectExplorer::ApplicationLauncher::Gui; + bool m_isUsingDyldImageSuffix = false; QString m_userWorkingDirectory; - bool m_parseSuccess; - bool m_parseInProgress; + bool m_parseSuccess = false; + bool m_parseInProgress = false; }; class DesktopQmakeRunConfigurationWidget : public QWidget @@ -165,19 +165,19 @@ private slots: void usingDyldImageSuffixChanged(bool); private: - DesktopQmakeRunConfiguration *m_qmakeRunConfiguration; - bool m_ignoreChange; - QLabel *m_disabledIcon; - QLabel *m_disabledReason; - QLabel *m_executableLineLabel; - Utils::PathChooser *m_workingDirectoryEdit; - QLineEdit *m_argumentsLineEdit; - QCheckBox *m_useTerminalCheck; - QCheckBox *m_useQvfbCheck; - QCheckBox *m_usingDyldImageSuffix; - QLineEdit *m_qmlDebugPort; + DesktopQmakeRunConfiguration *m_qmakeRunConfiguration = nullptr; + bool m_ignoreChange = false; + QLabel *m_disabledIcon = nullptr; + QLabel *m_disabledReason = nullptr; + QLabel *m_executableLineLabel = nullptr; + Utils::PathChooser *m_workingDirectoryEdit = nullptr; + QLineEdit *m_argumentsLineEdit = nullptr; + QCheckBox *m_useTerminalCheck = nullptr; + QCheckBox *m_useQvfbCheck = nullptr; + QCheckBox *m_usingDyldImageSuffix = nullptr; + QLineEdit *m_qmlDebugPort = nullptr; Utils::DetailsWidget *m_detailsContainer; - bool m_isShown; + bool m_isShown = false; }; class DesktopQmakeRunConfigurationFactory : public QmakeRunConfigurationFactory diff --git a/src/plugins/qmakeprojectmanager/externaleditors.cpp b/src/plugins/qmakeprojectmanager/externaleditors.cpp index e77bee6c852..58d3b80f083 100644 --- a/src/plugins/qmakeprojectmanager/externaleditors.cpp +++ b/src/plugins/qmakeprojectmanager/externaleditors.cpp @@ -210,8 +210,7 @@ DesignerExternalEditor::DesignerExternalEditor(QObject *parent) : ExternalQtEditor(designerIdC, QLatin1String(designerDisplayName), QLatin1String(Designer::Constants::FORM_MIMETYPE), - parent), - m_terminationMapper(0) + parent) { } diff --git a/src/plugins/qmakeprojectmanager/externaleditors.h b/src/plugins/qmakeprojectmanager/externaleditors.h index d5c4e6aefeb..b922dcdce78 100644 --- a/src/plugins/qmakeprojectmanager/externaleditors.h +++ b/src/plugins/qmakeprojectmanager/externaleditors.h @@ -139,7 +139,7 @@ private: typedef QMap ProcessCache; ProcessCache m_processCache; - QSignalMapper *m_terminationMapper; + QSignalMapper *m_terminationMapper = nullptr; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp index 3dfb8fd040b..286745f94c4 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp @@ -54,19 +54,7 @@ LibraryDetailsController::LibraryDetailsController( Ui::LibraryDetailsWidget *libraryDetails, const QString &proFile, QObject *parent) : QObject(parent), - m_platforms(AddLibraryWizard::LinuxPlatform - | AddLibraryWizard::MacPlatform - | AddLibraryWizard::WindowsMinGWPlatform - | AddLibraryWizard::WindowsMSVCPlatform), - m_linkageType(AddLibraryWizard::NoLinkage), - m_macLibraryType(AddLibraryWizard::NoLibraryType), m_proFile(proFile), - m_ignoreGuiSignals(false), - m_includePathChanged(false), - m_linkageRadiosVisible(true), - m_macLibraryRadiosVisible(true), - m_includePathVisible(true), - m_windowsGroupVisible(true), m_libraryDetailsWidget(libraryDetails) { switch (Utils::HostOsInfo::hostOs()) { diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.h b/src/plugins/qmakeprojectmanager/librarydetailscontroller.h index af99a145110..41a6591bf00 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.h +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.h @@ -104,21 +104,24 @@ private: void showLinkageType(AddLibraryWizard::LinkageType linkageType); void showMacLibraryType(AddLibraryWizard::MacLibraryType libType); - AddLibraryWizard::Platforms m_platforms; - AddLibraryWizard::LinkageType m_linkageType; - AddLibraryWizard::MacLibraryType m_macLibraryType; + AddLibraryWizard::Platforms m_platforms = AddLibraryWizard::LinuxPlatform + | AddLibraryWizard::MacPlatform + | AddLibraryWizard::WindowsMinGWPlatform + | AddLibraryWizard::WindowsMSVCPlatform; + AddLibraryWizard::LinkageType m_linkageType = AddLibraryWizard::NoLinkage; + AddLibraryWizard::MacLibraryType m_macLibraryType = AddLibraryWizard::NoLibraryType; QString m_proFile; CreatorPlatform m_creatorPlatform; - bool m_ignoreGuiSignals; - bool m_includePathChanged; + bool m_ignoreGuiSignals = false; + bool m_includePathChanged = false; - bool m_linkageRadiosVisible; - bool m_macLibraryRadiosVisible; - bool m_includePathVisible; - bool m_windowsGroupVisible; + bool m_linkageRadiosVisible = true; + bool m_macLibraryRadiosVisible = true; + bool m_includePathVisible = true; + bool m_windowsGroupVisible = true; Ui::LibraryDetailsWidget *m_libraryDetailsWidget; }; diff --git a/src/plugins/qmakeprojectmanager/makefileparse.h b/src/plugins/qmakeprojectmanager/makefileparse.h index a5690929aa7..a7da0746fb7 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.h +++ b/src/plugins/qmakeprojectmanager/makefileparse.h @@ -75,16 +75,10 @@ private: class QmakeBuildConfig { public: - QmakeBuildConfig() - : explicitDebug(false), - explicitRelease(false), - explicitBuildAll(false), - explicitNoBuildAll(false) - {} - bool explicitDebug; - bool explicitRelease; - bool explicitBuildAll; - bool explicitNoBuildAll; + bool explicitDebug = false; + bool explicitRelease = false; + bool explicitBuildAll = false; + bool explicitNoBuildAll = false; }; MakefileState m_state; diff --git a/src/plugins/qmakeprojectmanager/makestep.cpp b/src/plugins/qmakeprojectmanager/makestep.cpp index cd64af84f83..b6991cf1bf3 100644 --- a/src/plugins/qmakeprojectmanager/makestep.cpp +++ b/src/plugins/qmakeprojectmanager/makestep.cpp @@ -63,8 +63,7 @@ const char CLEAN_KEY[] = "Qt4ProjectManager.MakeStep.Clean"; } MakeStep::MakeStep(BuildStepList *bsl) : - AbstractProcessStep(bsl, Core::Id(MAKESTEP_BS_ID)), - m_clean(false) + AbstractProcessStep(bsl, Core::Id(MAKESTEP_BS_ID)) { ctor(); } @@ -79,8 +78,7 @@ MakeStep::MakeStep(BuildStepList *bsl, MakeStep *bs) : } MakeStep::MakeStep(BuildStepList *bsl, Core::Id id) : - AbstractProcessStep(bsl, id), - m_clean(false) + AbstractProcessStep(bsl, id) { ctor(); } @@ -314,7 +312,7 @@ void MakeStep::setUserArguments(const QString &arguments) } MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) - : BuildStepConfigWidget(), m_ui(new Internal::Ui::MakeStep), m_makeStep(makeStep), m_bc(0), m_ignoreChange(false) + : BuildStepConfigWidget(), m_ui(new Internal::Ui::MakeStep), m_makeStep(makeStep) { m_ui->setupUi(this); diff --git a/src/plugins/qmakeprojectmanager/makestep.h b/src/plugins/qmakeprojectmanager/makestep.h index a334ff4f62f..7586d989f92 100644 --- a/src/plugins/qmakeprojectmanager/makestep.h +++ b/src/plugins/qmakeprojectmanager/makestep.h @@ -109,8 +109,8 @@ private: void ctor(); void setMakeCommand(const QString &make); QStringList automaticallyAddedArguments() const; - bool m_clean; - bool m_scriptTarget; + bool m_clean = false; + bool m_scriptTarget = false; QString m_makeFileToCheck; QString m_userArgs; QString m_makeCmd; @@ -136,11 +136,11 @@ private slots: private: void setSummaryText(const QString &text); - Internal::Ui::MakeStep *m_ui; - MakeStep *m_makeStep; + Internal::Ui::MakeStep *m_ui = nullptr; + MakeStep *m_makeStep = nullptr; QString m_summaryText; - ProjectExplorer::BuildConfiguration *m_bc; - bool m_ignoreChange; + ProjectExplorer::BuildConfiguration *m_bc = nullptr; + bool m_ignoreChange = false; }; } // QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp b/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp index 36407376d4f..297043116fe 100644 --- a/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp +++ b/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp @@ -317,9 +317,6 @@ static const char *const functionKeywords[] = { // ------------------------------- // ProFileCompletionAssistProvider // ------------------------------- -ProFileCompletionAssistProvider::ProFileCompletionAssistProvider() -{} - void ProFileCompletionAssistProvider::init() { for (uint i = 0; i < sizeof variableKeywords / sizeof variableKeywords[0] - 1; i++) diff --git a/src/plugins/qmakeprojectmanager/profilecompletionassist.h b/src/plugins/qmakeprojectmanager/profilecompletionassist.h index 2ef25165a73..8ea39767666 100644 --- a/src/plugins/qmakeprojectmanager/profilecompletionassist.h +++ b/src/plugins/qmakeprojectmanager/profilecompletionassist.h @@ -43,7 +43,6 @@ class ProFileCompletionAssistProvider : public TextEditor::CompletionAssistProvi Q_OBJECT public: - ProFileCompletionAssistProvider(); void init(); ~ProFileCompletionAssistProvider(); diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp index e57ef27cc67..41a0d303bb3 100644 --- a/src/plugins/qmakeprojectmanager/profileeditor.cpp +++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp @@ -58,11 +58,6 @@ namespace Internal { class ProFileEditorWidget : public TextEditorWidget { -public: - ProFileEditorWidget() - { - } - protected: virtual Link findLinkAt(const QTextCursor &, bool resolveTarget = true, bool inNextSplit = false) override; diff --git a/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp b/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp index 7f094f64a0e..bf4904e1239 100644 --- a/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp +++ b/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp @@ -45,7 +45,7 @@ namespace QmakeProjectManager { namespace Internal { ProFileHoverHandler::ProFileHoverHandler(const TextEditor::Keywords &keywords) - : m_manualKind(UnknownManual), m_keywords(keywords) + : m_keywords(keywords) { } @@ -61,7 +61,7 @@ void ProFileHoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidg identifyQMakeKeyword(block.text(), pos - block.position()); if (m_manualKind != UnknownManual) { - QUrl url(QString::fromLatin1("qthelp://com.trolltech.qmake/qdoc/qmake-%1-reference.html#%2") + QUrl url(QString::fromLatin1("qthelp://org.qt-project.qmake/qmake/qmake-%1-reference.html#%2") .arg(manualName()).arg(m_docFragment)); setLastHelpItemIdentified(TextEditor::HelpItem(url.toString(), m_docFragment, TextEditor::HelpItem::QMakeVariableOfFunction)); @@ -134,7 +134,7 @@ void ProFileHoverHandler::identifyDocFragment(ProFileHoverHandler::ManualKind ma m_docFragment.replace(QLatin1Char('_'), QLatin1Char('-')); if (m_manualKind == FunctionManual) { - QUrl url(QString::fromLatin1("qthelp://com.trolltech.qmake/qdoc/qmake-%1-reference.html").arg(manualName())); + QUrl url(QString::fromLatin1("qthelp://org.qt-project.qmake/qmake/qmake-%1-reference.html").arg(manualName())); const QByteArray html = Core::HelpManager::fileData(url); Utils::HtmlDocExtractor htmlExtractor; diff --git a/src/plugins/qmakeprojectmanager/profilehoverhandler.h b/src/plugins/qmakeprojectmanager/profilehoverhandler.h index 9b13c3c490b..1271c2931a7 100644 --- a/src/plugins/qmakeprojectmanager/profilehoverhandler.h +++ b/src/plugins/qmakeprojectmanager/profilehoverhandler.h @@ -66,7 +66,7 @@ private: const QString &keyword); QString m_docFragment; - ManualKind m_manualKind; + ManualKind m_manualKind = UnknownManual; const TextEditor::Keywords m_keywords; }; diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 92af58f4ace..f9a76f9c1cb 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -106,12 +106,7 @@ QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target) } QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id) : - BuildConfiguration(target, id), - m_shadowBuild(true), - m_isEnabled(false), - m_qmakeBuildConfiguration(0), - m_subNodeBuild(0), - m_fileNodeBuild(0) + BuildConfiguration(target, id) { ctor(); } @@ -119,10 +114,7 @@ QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id) : QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, QmakeBuildConfiguration *source) : BuildConfiguration(target, source), m_shadowBuild(source->m_shadowBuild), - m_isEnabled(false), - m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration), - m_subNodeBuild(0), // temporary value, so not copied - m_fileNodeBuild(0) + m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration) { cloneSteps(source); ctor(); diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h index f47c5514512..ee9582273d5 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h @@ -144,11 +144,11 @@ private: }; LastKitState m_lastKitState; - bool m_shadowBuild; - bool m_isEnabled; - QtSupport::BaseQtVersion::QmakeBuildConfigs m_qmakeBuildConfiguration; - QmakeProjectManager::QmakeProFileNode *m_subNodeBuild; - ProjectExplorer::FileNode *m_fileNodeBuild; + bool m_shadowBuild = true; + bool m_isEnabled = false; + QtSupport::BaseQtVersion::QmakeBuildConfigs m_qmakeBuildConfiguration = 0; + QmakeProjectManager::QmakeProFileNode *m_subNodeBuild = nullptr; + ProjectExplorer::FileNode *m_fileNodeBuild = nullptr; friend class Internal::QmakeProjectConfigWidget; friend class QmakeBuildConfigurationFactory; diff --git a/src/plugins/qmakeprojectmanager/qmakebuildinfo.h b/src/plugins/qmakeprojectmanager/qmakebuildinfo.h index 87f8fe17ce3..fd5debe8feb 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildinfo.h +++ b/src/plugins/qmakeprojectmanager/qmakebuildinfo.h @@ -46,7 +46,7 @@ class QmakeBuildInfo : public ProjectExplorer::BuildInfo public: QmakeBuildInfo(const QmakeBuildConfigurationFactory *f) : ProjectExplorer::BuildInfo(f) { } - ProjectExplorer::BuildConfiguration::BuildType type; + ProjectExplorer::BuildConfiguration::BuildType type = ProjectExplorer::BuildConfiguration::Unknown; QString additionalArguments; QString makefile; QMakeStepConfig config; diff --git a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp index 1f4001d9b42..9db367b6605 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp +++ b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp @@ -41,8 +41,7 @@ namespace Internal { QmakeKitConfigWidget::QmakeKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki) : ProjectExplorer::KitConfigWidget(k, ki), - m_lineEdit(new QLineEdit), - m_ignoreChange(false) + m_lineEdit(new QLineEdit) { refresh(); // set up everything according to kit m_lineEdit->setToolTip(toolTip()); diff --git a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h index 7f2cfcb4c02..bc2a255a14e 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h +++ b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h @@ -61,8 +61,8 @@ private slots: private: int findQtVersion(const int id) const; - QLineEdit *m_lineEdit; - bool m_ignoreChange; + QLineEdit *m_lineEdit = nullptr; + bool m_ignoreChange = false; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 7de13272d18..3a0511c73e1 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -306,8 +306,7 @@ QmakePriFileNode::QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmak m_project(project), m_qmakeProFileNode(qmakeProFileNode), m_projectFilePath(filePath), - m_projectDir(filePath.toFileInfo().absolutePath()), - m_includedInExactParse(true) + m_projectDir(filePath.toFileInfo().absolutePath()) { Q_ASSERT(project); m_qmakePriFile = new QmakePriFile(this); @@ -335,19 +334,13 @@ struct InternalNode QList virtualfolders; QMap subnodes; FileNameList files; - FileType type; - int priority; + FileType type = UnknownFileType; + int priority = 0; QString displayName; QString typeName; QString fullPath; QIcon icon; - InternalNode() - { - type = UnknownFileType; - priority = 0; - } - ~InternalNode() { qDeleteAll(virtualfolders); @@ -1597,12 +1590,7 @@ bool QmakeProFileNode::isDeployable() const */ QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FileName &filePath) - : QmakePriFileNode(project, this, filePath), - m_validParse(false), - m_parseInProgress(true), - m_projectType(InvalidProject), - m_readerExact(0), - m_readerCumulative(0) + : QmakePriFileNode(project, this, filePath) { // The slot is a lambda, so that QmakeProFileNode does not need to be // a qobject. The lifetime of the m_parserFutureWatcher is shorter diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index 149b3806d56..e6a6a02b279 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -219,7 +219,7 @@ private: QMap > m_files; QSet m_recursiveEnumerateFiles; QSet m_watchedFolders; - bool m_includedInExactParse; + bool m_includedInExactParse = true; // managed by QmakeProFileNode friend class QmakeProjectManager::QmakeProFileNode; @@ -277,7 +277,7 @@ private: class QMAKEPROJECTMANAGER_EXPORT TargetInformation { public: - bool valid; + bool valid = false; QString target; QString destDir; QString buildDir; @@ -295,19 +295,9 @@ public: return !(*this == other); } - TargetInformation() - : valid(false) - {} - - TargetInformation(const TargetInformation &other) - : valid(other.valid), - target(other.target), - destDir(other.destDir), - buildDir(other.buildDir), - buildTarget(other.buildTarget) - { - } + TargetInformation() = default; + TargetInformation(const TargetInformation &other) = default; }; struct QMAKEPROJECTMANAGER_EXPORT InstallsItem { @@ -322,12 +312,6 @@ struct QMAKEPROJECTMANAGER_EXPORT InstallsList { QList items; }; -struct QMAKEPROJECTMANAGER_EXPORT ProjectVersion { - int major; - int minor; - int patch; -}; - // Implements ProjectNode for qmake .pro files class QMAKEPROJECTMANAGER_EXPORT QmakeProFileNode : public QmakePriFileNode { @@ -413,12 +397,12 @@ private: static TargetInformation targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const QString &buildDir, const QString &projectFilePath); static InstallsList installsList(const QtSupport::ProFileReader *reader, const QString &projectFilePath, const QString &projectDir); - bool m_isDeployable; + bool m_isDeployable = false; - bool m_validParse; - bool m_parseInProgress; + bool m_validParse = false; + bool m_parseInProgress = true; - QmakeProjectType m_projectType; + QmakeProjectType m_projectType = InvalidProject; QmakeVariablesHash m_varValues; QMap m_uitimestamps; @@ -430,8 +414,8 @@ private: // Async stuff QFutureWatcher m_parseFutureWatcher; - QtSupport::ProFileReader *m_readerExact; - QtSupport::ProFileReader *m_readerCumulative; + QtSupport::ProFileReader *m_readerExact = nullptr; + QtSupport::ProFileReader *m_readerCumulative = nullptr; }; } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 41f7afdbf3a..9d54d2eafdd 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -311,18 +311,9 @@ bool QmakeProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType QmakeProject::QmakeProject(QmakeManager *manager, const QString &fileName) : m_manager(manager), - m_rootProjectNode(0), m_fileInfo(new QmakeProjectFile(fileName, this)), m_projectFiles(new QmakeProjectFiles), - m_qmakeVfs(new QMakeVfs), - m_qmakeGlobals(0), - m_qmakeGlobalsRefCnt(0), - m_asyncUpdateFutureInterface(0), - m_pendingEvaluateFuturesCount(0), - m_asyncUpdateState(Base), - m_cancelEvaluate(false), - m_centralizedFolderWatcher(0), - m_activeTarget(0) + m_qmakeVfs(new QMakeVfs) { setId(Constants::QMAKEPROJECT_ID); setProjectContext(Core::Context(QmakeProjectManager::Constants::PROJECT_ID)); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index ccedabd2425..6d6b85d03d4 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -185,35 +185,35 @@ private: bool matchesKit(const ProjectExplorer::Kit *kit); QmakeManager *m_manager; - QmakeProFileNode *m_rootProjectNode; + QmakeProFileNode *m_rootProjectNode = 0; - Internal::QmakeProjectFile *m_fileInfo; + Internal::QmakeProjectFile *m_fileInfo = nullptr; // Current configuration QString m_oldQtIncludePath; QString m_oldQtLibsPath; // cached lists of all of files - Internal::QmakeProjectFiles *m_projectFiles; + Internal::QmakeProjectFiles *m_projectFiles = nullptr; - QMakeVfs *m_qmakeVfs; + QMakeVfs *m_qmakeVfs = nullptr; // cached data during project rescan - ProFileGlobals *m_qmakeGlobals; - int m_qmakeGlobalsRefCnt; + ProFileGlobals *m_qmakeGlobals = nullptr; + int m_qmakeGlobalsRefCnt = 0; QTimer m_asyncUpdateTimer; - QFutureInterface *m_asyncUpdateFutureInterface; - int m_pendingEvaluateFuturesCount; - AsyncUpdateState m_asyncUpdateState; - bool m_cancelEvaluate; + QFutureInterface *m_asyncUpdateFutureInterface = nullptr; + int m_pendingEvaluateFuturesCount = 0; + AsyncUpdateState m_asyncUpdateState = Base; + bool m_cancelEvaluate = false; QList m_partialEvaluate; QFuture m_codeModelFuture; - Internal::CentralizedFolderWatcher *m_centralizedFolderWatcher; + Internal::CentralizedFolderWatcher *m_centralizedFolderWatcher = nullptr; - ProjectExplorer::Target *m_activeTarget; + ProjectExplorer::Target *m_activeTarget = nullptr; friend class Internal::QmakeProjectFile; friend class Internal::QmakeProjectConfigWidget; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp index 5f01755cf76..358dcae5fb3 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp @@ -47,8 +47,7 @@ using namespace ProjectExplorer; QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc) : NamedWidget(), - m_buildConfiguration(bc), - m_ignoreChange(false) + m_buildConfiguration(bc) { m_defaultShadowBuildDir = QmakeBuildConfiguration::shadowBuildDirectory(bc->target()->project()->projectFilePath().toString(), diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h index 951f49f05a9..09d15a48466 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h @@ -73,7 +73,7 @@ private: QmakeBuildConfiguration *m_buildConfiguration; Utils::DetailsWidget *m_detailsContainer; QString m_defaultShadowBuildDir; - bool m_ignoreChange; + bool m_ignoreChange = false; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp index d8614bf7c8c..c6a2cee5b7a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp @@ -58,13 +58,6 @@ using namespace TextEditor; namespace QmakeProjectManager { -QmakeManager::QmakeManager() - : m_contextNode(0), - m_contextProject(0), - m_contextFile(0) -{ -} - QmakeManager::~QmakeManager() { } diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h index e09aab99254..c098c737cda 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h @@ -54,7 +54,6 @@ class QMAKEPROJECTMANAGER_EXPORT QmakeManager : public ProjectExplorer::IProject Q_OBJECT public: - QmakeManager(); ~QmakeManager(); void registerProject(QmakeProject *project); @@ -95,9 +94,9 @@ private: void addLibrary(const QString &fileName, TextEditor::BaseTextEditor *editor = 0); void runQMake(ProjectExplorer::Project *p, ProjectExplorer::Node *node); - ProjectExplorer::Node *m_contextNode; - ProjectExplorer::Project *m_contextProject; - ProjectExplorer::FileNode *m_contextFile; + ProjectExplorer::Node *m_contextNode = nullptr; + ProjectExplorer::Project *m_contextProject = nullptr; + ProjectExplorer::FileNode *m_contextFile = nullptr; }; } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp index 8e5789b12f6..318eb172f6a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp @@ -76,12 +76,6 @@ using namespace QmakeProjectManager::Internal; using namespace QmakeProjectManager; using namespace ProjectExplorer; -QmakeProjectManagerPlugin::QmakeProjectManagerPlugin() - : m_qmakeProjectManager(0), m_previousStartupProject(0), m_previousTarget(0) -{ - -} - QmakeProjectManagerPlugin::~QmakeProjectManagerPlugin() { } diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h index a052e462855..2d673a9af72 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h @@ -59,7 +59,6 @@ class QmakeProjectManagerPlugin : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QmakeProjectManager.json") public: - QmakeProjectManagerPlugin(); ~QmakeProjectManagerPlugin(); bool initialize(const QStringList &arguments, QString *errorMessage); void extensionsInitialized(); @@ -78,23 +77,23 @@ private slots: #endif private: - QmakeManager *m_qmakeProjectManager; - QmakeProject *m_previousStartupProject; - ProjectExplorer::Target *m_previousTarget; + QmakeManager *m_qmakeProjectManager = nullptr; + QmakeProject *m_previousStartupProject = nullptr; + ProjectExplorer::Target *m_previousTarget = nullptr; - QAction *m_runQMakeAction; - QAction *m_runQMakeActionContextMenu; - Utils::ParameterAction *m_buildSubProjectContextMenu; - QAction *m_subProjectRebuildSeparator; - QAction *m_rebuildSubProjectContextMenu; - QAction *m_cleanSubProjectContextMenu; - QAction *m_buildFileContextMenu; - Utils::ParameterAction *m_buildSubProjectAction; - Utils::ParameterAction *m_rebuildSubProjectAction; - Utils::ParameterAction *m_cleanSubProjectAction; - Utils::ParameterAction *m_buildFileAction; - QAction *m_addLibraryAction; - QAction *m_addLibraryActionContextMenu; + QAction *m_runQMakeAction = nullptr; + QAction *m_runQMakeActionContextMenu = nullptr; + Utils::ParameterAction *m_buildSubProjectContextMenu = nullptr; + QAction *m_subProjectRebuildSeparator = nullptr; + QAction *m_rebuildSubProjectContextMenu = nullptr; + QAction *m_cleanSubProjectContextMenu = nullptr; + QAction *m_buildFileContextMenu = nullptr; + Utils::ParameterAction *m_buildSubProjectAction = nullptr; + Utils::ParameterAction *m_rebuildSubProjectAction = nullptr; + Utils::ParameterAction *m_cleanSubProjectAction = nullptr; + Utils::ParameterAction *m_buildFileAction = nullptr; + QAction *m_addLibraryAction = nullptr; + QAction *m_addLibraryActionContextMenu = nullptr; Core::Context m_projectContext; }; diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 0f69f809c97..3945e9a2e51 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -75,22 +75,13 @@ const char QMAKE_QMLDEBUGLIB_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDeb } QMakeStep::QMakeStep(BuildStepList *bsl) : - AbstractProcessStep(bsl, Core::Id(QMAKE_BS_ID)), - m_forced(false), - m_needToRunQMake(false), - m_linkQmlDebuggingLibrary(DebugLink), - m_useQtQuickCompiler(false), - m_separateDebugInfo(false) + AbstractProcessStep(bsl, Core::Id(QMAKE_BS_ID)) { ctor(); } QMakeStep::QMakeStep(BuildStepList *bsl, Core::Id id) : - AbstractProcessStep(bsl, id), - m_forced(false), - m_linkQmlDebuggingLibrary(DebugLink), - m_useQtQuickCompiler(false), - m_separateDebugInfo(false) + AbstractProcessStep(bsl, id) { ctor(); } @@ -457,8 +448,7 @@ bool QMakeStep::fromMap(const QVariantMap &map) //// QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step) - : BuildStepConfigWidget(), m_ui(new Internal::Ui::QMakeStep), m_step(step), - m_ignoreChange(false) + : BuildStepConfigWidget(), m_ui(new Internal::Ui::QMakeStep), m_step(step) { m_ui->setupUi(this); diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h index 0f3fb7be4ba..1b799be6a53 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -91,25 +91,15 @@ public: static TargetArchConfig targetArchFor(const ProjectExplorer::Abi &targetAbi, const QtSupport::BaseQtVersion *version); static OsType osTypeFor(const ProjectExplorer::Abi &targetAbi, const QtSupport::BaseQtVersion *version); - - QMakeStepConfig() - : archConfig(NoArch), - osType(NoOsType), - linkQmlDebuggingQQ1(false), - linkQmlDebuggingQQ2(false), - useQtQuickCompiler(false), - separateDebugInfo(false) - {} - QStringList toArguments() const; // Actual data - TargetArchConfig archConfig; - OsType osType; - bool linkQmlDebuggingQQ1; - bool linkQmlDebuggingQQ2; - bool useQtQuickCompiler; - bool separateDebugInfo; + TargetArchConfig archConfig = NoArch; + OsType osType = NoOsType; + bool linkQmlDebuggingQQ1 = false; + bool linkQmlDebuggingQQ2 = false; + bool useQtQuickCompiler = false; + bool separateDebugInfo = false; }; @@ -192,13 +182,13 @@ private: void ctor(); // last values - bool m_forced; - bool m_needToRunQMake; // set in init(), read in run() + bool m_forced = false; + bool m_needToRunQMake = false; // set in init(), read in run() QString m_userArgs; - QmlLibraryLink m_linkQmlDebuggingLibrary; - bool m_useQtQuickCompiler; - bool m_scriptTemplate; - bool m_separateDebugInfo; + QmlLibraryLink m_linkQmlDebuggingLibrary = DebugLink; + bool m_useQtQuickCompiler = false; + bool m_scriptTemplate = false; + bool m_separateDebugInfo = false; }; @@ -239,11 +229,11 @@ private: void setSummaryText(const QString &); - Internal::Ui::QMakeStep *m_ui; - QMakeStep *m_step; + Internal::Ui::QMakeStep *m_ui = nullptr; + QMakeStep *m_step = nullptr; QString m_summaryText; QString m_additionalSummaryText; - bool m_ignoreChange; + bool m_ignoreChange = false; }; } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp index f0092950ad6..b0921cc9e1f 100644 --- a/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp @@ -83,7 +83,7 @@ GuiAppWizard::GuiAppWizard() "Includes a Qt Designer-based main window.\n\n" "Preselects a desktop Qt for building the application if available.")); setIcon(QIcon(QLatin1String(":/wizards/images/gui.png"))); - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QWIDGETS)); + setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QWIDGETS)); } Core::BaseFileWizard *GuiAppWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp b/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp index 3e10554ba59..f509bdd8775 100644 --- a/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp @@ -56,7 +56,7 @@ LibraryWizard::LibraryWizard() "
  • a shared C++ library for use with QPluginLoader and runtime (Plugins)
  • " "
  • a shared or static C++ library for use with another project at linktime
  • ")); setIcon(QIcon(QLatin1String(":/wizards/images/lib.png"))); - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QT)); + setRequiredFeatures(Core::FeatureSet(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_PREFIX))); } Core::BaseFileWizard *LibraryWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp index 07c46b2d0dd..3741e3c10cf 100644 --- a/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp @@ -51,7 +51,7 @@ SubdirsProjectWizard::SubdirsProjectWizard() setDescription(tr("Creates a qmake-based subdirs project. This allows you to group " "your projects in a tree structure.")); setIcon(QIcon(QLatin1String(":/wizards/images/gui.png"))); - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QT)); + setRequiredFeatures(Core::FeatureSet(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_PREFIX))); } Core::BaseFileWizard *SubdirsProjectWizard::create(QWidget *parent, diff --git a/src/plugins/qmakeprojectmanager/wizards/testwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/testwizard.cpp index 579f7f98caf..7aa03dc2621 100644 --- a/src/plugins/qmakeprojectmanager/wizards/testwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/testwizard.cpp @@ -57,7 +57,7 @@ TestWizard::TestWizard() "and that there are no regressions.")); setIcon(QIcon(QLatin1String(":/wizards/images/console.png"))); setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QT_CONSOLE) | - Core::Feature(QtSupport::Constants::FEATURE_QT)); + Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_PREFIX)); } Core::BaseFileWizard *TestWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 4ce998fc454..eee38122bd1 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -68,7 +68,7 @@ static inline QStringList supportedVersionsList() QStringList list; list << QStringLiteral("2.0") << QStringLiteral("2.1") << QStringLiteral("2.2") << QStringLiteral("2.3") - << QStringLiteral("2.4"); + << QStringLiteral("2.4") << QStringLiteral("2.5"); return list; } diff --git a/src/plugins/qmljstools/qmljsbundleprovider.cpp b/src/plugins/qmljstools/qmljsbundleprovider.cpp index 760004caf77..78a7f78aef0 100644 --- a/src/plugins/qmljstools/qmljsbundleprovider.cpp +++ b/src/plugins/qmljstools/qmljsbundleprovider.cpp @@ -131,9 +131,7 @@ void BasicBundleProvider::mergeBundlesForKit(ProjectExplorer::Kit *kit QString qtQmlPath = qtVersion->qmakeProperty("QT_INSTALL_QML"); Core::FeatureSet features = qtVersion->availableFeatures(); - if (features.contains(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK)) - || features.contains(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK_1)) - || features.contains(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK_1_1))) { + if (features.contains(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_QUICK_PREFIX))) { myReplacements.insert(QLatin1String("$(CURRENT_DIRECTORY)"), qtImportsPath); QDir qtQuick1Bundles(qtImportsPath); qtQuick1Bundles.setNameFilters(QStringList(QLatin1String("*-bundle.json"))); @@ -158,7 +156,7 @@ void BasicBundleProvider::mergeBundlesForKit(ProjectExplorer::Kit *kit bundles.mergeBundleForLanguage(Dialect::Qml, qtQuick1Bundle); bundles.mergeBundleForLanguage(Dialect::QmlQtQuick1, qtQuick1Bundle); } - if (features.contains(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK_2))) { + if (features.contains(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_QUICK_PREFIX, 2))) { myReplacements.insert(QLatin1String("$(CURRENT_DIRECTORY)"), qtQmlPath); QDir qtQuick2Bundles(qtQmlPath); qtQuick2Bundles.setNameFilters(QStringList(QLatin1String("*-bundle.json"))); diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp index 283e1f3b836..adb1db87dc1 100644 --- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp @@ -71,7 +71,7 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS action->setWidgetCreator(widgetCreator); action->setRunControlCreator(runControlCreator); action->setToolPreparer([tool] { return tool->prepareTool(); }); - action->setRunMode(ProjectExplorer::QmlProfilerRunMode); + action->setRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); action->setText(tr("QML Profiler")); action->setToolTip(description); action->setMenuGroup(Constants::G_ANALYZER_TOOLS); @@ -84,7 +84,7 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS action->setRunControlCreator(runControlCreator); action->setCustomToolStarter([tool] { tool->startRemoteTool(); }); action->setToolPreparer([tool] { return tool->prepareTool(); }); - action->setRunMode(ProjectExplorer::QmlProfilerRunMode); + action->setRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); action->setText(tr("QML Profiler (External)")); action->setToolTip(description); action->setMenuGroup(Constants::G_ANALYZER_REMOTE_TOOLS); diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp index a5ea4fa0032..6fc364d347f 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -57,9 +57,9 @@ QmlProfilerRunControlFactory::QmlProfilerRunControlFactory(QObject *parent) : { } -bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - return mode == QmlProfilerRunMode + return mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE && (qobject_cast(runConfiguration)); } @@ -83,7 +83,7 @@ static AnalyzerStartParameters createQmlProfilerStartParameters(RunConfiguration return sp; } -RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { QTC_ASSERT(canRun(runConfiguration, mode), return 0); diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h index f5513c98cae..269895b36cd 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h @@ -45,10 +45,10 @@ public: explicit QmlProfilerRunControlFactory(QObject *parent = 0); // IRunControlFactory implementation - bool canRun(RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const; ProjectExplorer::RunControl *create(RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); }; diff --git a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp index a6c8e47e322..05dc7503b03 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp @@ -224,12 +224,6 @@ void QmlProfilerStateWidget::updateDisplay() return; } - // View is not supported for this kind of application - if (d->traceAvailable && d->loadingDone && !parentWidget()->isEnabled()) { - showText(tr("Not supported for this application")); - return; - } - // Application died before all data could be read if (!d->loadingDone && !d->emptyList && d->appKilled) { showText(tr("Application stopped before loading all data"), true); diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 766faf0ed97..82d08e9d75e 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -469,7 +469,7 @@ void QmlProfilerTool::startRemoteTool() sp.analyzerPort = port; AnalyzerRunControl *rc = createRunControl(sp, 0); - ProjectExplorerPlugin::startRunControl(rc, QmlProfilerRunMode); + ProjectExplorerPlugin::startRunControl(rc, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); } void QmlProfilerTool::logState(const QString &msg) @@ -524,7 +524,7 @@ void QmlProfilerTool::showLoadDialog() if (ModeManager::currentMode()->id() != MODE_ANALYZE) AnalyzerManager::showMode(); - AnalyzerManager::selectTool(QmlProfilerRemoteActionId); + AnalyzerManager::selectAction(QmlProfilerRemoteActionId); QString filename = QFileDialog::getOpenFileName(ICore::mainWindow(), tr("Load QML Trace"), QString(), tr("QML traces (*%1)").arg(QLatin1String(TraceFileExtension))); diff --git a/src/plugins/qnx/qnxattachdebugsupport.cpp b/src/plugins/qnx/qnxattachdebugsupport.cpp index 65f62f4e60d..3bb3f271a98 100644 --- a/src/plugins/qnx/qnxattachdebugsupport.cpp +++ b/src/plugins/qnx/qnxattachdebugsupport.cpp @@ -116,15 +116,10 @@ void QnxAttachDebugSupport::attachToProcess() sp.attachPID = m_process.pid; sp.startMode = Debugger::AttachToRemoteServer; sp.closeMode = Debugger::DetachAtClose; - sp.masterEngineType = Debugger::GdbEngineType; sp.connParams.port = m_pdebugPort; sp.remoteChannel = m_device->sshParameters().host + QLatin1Char(':') + QString::number(m_pdebugPort); sp.displayName = tr("Remote: \"%1:%2\" - Process %3").arg(sp.connParams.host).arg(m_pdebugPort).arg(m_process.pid); - sp.debuggerCommand = Debugger::DebuggerKitInformation::debuggerCommand(m_kit).toString(); - sp.projectSourceDirectory = m_projectSourceDirectory; sp.executable = m_localExecutablePath; - if (ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit)) - sp.toolChainAbi = tc->targetAbi(); sp.useCtrlCStub = true; QnxQtVersion *qtVersion = dynamic_cast(QtSupport::QtKitInformation::qtVersion(m_kit)); @@ -132,7 +127,7 @@ void QnxAttachDebugSupport::attachToProcess() sp.solibSearchPath = QnxUtils::searchPaths(qtVersion); QString errorMessage; - Debugger::DebuggerRunControl * const runControl = Debugger::createDebuggerRunControl(sp, &errorMessage); + Debugger::DebuggerRunControl *runControl = Debugger::createDebuggerRunControl(sp, 0, &errorMessage); if (!errorMessage.isEmpty()) { handleError(errorMessage); stopPDebug(); @@ -140,7 +135,7 @@ void QnxAttachDebugSupport::attachToProcess() } connect(runControl, &Debugger::DebuggerRunControl::stateChanged, this, &QnxAttachDebugSupport::handleDebuggerStateChanged); - ProjectExplorer::ProjectExplorerPlugin::startRunControl(runControl, ProjectExplorer::DebugRunMode); + ProjectExplorer::ProjectExplorerPlugin::startRunControl(runControl, ProjectExplorer::Constants::DEBUG_RUN_MODE); } void QnxAttachDebugSupport::handleDebuggerStateChanged(Debugger::DebuggerState state) diff --git a/src/plugins/qnx/qnxruncontrolfactory.cpp b/src/plugins/qnx/qnxruncontrolfactory.cpp index 9a08cc545d6..ee5c37044c1 100644 --- a/src/plugins/qnx/qnxruncontrolfactory.cpp +++ b/src/plugins/qnx/qnxruncontrolfactory.cpp @@ -73,14 +73,7 @@ static DebuggerStartParameters createDebuggerStartParameters(QnxRunConfiguration return params; params.startMode = AttachToRemoteServer; - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(k).toString(); - params.sysRoot = SysRootKitInformation::sysRoot(k).toString(); params.useCtrlCStub = true; - params.runConfiguration = runConfig; - - if (ToolChain *tc = ToolChainKitInformation::toolChain(k)) - params.toolChainAbi = tc->targetAbi(); - params.executable = runConfig->localExecutableFilePath(); params.remoteExecutable = runConfig->remoteExecutableFilePath(); params.remoteChannel = device->sshParameters().host + QLatin1String(":-1"); @@ -89,33 +82,20 @@ static DebuggerStartParameters createDebuggerStartParameters(QnxRunConfiguration params.closeMode = KillAtClose; params.processArgs = runConfig->arguments().join(QLatin1Char(' ')); - DebuggerRunConfigurationAspect *aspect - = runConfig->extraAspect(); + auto aspect = runConfig->extraAspect(); if (aspect->useQmlDebugger()) { - params.languages |= QmlLanguage; params.qmlServerAddress = device->sshParameters().host; params.qmlServerPort = 0; // QML port is handed out later } - if (aspect->useCppDebugger()) - params.languages |= CppLanguage; - - if (const Project *project = runConfig->target()->project()) { - params.projectSourceDirectory = project->projectDirectory().toString(); - if (const BuildConfiguration *buildConfig = runConfig->target()->activeBuildConfiguration()) - params.projectBuildDirectory = buildConfig->buildDirectory().toString(); - params.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - } - - QnxQtVersion *qtVersion = - dynamic_cast(QtSupport::QtKitInformation::qtVersion(k)); + auto qtVersion = dynamic_cast(QtSupport::QtKitInformation::qtVersion(k)); if (qtVersion) params.solibSearchPath = QnxUtils::searchPaths(qtVersion); return params; } -static AnalyzerStartParameters createAnalyzerStartParameters(const QnxRunConfiguration *runConfig, RunMode mode) +static AnalyzerStartParameters createAnalyzerStartParameters(const QnxRunConfiguration *runConfig, Core::Id mode) { AnalyzerStartParameters params; Target *target = runConfig->target(); @@ -145,10 +125,13 @@ QnxRunControlFactory::QnxRunControlFactory(QObject *parent) { } -bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != QmlProfilerRunMode) + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { return false; + } if (!runConfiguration->isEnabled() || !runConfiguration->id().name().startsWith(Constants::QNX_QNX_RUNCONFIGURATION_PREFIX)) { @@ -161,24 +144,24 @@ bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mo if (dev.isNull()) return false; - if (mode == DebugRunMode || mode == QmlProfilerRunMode) + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE || mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) return rc->portsUsedByDebuggers() <= dev->freePorts().count(); return true; } -RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, RunMode mode, QString *errorMessage) +RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *errorMessage) { Q_ASSERT(canRun(runConfig, mode)); QnxRunConfiguration *rc = qobject_cast(runConfig); Q_ASSERT(rc); - switch (mode) { - case NormalRunMode: + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) return new QnxRunControl(rc); - case DebugRunMode: { + + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE) { const DebuggerStartParameters params = createDebuggerStartParameters(rc); - DebuggerRunControl * const runControl = createDebuggerRunControl(params, errorMessage); + DebuggerRunControl *runControl = createDebuggerRunControl(params, runConfig, errorMessage); if (!runControl) return 0; @@ -187,21 +170,15 @@ RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, RunMode mo return runControl; } - case QmlProfilerRunMode: { + + if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { const AnalyzerStartParameters params = createAnalyzerStartParameters(rc, mode); AnalyzerRunControl *runControl = AnalyzerManager::createRunControl(params, runConfig); QnxAnalyzeSupport * const analyzeSupport = new QnxAnalyzeSupport(rc, runControl); connect(runControl, SIGNAL(finished()), analyzeSupport, SLOT(handleProfilingFinished())); return runControl; } - case PerfProfilerRunMode: - case NoRunMode: - case CallgrindRunMode: - case MemcheckRunMode: - case MemcheckWithGdbRunMode: - case ClangStaticAnalyzerMode: - case DebugRunModeWithBreakOnMain: - QTC_ASSERT(false, return 0); - } + + QTC_CHECK(false); return 0; } diff --git a/src/plugins/qnx/qnxruncontrolfactory.h b/src/plugins/qnx/qnxruncontrolfactory.h index afd6e6a585e..f3753f49b85 100644 --- a/src/plugins/qnx/qnxruncontrolfactory.h +++ b/src/plugins/qnx/qnxruncontrolfactory.h @@ -46,9 +46,9 @@ public: explicit QnxRunControlFactory(QObject *parent = 0); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const; + Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, QString *errorMessage); + Core::Id mode, QString *errorMessage); }; } // namespace Internal diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index bca68d01341..b4825cbf679 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -98,15 +98,24 @@ QtVersionNumber::QtVersionNumber() FeatureSet QtVersionNumber::features() const { - FeatureSet result; - result |= Feature(Constants::FEATURE_QT); - if (majorVersion >= 0) { - QString featureMajor = QString::fromLatin1(Constants::FEATURE_QT) + QString::number(majorVersion); - result |= Feature(Id::fromString(featureMajor)); - for (int i = 0; i <= minorVersion; ++i) - result |= Feature(Id::fromString(featureMajor + QLatin1Char('.') + QString::number(i))); - } - return result; + return FeatureSet::versionedFeatures(Constants::FEATURE_QT_PREFIX, majorVersion, minorVersion); +} + +bool QtVersionNumber::matches(int major, int minor, int patch) const +{ + if (major < 0) + return true; + if (major != majorVersion) + return false; + + if (minor < 0) + return true; + if (minor != minorVersion) + return false; + + if (patch < 0) + return true; + return (patch == patchVersion); } bool QtVersionNumber::operator <(const QtVersionNumber &b) const @@ -363,59 +372,62 @@ FeatureSet BaseQtVersion::availableFeatures() const { FeatureSet features = qtVersion().features(); // Qt Version features - features |= (FeatureSet(Constants::FEATURE_QWIDGETS) - | FeatureSet(Constants::FEATURE_QT_WEBKIT) - | FeatureSet(Constants::FEATURE_QT_CONSOLE)); + features |= (Feature(Constants::FEATURE_QWIDGETS) + | Feature(Constants::FEATURE_QT_WEBKIT) + | Feature(Constants::FEATURE_QT_CONSOLE)); if (qtVersion() < QtVersionNumber(4, 7, 0)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_1); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 1, 0); - if (qtVersion() < QtVersionNumber(4, 7, 1)) + if (qtVersion().matches(4, 7, 0)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_1_1); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 1, 1); - if (qtVersion() < QtVersionNumber(5, 0, 0)) + if (qtVersion().matches(4)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_0); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 0); - if (qtVersion() < QtVersionNumber(5, 1, 0)) + if (qtVersion().matches(5, 0)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_1); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1_0); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 1); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 0); - if (qtVersion() < QtVersionNumber(5, 2, 0)) + if (qtVersion().matches(5, 1)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_2); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1_1); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 2); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 1); - if (qtVersion() < QtVersionNumber(5, 3, 0)) + if (qtVersion().matches(5, 2)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_3); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1_2); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 3); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 2); - if (qtVersion() < QtVersionNumber(5, 4, 0)) + if (qtVersion().matches(5, 3)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_4); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1_3); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_UI_FILES); + features |= Feature(Constants::FEATURE_QT_QUICK_UI_FILES); - if (qtVersion() < QtVersionNumber(5, 5, 0)) + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 4); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 3); + + if (qtVersion().matches(5, 4)) return features; - features |= FeatureSet(Constants::FEATURE_QT_3D); - features |= FeatureSet(Constants::FEATURE_QT_CANVAS3D); + features |= Feature(Constants::FEATURE_QT_3D); + features |= Feature(Constants::FEATURE_QT_CANVAS3D); + + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 5); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 4); + + if (qtVersion().matches(5, 5)) + return features; return features; } diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h index 1df47a217ad..57d0aaaf690 100644 --- a/src/plugins/qtsupport/baseqtversion.h +++ b/src/plugins/qtsupport/baseqtversion.h @@ -73,6 +73,9 @@ public: int majorVersion; int minorVersion; int patchVersion; + + bool matches(int major = -1, int minor = -1, int patch = -1) const; + bool operator <(const QtVersionNumber &b) const; bool operator <=(const QtVersionNumber &b) const; bool operator >(const QtVersionNumber &b) const; diff --git a/src/plugins/qtsupport/qtsupportconstants.h b/src/plugins/qtsupport/qtsupportconstants.h index 38e0f0589fa..4df20c25b0c 100644 --- a/src/plugins/qtsupport/qtsupportconstants.h +++ b/src/plugins/qtsupport/qtsupportconstants.h @@ -50,24 +50,11 @@ static const char QTVERSIONID[] = "Id"; static const char QTVERSIONNAME[] = "Name"; //Qt Features -const char FEATURE_QT[] = "QtSupport.Wizards.FeatureQt"; +const char FEATURE_QT_PREFIX[] = "QtSupport.Wizards.FeatureQt"; const char FEATURE_QWIDGETS[] = "QtSupport.Wizards.FeatureQWidgets"; -const char FEATURE_QT_QUICK[] = "QtSupport.Wizards.FeatureQtQuick"; +const char FEATURE_QT_QUICK_PREFIX[] = "QtSupport.Wizards.FeatureQtQuick"; const char FEATURE_QMLPROJECT[] = "QtSupport.Wizards.FeatureQtQuickProject"; -const char FEATURE_QT_QUICK_1[] = "QtSupport.Wizards.FeatureQtQuick.1"; -const char FEATURE_QT_QUICK_1_1[] = "QtSupport.Wizards.FeatureQtQuick.1.1"; -const char FEATURE_QT_QUICK_2[] = "QtSupport.Wizards.FeatureQtQuick.2"; -const char FEATURE_QT_QUICK_2_0[] = "QtSupport.Wizards.FeatureQtQuick.2.0"; -const char FEATURE_QT_QUICK_2_1[] = "QtSupport.Wizards.FeatureQtQuick.2.1"; -const char FEATURE_QT_QUICK_2_2[] = "QtSupport.Wizards.FeatureQtQuick.2.2"; -const char FEATURE_QT_QUICK_2_3[] = "QtSupport.Wizards.FeatureQtQuick.2.3"; -const char FEATURE_QT_QUICK_2_4[] = "QtSupport.Wizards.FeatureQtQuick.2.4"; -const char FEATURE_QT_QUICK_CONTROLS[] = "QtSupport.Wizards.FeatureQtQuick.Controls"; -const char FEATURE_QT_QUICK_CONTROLS_1[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1"; -const char FEATURE_QT_QUICK_CONTROLS_1_0[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1.0"; -const char FEATURE_QT_QUICK_CONTROLS_1_1[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1.1"; -const char FEATURE_QT_QUICK_CONTROLS_1_2[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1.2"; -const char FEATURE_QT_QUICK_CONTROLS_1_3[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1.3"; +const char FEATURE_QT_QUICK_CONTROLS_PREFIX[] = "QtSupport.Wizards.FeatureQtQuick.Controls"; const char FEATURE_QT_QUICK_UI_FILES[] = "QtSupport.Wizards.FeatureQtQuick.UiFiles"; const char FEATURE_QT_WEBKIT[] = "QtSupport.Wizards.FeatureQtWebkit"; const char FEATURE_QT_3D[] = "QtSupport.Wizards.FeatureQt3d"; diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp index ea2020e15e6..a7316280e94 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp @@ -56,9 +56,9 @@ namespace Internal { class RemoteLinuxAnalyzeSupportPrivate { public: - RemoteLinuxAnalyzeSupportPrivate(AnalyzerRunControl *rc, RunMode runMode) + RemoteLinuxAnalyzeSupportPrivate(AnalyzerRunControl *rc, Core::Id runMode) : runControl(rc), - qmlProfiling(runMode == QmlProfilerRunMode), + qmlProfiling(runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE), qmlPort(-1) { } @@ -75,7 +75,7 @@ public: using namespace Internal; AnalyzerStartParameters RemoteLinuxAnalyzeSupport::startParameters(const RunConfiguration *runConfig, - RunMode runMode) + Core::Id runMode) { AnalyzerStartParameters params; params.runMode = runMode; @@ -88,7 +88,7 @@ AnalyzerStartParameters RemoteLinuxAnalyzeSupport::startParameters(const RunConf } RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(AbstractRemoteLinuxRunConfiguration *runConfig, - AnalyzerRunControl *engine, RunMode runMode) + AnalyzerRunControl *engine, Core::Id runMode) : AbstractRemoteLinuxRunSupport(runConfig, engine), d(new RemoteLinuxAnalyzeSupportPrivate(engine, runMode)) { diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.h b/src/plugins/remotelinux/remotelinuxanalyzesupport.h index 20ff11d802d..b5e3694af48 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.h +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.h @@ -53,10 +53,10 @@ class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public AbstractRemoteLinuxR Q_OBJECT public: static Analyzer::AnalyzerStartParameters startParameters(const ProjectExplorer::RunConfiguration *runConfig, - ProjectExplorer::RunMode runMode); + Core::Id runMode); RemoteLinuxAnalyzeSupport(AbstractRemoteLinuxRunConfiguration *runConfig, - Analyzer::AnalyzerRunControl *engine, ProjectExplorer::RunMode runMode); + Analyzer::AnalyzerRunControl *engine, Core::Id runMode); ~RemoteLinuxAnalyzeSupport(); protected: diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index f9bf98e4917..769b0a2929e 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -87,41 +87,25 @@ DebuggerStartParameters LinuxDeviceDebugSupport::startParameters(const AbstractR const IDevice::ConstPtr device = DeviceKitInformation::device(k); QTC_ASSERT(device, return params); + params.startMode = AttachToRemoteServer; params.closeMode = KillAndExitMonitorAtClose; - params.sysRoot = SysRootKitInformation::sysRoot(k).toString(); - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(k).toString(); - if (ToolChain *tc = ToolChainKitInformation::toolChain(k)) - params.toolChainAbi = tc->targetAbi(); + params.remoteSetupNeeded = true; + params.displayName = runConfig->displayName(); - DebuggerRunConfigurationAspect *aspect - = runConfig->extraAspect(); + auto aspect = runConfig->extraAspect(); if (aspect->useQmlDebugger()) { - params.languages |= QmlLanguage; params.qmlServerAddress = device->sshParameters().host; params.qmlServerPort = 0; // port is selected later on } if (aspect->useCppDebugger()) { - params.multiProcess = true; - params.languages |= CppLanguage; + aspect->setUseMultiProcess(true); QStringList args = runConfig->arguments(); if (aspect->useQmlDebugger()) args.prepend(QString::fromLatin1("-qmljsdebugger=port:%qml_port%,block")); params.processArgs = Utils::QtcProcess::joinArgs(args, Utils::OsTypeLinux); - params.startMode = AttachToRemoteServer; params.executable = runConfig->localExecutableFilePath(); params.remoteChannel = device->sshParameters().host + QLatin1String(":-1"); params.remoteExecutable = runConfig->remoteExecutableFilePath(); - } else { - params.startMode = AttachToRemoteServer; - } - params.remoteSetupNeeded = true; - params.displayName = runConfig->displayName(); - - if (const Project *project = target->project()) { - params.projectSourceDirectory = project->projectDirectory().toString(); - if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration()) - params.projectBuildDirectory = buildConfig->buildDirectory().toString(); - params.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); } return params; diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.cpp b/src/plugins/remotelinux/remotelinuxruncontrol.cpp index 4d359f82673..7525ba93b23 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrol.cpp +++ b/src/plugins/remotelinux/remotelinuxruncontrol.cpp @@ -57,7 +57,7 @@ public: }; RemoteLinuxRunControl::RemoteLinuxRunControl(RunConfiguration *rc) - : RunControl(rc, NormalRunMode), d(new RemoteLinuxRunControlPrivate) + : RunControl(rc, ProjectExplorer::Constants::NORMAL_RUN_MODE), d(new RemoteLinuxRunControlPrivate) { setIcon(QLatin1String(ProjectExplorer::Constants::ICON_RUN_SMALL)); diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp index 69a94478dc0..3053e39027f 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp @@ -63,10 +63,12 @@ RemoteLinuxRunControlFactory::~RemoteLinuxRunControlFactory() { } -bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != DebugRunModeWithBreakOnMain - && mode != QmlProfilerRunMode) { + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN + && mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { return false; } @@ -76,16 +78,16 @@ bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Ru || id.name().startsWith(RemoteLinuxRunConfiguration::IdPrefix)); } -RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, RunMode mode, +RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *errorMessage) { QTC_ASSERT(canRun(runConfig, mode), return 0); - switch (mode) { - case NormalRunMode: + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) return new RemoteLinuxRunControl(runConfig); - case DebugRunMode: - case DebugRunModeWithBreakOnMain: { + + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE + || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) { IDevice::ConstPtr dev = DeviceKitInformation::device(runConfig->target()->kit()); if (!dev) { *errorMessage = tr("Cannot debug: Kit has no device."); @@ -104,10 +106,7 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Ru } DebuggerStartParameters params = LinuxDeviceDebugSupport::startParameters(rc); - if (mode == DebugRunModeWithBreakOnMain) - params.breakOnMain = true; - params.runConfiguration = runConfig; - DebuggerRunControl * const runControl = createDebuggerRunControl(params, errorMessage); + DebuggerRunControl * const runControl = createDebuggerRunControl(params, runConfig, errorMessage); if (!runControl) return 0; LinuxDeviceDebugSupport * const debugSupport = @@ -115,7 +114,8 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Ru connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished())); return runControl; } - case QmlProfilerRunMode: { + + if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { AnalyzerStartParameters params = RemoteLinuxAnalyzeSupport::startParameters(runConfig, mode); auto * const rc = qobject_cast(runConfig); QTC_ASSERT(rc, return 0); @@ -123,16 +123,8 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Ru (void) new RemoteLinuxAnalyzeSupport(rc, runControl, mode); return runControl; } - case PerfProfilerRunMode: - case NoRunMode: - case CallgrindRunMode: - case MemcheckRunMode: - case MemcheckWithGdbRunMode: - case ClangStaticAnalyzerMode: - QTC_ASSERT(false, return 0); - } - QTC_ASSERT(false, return 0); + QTC_CHECK(false); return 0; } diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.h b/src/plugins/remotelinux/remotelinuxruncontrolfactory.h index b8a8aa34504..fb8828248e9 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.h +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.h @@ -43,9 +43,9 @@ public: ~RemoteLinuxRunControlFactory(); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const; + Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, QString *errorMessage); + Core::Id mode, QString *errorMessage); }; } // namespace Internal diff --git a/src/plugins/texteditor/codeassist/assistproposalitem.cpp b/src/plugins/texteditor/codeassist/assistproposalitem.cpp index eaad6d3b083..38c102a7c9f 100644 --- a/src/plugins/texteditor/codeassist/assistproposalitem.cpp +++ b/src/plugins/texteditor/codeassist/assistproposalitem.cpp @@ -135,12 +135,14 @@ bool AssistProposalItem::prematurelyApplies(const QChar &c) const void AssistProposalItem::apply(TextEditorWidget *editorWidget, int basePosition) const { - if (data().canConvert()) + if (data().canConvert()) { applySnippet(editorWidget, basePosition); - else if (data().canConvert()) + } else if (data().canConvert()) { applyQuickFix(editorWidget, basePosition); - else + } else { applyContextualContent(editorWidget, basePosition); + editorWidget->encourageApply(); + } } void AssistProposalItem::applyContextualContent(TextEditorWidget *editorWidget, int basePosition) const diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 53d737c0709..b7f5302fef9 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -150,6 +150,8 @@ using namespace Utils; namespace TextEditor { namespace Internal { +enum { NExtraSelectionKinds = 12 }; + typedef QString (TransformationMethod)(const QString &); static QString QString_toUpper(const QString &str) @@ -414,8 +416,8 @@ public: void highlightSearchResults(const QTextBlock &block, TextEditorOverlay *overlay); QTimer m_delayedUpdateTimer; - void setExtraSelections(int kind, const QList &selections); - QHash> m_extraSelections; + void setExtraSelections(Core::Id kind, const QList &selections); + QHash> m_extraSelections; // block selection mode bool m_inBlockSelectionMode; @@ -555,8 +557,7 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) m_cursorPositionLabelAction = m_toolBar->addWidget(m_cursorPositionLabel); m_fileEncodingLabelAction = m_toolBar->addWidget(m_fileEncodingLabel); - - m_extraSelections.reserve(TextEditorWidget::NExtraSelectionKinds); + m_extraSelections.reserve(NExtraSelectionKinds); } } // namespace Internal @@ -619,6 +620,18 @@ QString TextEditorWidget::convertToPlainText(const QString &txt) static const char kTextBlockMimeType[] = "application/vnd.qtcreator.blocktext"; +Id TextEditorWidget::SnippetPlaceholderSelection("TextEdit.SnippetPlaceHolderSelection"); +Id TextEditorWidget::CurrentLineSelection("TextEdit.CurrentLineSelection"); +Id TextEditorWidget::ParenthesesMatchingSelection("TextEdit.ParenthesesMatchingSelection"); +Id TextEditorWidget::CodeWarningsSelection("TextEdit.CodeWarningsSelection"); +Id TextEditorWidget::CodeSemanticsSelection("TextEdit.CodeSemanticsSelection"); +Id TextEditorWidget::UndefinedSymbolSelection("TextEdit.UndefinedSymbolSelection"); +Id TextEditorWidget::UnusedSymbolSelection("TextEdit.UnusedSymbolSelection"); +Id TextEditorWidget::OtherSelection("TextEdit.OtherSelection"); +Id TextEditorWidget::ObjCSelection("TextEdit.ObjCSelection"); +Id TextEditorWidget::DebuggerExceptionSelection("TextEdit.DebuggerExceptionSelection"); +Id TextEditorWidget::FakeVimSelection("TextEdit.FakeVimSelection"); + TextEditorWidget::TextEditorWidget(QWidget *parent) : QPlainTextEdit(parent) { @@ -2615,7 +2628,7 @@ void TextEditorWidgetPrivate::documentAboutToBeReloaded() // remove extra selections (loads of QTextCursor objects) m_extraSelections.clear(); - m_extraSelections.reserve(TextEditorWidget::NExtraSelectionKinds); + m_extraSelections.reserve(NExtraSelectionKinds); q->QPlainTextEdit::setExtraSelections(QList()); // clear all overlays @@ -5423,7 +5436,14 @@ void TextEditorWidgetPrivate::handleBackspaceKey() void TextEditorWidget::wheelEvent(QWheelEvent *e) { d->clearVisibleFoldedBlock(); - if (scrollWheelZoomingEnabled() && e->modifiers() & Qt::ControlModifier) { + if (e->modifiers() & Qt::ControlModifier) { + if (!scrollWheelZoomingEnabled()) { + // When the setting is disabled globally, + // we have to skip calling QPlainTextEdit::wheelEvent() + // that changes zoom in it. + return; + } + const int delta = e->delta(); if (delta < 0) zoomOut(); @@ -6085,8 +6105,7 @@ void TextEditorWidget::deleteStartOfWordCamelCase() setTextCursor(c); } -// kind can be either a value from the ExtraSelectionKind enum, or an unique Core::Id identifier. -void TextEditorWidgetPrivate::setExtraSelections(int kind, const QList &selections) +void TextEditorWidgetPrivate::setExtraSelections(Id kind, const QList &selections) { if (selections.isEmpty() && m_extraSelections[kind].isEmpty()) return; @@ -6124,28 +6143,14 @@ void TextEditorWidgetPrivate::setExtraSelections(int kind, const QList &selections) +void TextEditorWidget::setExtraSelections(Id kind, const QList &selections) { d->setExtraSelections(kind, selections); } -QList TextEditorWidget::extraSelections(ExtraSelectionKind kind) const -{ - return d->m_extraSelections[kind]; -} - -void TextEditorWidget::setExtraSelections(Id kind, const QList &selections) -{ - // Private Core:Id identifiers from the 0-1000 range cannot be used here, they conflict with ExtraSelectionKind - QTC_ASSERT(kind.uniqueIdentifier() >= NExtraSelectionKinds, return); - d->setExtraSelections(kind.uniqueIdentifier(), selections); -} - QList TextEditorWidget::extraSelections(Id kind) const { - // Private Core:Id identifiers from the 0-1000 range cannot be used here, they conflict with ExtraSelectionKind - QTC_ASSERT(kind.uniqueIdentifier() >= NExtraSelectionKinds, return QList()); - return d->m_extraSelections[kind.uniqueIdentifier()]; + return d->m_extraSelections.value(kind); } QString TextEditorWidget::extraSelectionTooltip(int pos) const @@ -6351,6 +6356,13 @@ void TextEditorWidget::unCommentSelection() Utils::unCommentSelection(this, d->m_commentDefinition); } +void TextEditorWidget::encourageApply() +{ + if (!d->m_snippetOverlay->isVisible() || d->m_snippetOverlay->isEmpty()) + return; + d->m_snippetOverlay->updateEquivalentSelections(textCursor()); +} + void TextEditorWidget::showEvent(QShowEvent* e) { triggerPendingUpdates(); @@ -6586,6 +6598,7 @@ void TextEditorWidget::copy() void TextEditorWidget::paste() { QPlainTextEdit::paste(); + encourageApply(); } void TextEditorWidgetPrivate::collectToCircularClipboard() diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 183163232a1..9dd8e3b117c 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -328,22 +328,18 @@ public: void ensureCursorVisible(); - enum ExtraSelectionKind { - CurrentLineSelection, - ParenthesesMatchingSelection, - CodeWarningsSelection, - CodeSemanticsSelection, - UndefinedSymbolSelection, - UnusedSymbolSelection, - FakeVimSelection, - OtherSelection, - SnippetPlaceholderSelection, - ObjCSelection, - DebuggerExceptionSelection, - NExtraSelectionKinds - }; - void setExtraSelections(ExtraSelectionKind kind, const QList &selections); - QList extraSelections(ExtraSelectionKind kind) const; + static Core::Id FakeVimSelection; + static Core::Id SnippetPlaceholderSelection; + static Core::Id CurrentLineSelection; + static Core::Id ParenthesesMatchingSelection; + static Core::Id CodeWarningsSelection; + static Core::Id CodeSemanticsSelection; + static Core::Id UndefinedSymbolSelection; + static Core::Id UnusedSymbolSelection; + static Core::Id OtherSelection; + static Core::Id ObjCSelection; + static Core::Id DebuggerExceptionSelection; + void setExtraSelections(Core::Id kind, const QList &selections); QList extraSelections(Core::Id kind) const; QString extraSelectionTooltip(int pos) const; @@ -367,6 +363,8 @@ public: virtual void rewrapParagraph(); virtual void unCommentSelection(); + virtual void encourageApply(); + public slots: // Qt4-style connect used in EditorConfiguration virtual void setDisplaySettings(const TextEditor::DisplaySettings &); virtual void setMarginSettings(const TextEditor::MarginSettings &); diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index 036a1606d28..4d61da53d6c 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -63,7 +63,7 @@ public: uint optionalActions); QAction *registerActionHelper(Core::Id id, bool scriptable, const QString &title, - const QKeySequence &keySequence, const char *menueGroup, + const QKeySequence &keySequence, Core::Id menueGroup, Core::ActionContainer *container, std::function slot) { @@ -72,7 +72,7 @@ public: if (!keySequence.isEmpty()) command->setDefaultKeySequence(keySequence); - if (container && menueGroup) + if (container && menueGroup.isValid()) container->addAction(command, menueGroup); connect(result, &QAction::triggered, slot); @@ -84,7 +84,7 @@ public: bool scriptable = false, const QString &title = QString(), const QKeySequence &keySequence = QKeySequence(), - const char *menueGroup = 0, + Core::Id menueGroup = Core::Id(), Core::ActionContainer *container = 0) { return registerActionHelper(id, scriptable, title, keySequence, menueGroup, container, @@ -96,7 +96,7 @@ public: bool scriptable = false, const QString &title = QString(), const QKeySequence &keySequence = QKeySequence(), - const char *menueGroup = 0, + Core::Id menueGroup = Core::Id(), Core::ActionContainer *container = 0) { return registerActionHelper(id, scriptable, title, keySequence, menueGroup, container, @@ -108,7 +108,7 @@ public: bool scriptable = false, const QString &title = QString(), const QKeySequence &keySequence = QKeySequence(), - const char *menueGroup = 0, + Core::Id menueGroup = Core::Id(), Core::ActionContainer *container = 0) { return registerActionHelper(id, scriptable, title, keySequence, menueGroup, container, diff --git a/src/plugins/valgrind/callgrindengine.cpp b/src/plugins/valgrind/callgrindengine.cpp index 42273f69a35..a37d276606e 100644 --- a/src/plugins/valgrind/callgrindengine.cpp +++ b/src/plugins/valgrind/callgrindengine.cpp @@ -30,6 +30,7 @@ #include "callgrindengine.h" +#include "callgrindtool.h" #include "valgrindsettings.h" #include @@ -58,7 +59,7 @@ CallgrindRunControl::CallgrindRunControl(const AnalyzerStartParameters &sp, void CallgrindRunControl::showStatusMessage(const QString &msg) { - AnalyzerManager::showStatusMessage(msg); + AnalyzerManager::showStatusMessage(CallgrindToolId, msg); } QStringList CallgrindRunControl::toolArguments() const diff --git a/src/plugins/valgrind/callgrindtool.cpp b/src/plugins/valgrind/callgrindtool.cpp index b792cd2dd1e..a30898e6041 100644 --- a/src/plugins/valgrind/callgrindtool.cpp +++ b/src/plugins/valgrind/callgrindtool.cpp @@ -834,7 +834,7 @@ void CallgrindToolPrivate::engineFinished() if (data) showParserResults(data); else - AnalyzerManager::showStatusMessage(tr("Profiling aborted.")); + AnalyzerManager::showStatusMessage(CallgrindToolId, tr("Profiling aborted.")); setBusyCursor(false); } @@ -853,7 +853,7 @@ void CallgrindToolPrivate::showParserResults(const ParseData *data) } else { msg = tr("Parsing failed."); } - AnalyzerManager::showStatusMessage(msg); + AnalyzerManager::showStatusMessage(CallgrindToolId, msg); } void CallgrindToolPrivate::editorOpened(IEditor *editor) @@ -891,8 +891,7 @@ void CallgrindToolPrivate::handleShowCostsOfFunction() m_toggleCollectFunction = qualifiedFunctionName + QLatin1String("()"); - AnalyzerManager::selectTool(CallgrindLocalActionId); - AnalyzerManager::startTool(); + AnalyzerManager::selectAction(CallgrindLocalActionId, /* alsoRunIt = */ true); } void CallgrindToolPrivate::slotRequestDump() @@ -919,7 +918,7 @@ void CallgrindToolPrivate::loadExternalLogFile() return; } - AnalyzerManager::showStatusMessage(tr("Parsing Profile Data...")); + AnalyzerManager::showStatusMessage(CallgrindToolId, tr("Parsing Profile Data...")); QCoreApplication::processEvents(); Parser parser; diff --git a/src/plugins/valgrind/callgrindtool.h b/src/plugins/valgrind/callgrindtool.h index 0018ecab2aa..0ef8905c6ba 100644 --- a/src/plugins/valgrind/callgrindtool.h +++ b/src/plugins/valgrind/callgrindtool.h @@ -41,6 +41,8 @@ const char CallgrindLocalActionId[] = "Callgrind.Local"; const char CallgrindRemoteActionId[] = "Callgrind.Remote"; class ValgrindRunControl; +const char CALLGRIND_RUN_MODE[] = "CallgrindTool.CallgrindRunMode"; + class CallgrindToolPrivate; class CallgrindTool : public QObject diff --git a/src/plugins/valgrind/memcheckengine.cpp b/src/plugins/valgrind/memcheckengine.cpp index c11d307b0da..158006f724b 100644 --- a/src/plugins/valgrind/memcheckengine.cpp +++ b/src/plugins/valgrind/memcheckengine.cpp @@ -156,39 +156,17 @@ void MemcheckWithGdbRunControl::startDebugger() { const qint64 valgrindPid = runner()->valgrindProcess()->pid(); const AnalyzerStartParameters &mySp = startParameters(); + Debugger::DebuggerStartParameters sp; - - RunConfiguration *rc = runConfiguration(); - const Target *target = rc->target(); - QTC_ASSERT(target, return); - - const Kit *kit = target->kit(); - QTC_ASSERT(kit, return); - - if (const ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - sp.toolChainAbi = tc->targetAbi(); - - if (const Project *project = target->project()) { - sp.projectSourceDirectory = project->projectDirectory().toString(); - sp.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - - if (const BuildConfiguration *bc = target->activeBuildConfiguration()) - sp.projectBuildDirectory = bc->buildDirectory().toString(); - } - sp.executable = mySp.debuggee; - sp.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - sp.debuggerCommand = Debugger::DebuggerKitInformation::debuggerCommand(kit).toString(); - sp.languages |= Debugger::CppLanguage; sp.startMode = Debugger::AttachToRemoteServer; sp.displayName = QString::fromLatin1("VGdb %1").arg(valgrindPid); sp.remoteChannel = QString::fromLatin1("| vgdb --pid=%1").arg(valgrindPid); sp.useContinueInsteadOfRun = true; - sp.expectedSignals << "SIGTRAP"; - sp.runConfiguration = rc; + sp.expectedSignals.append("SIGTRAP"); QString errorMessage; - RunControl *gdbRunControl = Debugger::createDebuggerRunControl(sp, &errorMessage); + RunControl *gdbRunControl = Debugger::createDebuggerRunControl(sp, runConfiguration(), &errorMessage); QTC_ASSERT(gdbRunControl, return); connect(gdbRunControl, &RunControl::finished, gdbRunControl, &RunControl::deleteLater); diff --git a/src/plugins/valgrind/memcheckerrorview.cpp b/src/plugins/valgrind/memcheckerrorview.cpp index 85d71a62e1a..05348a5a519 100644 --- a/src/plugins/valgrind/memcheckerrorview.cpp +++ b/src/plugins/valgrind/memcheckerrorview.cpp @@ -83,9 +83,9 @@ static QString makeFrameName(const Frame &frame, const QString &relativeTo, bool link = true, const QString &linkAttr = QString()) { const QString d = frame.directory(); - const QString f = frame.file(); + const QString f = frame.fileName(); const QString fn = frame.functionName(); - const QString fullPath = d + QLatin1Char('/') + f; + const QString fullPath = frame.filePath(); QString path; if (!d.isEmpty() && !f.isEmpty()) diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index 04d4085e2e6..d6830df6e41 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -94,6 +94,7 @@ using namespace Valgrind::XmlProtocol; namespace Valgrind { namespace Internal { +const Core::Id MemcheckToolId = "Memcheck"; // ---------------------------- MemcheckErrorFilterProxyModel MemcheckErrorFilterProxyModel::MemcheckErrorFilterProxyModel(QObject *parent) @@ -299,11 +300,11 @@ public: //find the first frame belonging to the project if (!m_projectFiles.isEmpty()) { foreach (const Frame &frame, frames) { - if (frame.directory().isEmpty() || frame.file().isEmpty()) + if (frame.directory().isEmpty() || frame.fileName().isEmpty()) continue; //filepaths can contain "..", clean them: - const QString f = QFileInfo(frame.directory() + QLatin1Char('/') + frame.file()).absoluteFilePath(); + const QString f = QFileInfo(frame.filePath()).absoluteFilePath(); if (m_projectFiles.contains(f)) return frame; } @@ -355,7 +356,7 @@ QWidget *MemcheckTool::createWidgets() m_errorView->setObjectName(QLatin1String("Valgrind.MemcheckTool.ErrorView")); m_errorView->setWindowTitle(tr("Memory Issues")); - QDockWidget *errorDock = AnalyzerManager::createDockWidget("Memcheck", m_errorView); + QDockWidget *errorDock = AnalyzerManager::createDockWidget(MemcheckToolId, m_errorView); errorDock->show(); mw->splitDockWidget(mw->toolBarDockWidget(), errorDock, Qt::Vertical); @@ -575,7 +576,7 @@ MemcheckRunControl *MemcheckTool::createMemcheckRunControl(const AnalyzerStartPa void MemcheckTool::engineFinished() { const int issuesFound = updateUiAfterFinishedHelper(); - AnalyzerManager::showStatusMessage(issuesFound > 0 + AnalyzerManager::showStatusMessage(MemcheckToolId, issuesFound > 0 ? AnalyzerManager::tr("Memory Analyzer Tool finished, %n issues were found.", 0, issuesFound) : AnalyzerManager::tr("Memory Analyzer Tool finished, no issues were found.")); } @@ -583,7 +584,7 @@ void MemcheckTool::engineFinished() void MemcheckTool::loadingExternalXmlLogFileFinished() { const int issuesFound = updateUiAfterFinishedHelper(); - AnalyzerManager::showStatusMessage(issuesFound > 0 + AnalyzerManager::showStatusMessage(MemcheckToolId, issuesFound > 0 ? AnalyzerManager::tr("Log file processed, %n issues were found.", 0, issuesFound) : AnalyzerManager::tr("Log file processed, no issues were found.")); } diff --git a/src/plugins/valgrind/memchecktool.h b/src/plugins/valgrind/memchecktool.h index 6e9cdaae1c8..2f0f593e7d9 100644 --- a/src/plugins/valgrind/memchecktool.h +++ b/src/plugins/valgrind/memchecktool.h @@ -50,6 +50,10 @@ class Error; } namespace Valgrind { + +const char MEMCHECK_RUN_MODE[] = "MemcheckTool.MemcheckRunMode"; +const char MEMCHECK_WITH_GDB_RUN_MODE[] = "MemcheckTool.MemcheckWithGdbRunMode"; + namespace Internal { class FrameFinder; @@ -57,6 +61,7 @@ class MemcheckErrorView; class MemcheckRunControl; class ValgrindBaseSettings; + class MemcheckErrorFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT diff --git a/src/plugins/valgrind/valgrindplugin.cpp b/src/plugins/valgrind/valgrindplugin.cpp index f8efdf33527..f92b648230e 100644 --- a/src/plugins/valgrind/valgrindplugin.cpp +++ b/src/plugins/valgrind/valgrindplugin.cpp @@ -54,7 +54,6 @@ #include #include -#include #include @@ -166,7 +165,7 @@ void ValgrindPlugin::extensionsInitialized() action->setWidgetCreator(mcWidgetCreator); action->setRunControlCreator(mcRunControlCreator); action->setToolMode(DebugMode); - action->setRunMode(ProjectExplorer::MemcheckRunMode); + action->setRunMode(MEMCHECK_RUN_MODE); action->setText(tr("Valgrind Memory Analyzer")); action->setToolTip(memcheckToolTip); action->setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS); @@ -182,7 +181,7 @@ void ValgrindPlugin::extensionsInitialized() action->setRunControlCreator(std::bind(&MemcheckWithGdbTool::createRunControl, mcgTool, _1, _2)); action->setToolMode(DebugMode); - action->setRunMode(ProjectExplorer::MemcheckWithGdbRunMode); + action->setRunMode(MEMCHECK_WITH_GDB_RUN_MODE); action->setText(tr("Valgrind Memory Analyzer with GDB")); action->setToolTip(tr("Valgrind Analyze Memory with GDB uses the " "Memcheck tool to find memory leaks.\nWhen a problem is detected, " @@ -197,7 +196,7 @@ void ValgrindPlugin::extensionsInitialized() action->setWidgetCreator(cgWidgetCreator); action->setRunControlCreator(cgRunControlCreator); action->setToolMode(ReleaseMode); - action->setRunMode(CallgrindRunMode); + action->setRunMode(CALLGRIND_RUN_MODE); action->setText(tr("Valgrind Function Profiler")); action->setToolTip(callgrindToolTip); action->setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS); @@ -216,7 +215,7 @@ void ValgrindPlugin::extensionsInitialized() ValgrindRunControl *rc = mcTool->createRunControl(sp, 0); QTC_ASSERT(rc, return); rc->setCustomStart(); - ProjectExplorerPlugin::startRunControl(rc, MemcheckRunMode); + ProjectExplorerPlugin::startRunControl(rc, MEMCHECK_RUN_MODE); }); action->setText(tr("Valgrind Memory Analyzer (External Remote Application)")); action->setToolTip(memcheckToolTip); @@ -234,7 +233,7 @@ void ValgrindPlugin::extensionsInitialized() ValgrindRunControl *rc = cgTool->createRunControl(sp, 0); QTC_ASSERT(rc, return); rc->setCustomStart(); - ProjectExplorerPlugin::startRunControl(rc, CallgrindRunMode); + ProjectExplorerPlugin::startRunControl(rc, CALLGRIND_RUN_MODE); }); action->setText(tr("Valgrind Function Profiler (External Remote Application)")); diff --git a/src/plugins/valgrind/valgrindplugin.h b/src/plugins/valgrind/valgrindplugin.h index 912c3ce5023..a53152903ff 100644 --- a/src/plugins/valgrind/valgrindplugin.h +++ b/src/plugins/valgrind/valgrindplugin.h @@ -34,6 +34,7 @@ #include #include +#include namespace Valgrind { namespace Internal { diff --git a/src/plugins/valgrind/valgrindruncontrolfactory.cpp b/src/plugins/valgrind/valgrindruncontrolfactory.cpp index 23b393d2bb8..32f214b2ece 100644 --- a/src/plugins/valgrind/valgrindruncontrolfactory.cpp +++ b/src/plugins/valgrind/valgrindruncontrolfactory.cpp @@ -31,6 +31,8 @@ #include "valgrindruncontrolfactory.h" #include "valgrindsettings.h" #include "valgrindplugin.h" +#include "callgrindtool.h" +#include "memchecktool.h" #include #include @@ -62,13 +64,13 @@ ValgrindRunControlFactory::ValgrindRunControlFactory(QObject *parent) : { } -bool ValgrindRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool ValgrindRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { Q_UNUSED(runConfiguration); - return mode == CallgrindRunMode || mode == MemcheckRunMode || mode == MemcheckWithGdbRunMode; + return mode == CALLGRIND_RUN_MODE || mode == MEMCHECK_RUN_MODE || mode == MEMCHECK_WITH_GDB_RUN_MODE; } -RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { Q_UNUSED(errorMessage); diff --git a/src/plugins/valgrind/valgrindruncontrolfactory.h b/src/plugins/valgrind/valgrindruncontrolfactory.h index 2b04b33b46f..6c306325396 100644 --- a/src/plugins/valgrind/valgrindruncontrolfactory.h +++ b/src/plugins/valgrind/valgrindruncontrolfactory.h @@ -45,10 +45,10 @@ public: explicit ValgrindRunControlFactory(QObject *parent = 0); // IRunControlFactory implementation - bool canRun(RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const; ProjectExplorer::RunControl *create(RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); ProjectExplorer::IRunConfigurationAspect *createRunConfigurationAspect(ProjectExplorer::RunConfiguration *rc); }; diff --git a/src/plugins/valgrind/xmlprotocol/error.cpp b/src/plugins/valgrind/xmlprotocol/error.cpp index 7ba728f8d59..5794e7dc46d 100644 --- a/src/plugins/valgrind/xmlprotocol/error.cpp +++ b/src/plugins/valgrind/xmlprotocol/error.cpp @@ -238,8 +238,8 @@ QString Error::toXml() const stream << " " << frame.functionName() << "\n"; if (!frame.directory().isEmpty()) stream << " " << frame.directory() << "\n"; - if (!frame.file().isEmpty()) - stream << " " << frame.file() << "\n"; + if (!frame.fileName().isEmpty()) + stream << " " << frame.fileName() << "\n"; if (frame.line() != -1) stream << " " << frame.line() << ""; stream << " \n"; diff --git a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp index ba7cf71348b..6c23993097b 100644 --- a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp +++ b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp @@ -111,16 +111,13 @@ Frame ErrorListModel::Private::findRelevantFrame(const Error &error) const QString ErrorListModel::Private::formatAbsoluteFilePath(const Error &error) const { - const Frame f = findRelevantFrame(error); - if (!f.directory().isEmpty() && !f.file().isEmpty()) - return f.directory() + QLatin1Char('/') + f.file(); - return QString(); + return findRelevantFrame(error).filePath(); } QString ErrorListModel::Private::formatLocation(const Error &error) const { const Frame frame = findRelevantFrame(error); - const QString file = frame.file(); + const QString file = frame.fileName(); if (!frame.functionName().isEmpty()) return frame.functionName(); if (!file.isEmpty()) { @@ -185,7 +182,7 @@ QVariant ErrorListModel::Private::errorData(int row, int column, int role) const case AbsoluteFilePathRole: return formatAbsoluteFilePath(error); case FileRole: - return findRelevantFrame(error).file(); + return findRelevantFrame(error).fileName(); case LineRole: { const qint64 line = findRelevantFrame(error).line(); return line > 0 ? line : QVariant(); diff --git a/src/plugins/valgrind/xmlprotocol/frame.cpp b/src/plugins/valgrind/xmlprotocol/frame.cpp index fe916fa5995..e29ddf1ec76 100644 --- a/src/plugins/valgrind/xmlprotocol/frame.cpp +++ b/src/plugins/valgrind/xmlprotocol/frame.cpp @@ -48,7 +48,7 @@ public: return ip == other.ip && object == other.object && functionName == other.functionName - && file == other.file + && fileName == other.fileName && directory == other.directory && line == other.line; } @@ -56,7 +56,7 @@ public: quint64 ip; QString object; QString functionName; - QString file; + QString fileName; QString directory; int line; }; @@ -126,14 +126,14 @@ void Frame::setFunctionName(const QString &functionName) d->functionName = functionName; } -QString Frame::file() const +QString Frame::fileName() const { - return d->file; + return d->fileName; } -void Frame::setFile(const QString &file) +void Frame::setFileName(const QString &file) { - d->file = file; + d->fileName = file; } QString Frame::directory() const @@ -146,6 +146,14 @@ void Frame::setDirectory(const QString &directory) d->directory = directory; } +QString Frame::filePath() const +{ + QString f; + if (!directory().isEmpty()) + f.append(directory()).append(QLatin1Char('/')); + return f.append(fileName()); +} + int Frame::line() const { return d->line; diff --git a/src/plugins/valgrind/xmlprotocol/frame.h b/src/plugins/valgrind/xmlprotocol/frame.h index 697e25f2149..d184748d548 100644 --- a/src/plugins/valgrind/xmlprotocol/frame.h +++ b/src/plugins/valgrind/xmlprotocol/frame.h @@ -59,12 +59,14 @@ public: QString functionName() const; void setFunctionName(const QString &functionName); - QString file() const; - void setFile(const QString &file); + QString fileName() const; + void setFileName(const QString &fileName); QString directory() const; void setDirectory(const QString &directory); + QString filePath() const; + int line() const; void setLine(int line); diff --git a/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp b/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp index 3b01e69b475..754e99922f2 100644 --- a/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp +++ b/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp @@ -43,8 +43,8 @@ namespace XmlProtocol { QString toolTipForFrame(const Frame &frame) { QString location; - if (!frame.file().isEmpty()) { - location = frame.directory() + QLatin1Char('/') + frame.file(); + if (!frame.fileName().isEmpty()) { + location = frame.filePath(); if (frame.line() > 0) location += QLatin1Char(':') + QString::number(frame.line()); } diff --git a/src/plugins/valgrind/xmlprotocol/parser.cpp b/src/plugins/valgrind/xmlprotocol/parser.cpp index 95114578bdd..9ace7559445 100644 --- a/src/plugins/valgrind/xmlprotocol/parser.cpp +++ b/src/plugins/valgrind/xmlprotocol/parser.cpp @@ -517,7 +517,7 @@ Frame Parser::Private::parseFrame() else if (name == QLatin1String("dir")) frame.setDirectory(blockingReadElementText()); else if (name == QLatin1String("file")) - frame.setFile( blockingReadElementText()); + frame.setFileName(blockingReadElementText()); else if (name == QLatin1String("line")) frame.setLine(parseInt64(blockingReadElementText(), QLatin1String("error/frame/line"))); else if (reader.isStartElement()) diff --git a/src/plugins/valgrind/xmlprotocol/stackmodel.cpp b/src/plugins/valgrind/xmlprotocol/stackmodel.cpp index 9ae8beb48e2..5d806eca870 100644 --- a/src/plugins/valgrind/xmlprotocol/stackmodel.cpp +++ b/src/plugins/valgrind/xmlprotocol/stackmodel.cpp @@ -60,7 +60,7 @@ public: static QString makeName(const Frame &frame) { const QString d = frame.directory(); - const QString f = frame.file(); + const QString f = frame.fileName(); const QString fn = frame.functionName(); if (!fn.isEmpty()) return fn; @@ -123,7 +123,7 @@ QVariant StackModel::data(const QModelIndex &index, int role) const case DirectoryColumn: return frame.directory(); case FileColumn: - return frame.file(); + return frame.fileName(); case LineColumn: if (frame.line() > 0) return frame.line(); @@ -139,7 +139,7 @@ QVariant StackModel::data(const QModelIndex &index, int role) const case FunctionNameRole: return frame.functionName(); case FileRole: - return frame.file(); + return frame.fileName(); case DirectoryRole: return frame.directory(); case LineRole: diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 36df6fb2f00..3a0256e5f3f 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -56,6 +56,17 @@ #include #include +static void commandFinished(VcsBase::VcsBaseEditorWidget *editor, VcsBase::VcsCommand *cmd) +{ + if (!cmd->lastExecutionSuccess()) { + editor->reportCommandFinished(false, cmd->lastExecutionExitCode(), cmd->cookie()); + } else if (cmd->cookie().type() == QVariant::Int) { + const int line = cmd->cookie().toInt(); + if (line >= 0) + editor->gotoLine(line); + } +} + /*! \class VcsBase::VcsBaseClient @@ -80,27 +91,14 @@ namespace VcsBase { class VcsBaseClientImplPrivate { public: - VcsBaseClientImplPrivate(VcsBaseClientImpl *client, VcsBaseClientSettings *settings); + VcsBaseClientImplPrivate(VcsBaseClientSettings *settings); ~VcsBaseClientImplPrivate(); - void bindCommandToEditor(VcsCommand *cmd, VcsBaseEditorWidget *editor); - VcsBaseClientSettings *m_clientSettings; - QSignalMapper *m_cmdFinishedMapper; }; -void VcsBaseClientImplPrivate::bindCommandToEditor(VcsCommand *cmd, VcsBaseEditorWidget *editor) -{ - editor->setCommand(cmd); - QObject::connect(cmd, &VcsCommand::finished, - m_cmdFinishedMapper, static_cast(&QSignalMapper::map)); - m_cmdFinishedMapper->setMapping(cmd, editor); -} - -VcsBaseClientImplPrivate::VcsBaseClientImplPrivate(VcsBaseClientImpl *client, - VcsBaseClientSettings *settings) : - m_clientSettings(settings), - m_cmdFinishedMapper(new QSignalMapper(client)) +VcsBaseClientImplPrivate::VcsBaseClientImplPrivate(VcsBaseClientSettings *settings) : + m_clientSettings(settings) { m_clientSettings->readSettings(Core::ICore::settings()); } @@ -110,14 +108,11 @@ VcsBaseClientImplPrivate::~VcsBaseClientImplPrivate() delete m_clientSettings; } -VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseClientImpl *client, VcsBaseClientSettings *settings) : - d(new VcsBaseClientImplPrivate(client, settings)) +VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseClientSettings *settings) : + d(new VcsBaseClientImplPrivate(settings)) { connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, this, &VcsBaseClientImpl::saveSettings); - - connect(d->m_cmdFinishedMapper, static_cast(&QSignalMapper::mapped), - this, &VcsBaseClientImpl::commandFinishedGotoLine); } VcsBaseClientImpl::~VcsBaseClientImpl() @@ -141,8 +136,12 @@ VcsCommand *VcsBaseClientImpl::createCommand(const QString &workingDirectory, { auto cmd = new VcsCommand(workingDirectory, processEnvironment()); cmd->setDefaultTimeoutS(vcsTimeoutS()); - if (editor) - d->bindCommandToEditor(cmd, editor); + if (editor) { + editor->setCommand(cmd); + connect(editor, &QObject::destroyed, cmd, &VcsCommand::abort); + connect(cmd, &VcsCommand::finished, + editor, [editor, cmd]() { commandFinished(editor, cmd); }); + } if (mode == VcsWindowOutputBind) { cmd->addFlags(VcsCommand::ShowStdOut); if (editor) // assume that the commands output is the important thing @@ -278,22 +277,6 @@ void VcsBaseClientImpl::saveSettings() settings().writeSettings(Core::ICore::settings()); } -void VcsBaseClientImpl::commandFinishedGotoLine(QWidget *editorObject) -{ - VcsBaseEditorWidget *editor = qobject_cast(editorObject); - VcsCommand *cmd = qobject_cast(d->m_cmdFinishedMapper->mapping(editor)); - if (editor && cmd) { - if (!cmd->lastExecutionSuccess()) { - editor->reportCommandFinished(false, cmd->lastExecutionExitCode(), cmd->cookie()); - } else if (cmd->cookie().type() == QVariant::Int) { - const int line = cmd->cookie().toInt(); - if (line >= 0) - editor->gotoLine(line); - } - d->m_cmdFinishedMapper->removeMappings(cmd); - } -} - class VcsBaseClientPrivate { public: @@ -319,7 +302,7 @@ VcsBaseClient::StatusItem::StatusItem(const QString &s, const QString &f) : { } VcsBaseClient::VcsBaseClient(VcsBaseClientSettings *settings) : - VcsBaseClientImpl(this, settings), + VcsBaseClientImpl(settings), d(new VcsBaseClientPrivate) { qRegisterMetaType(); diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index 50827a1384b..03a87ea4587 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -68,7 +68,7 @@ class VCSBASE_EXPORT VcsBaseClientImpl : public QObject Q_OBJECT public: - explicit VcsBaseClientImpl(VcsBaseClientImpl *client, VcsBaseClientSettings *settings); + explicit VcsBaseClientImpl(VcsBaseClientSettings *settings); ~VcsBaseClientImpl(); VcsBaseClientSettings &settings() const; @@ -130,7 +130,6 @@ protected: private: void saveSettings(); - void commandFinishedGotoLine(QWidget*); VcsBaseClientImplPrivate *d; }; diff --git a/src/plugins/winrt/winrtdebugsupport.cpp b/src/plugins/winrt/winrtdebugsupport.cpp index c81b94a4542..0f25380fc82 100644 --- a/src/plugins/winrt/winrtdebugsupport.cpp +++ b/src/plugins/winrt/winrtdebugsupport.cpp @@ -68,21 +68,15 @@ void WinRtDebugSupport::finish() } RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runConfig, - RunMode mode, + Core::Id mode, QString *errorMessage) { // FIXME: This is just working for local debugging; using namespace Debugger; DebuggerStartParameters params; params.startMode = AttachExternal; - params.languages |= CppLanguage; - params.breakOnMain = mode == DebugRunModeWithBreakOnMain; // The first Thread needs to be resumed manually. params.commandsAfterConnect = "~0 m"; - Kit *kit = runConfig->target()->kit(); - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - if (ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - params.toolChainAbi = tc->targetAbi(); QFileInfo debuggerHelper(QCoreApplication::applicationDirPath() + QLatin1String("/winrtdebughelper.exe")); @@ -125,9 +119,8 @@ RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runC return 0; } server.close(); - params.runConfiguration = runConfig; Debugger::DebuggerRunControl *debugRunControl - = createDebuggerRunControl(params, errorMessage); + = createDebuggerRunControl(params, runConfig, errorMessage, mode); runner->setRunControl(debugRunControl); new WinRtDebugSupport(debugRunControl, runner); return debugRunControl; diff --git a/src/plugins/winrt/winrtdebugsupport.h b/src/plugins/winrt/winrtdebugsupport.h index 4b5d8d5cf3e..f92281beb27 100644 --- a/src/plugins/winrt/winrtdebugsupport.h +++ b/src/plugins/winrt/winrtdebugsupport.h @@ -47,7 +47,7 @@ class WinRtDebugSupport : public QObject Q_OBJECT public: static ProjectExplorer::RunControl *createDebugRunControl(WinRtRunConfiguration *runConfig, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); ~WinRtDebugSupport(); diff --git a/src/plugins/winrt/winrtqtversion.cpp b/src/plugins/winrt/winrtqtversion.cpp index b49c8bff4e4..07728e68452 100644 --- a/src/plugins/winrt/winrtqtversion.cpp +++ b/src/plugins/winrt/winrtqtversion.cpp @@ -69,7 +69,7 @@ Core::FeatureSet WinRtQtVersion::availableFeatures() const Core::FeatureSet features = QtSupport::BaseQtVersion::availableFeatures(); features |= Core::FeatureSet(QtSupport::Constants::FEATURE_MOBILE); features.remove(Core::Feature(QtSupport::Constants::FEATURE_QT_CONSOLE)); - features.remove(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK_1)); + features.remove(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1)); features.remove(Core::Feature(QtSupport::Constants::FEATURE_QT_WEBKIT)); return features; } diff --git a/src/plugins/winrt/winrtruncontrol.cpp b/src/plugins/winrt/winrtruncontrol.cpp index 6e0b41d0f4e..fed9db96350 100644 --- a/src/plugins/winrt/winrtruncontrol.cpp +++ b/src/plugins/winrt/winrtruncontrol.cpp @@ -48,13 +48,13 @@ using ProjectExplorer::DeviceKitInformation; using ProjectExplorer::IDevice; using ProjectExplorer::RunControl; -using ProjectExplorer::RunMode; +using Core::Id; using ProjectExplorer::Target; namespace WinRt { namespace Internal { -WinRtRunControl::WinRtRunControl(WinRtRunConfiguration *runConfiguration, RunMode mode) +WinRtRunControl::WinRtRunControl(WinRtRunConfiguration *runConfiguration, Core::Id mode) : RunControl(runConfiguration, mode) , m_runConfiguration(runConfiguration) , m_state(StoppedState) diff --git a/src/plugins/winrt/winrtruncontrol.h b/src/plugins/winrt/winrtruncontrol.h index 9b63fe89c32..ed25928687b 100644 --- a/src/plugins/winrt/winrtruncontrol.h +++ b/src/plugins/winrt/winrtruncontrol.h @@ -54,7 +54,7 @@ class WinRtRunControl : public ProjectExplorer::RunControl { Q_OBJECT public: - explicit WinRtRunControl(WinRtRunConfiguration *runConfiguration, ProjectExplorer::RunMode mode); + explicit WinRtRunControl(WinRtRunConfiguration *runConfiguration, Core::Id mode); void start(); StopResult stop(); diff --git a/src/plugins/winrt/winrtrunfactories.cpp b/src/plugins/winrt/winrtrunfactories.cpp index 14336fb5306..859ca9c1b44 100644 --- a/src/plugins/winrt/winrtrunfactories.cpp +++ b/src/plugins/winrt/winrtrunfactories.cpp @@ -137,7 +137,7 @@ WinRtRunControlFactory::WinRtRunControlFactory() } bool WinRtRunControlFactory::canRun(RunConfiguration *runConfiguration, - RunMode mode) const + Core::Id mode) const { if (!runConfiguration) return false; @@ -145,35 +145,32 @@ bool WinRtRunControlFactory::canRun(RunConfiguration *runConfiguration, if (!device) return false; - switch (mode) { - case DebugRunMode: - case DebugRunModeWithBreakOnMain: + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE + || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) { if (device->type() != Constants::WINRT_DEVICE_TYPE_LOCAL) return false; - // fall through - case NormalRunMode: return qobject_cast(runConfiguration); - default: - return false; } + + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) + return qobject_cast(runConfiguration); + + return false; } RunControl *WinRtRunControlFactory::create( - RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) + RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { WinRtRunConfiguration *rc = qobject_cast(runConfiguration); QTC_ASSERT(rc, return 0); - switch (mode) { - case NormalRunMode: + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) return new WinRtRunControl(rc, mode); - case DebugRunMode: - case DebugRunModeWithBreakOnMain: + + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) return WinRtDebugSupport::createDebugRunControl(rc, mode, errorMessage); - default: - break; - } - *errorMessage = tr("Unsupported run mode %1.").arg(mode); + + *errorMessage = tr("Unsupported run mode %1.").arg(mode.toString()); return 0; } diff --git a/src/plugins/winrt/winrtrunfactories.h b/src/plugins/winrt/winrtrunfactories.h index 0e310e88d78..b77868bab34 100644 --- a/src/plugins/winrt/winrtrunfactories.h +++ b/src/plugins/winrt/winrtrunfactories.h @@ -64,9 +64,9 @@ class WinRtRunControlFactory : public ProjectExplorer::IRunControlFactory public: WinRtRunControlFactory(); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const; + Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, QString *errorMessage); + Core::Id mode, QString *errorMessage); QString displayName() const; }; diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index 5ed6ed916cb..4717c5fc228 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -166,6 +166,7 @@ private slots: void pointer_to_function_1(); void template_instance_1(); + void explicit_instantiation_1(); void expression_under_cursor_1(); @@ -523,6 +524,25 @@ void tst_Semantic::template_instance_1() QCOMPARE(genDecl, QString::fromLatin1("void (const int &)")); } +void tst_Semantic::explicit_instantiation_1() +{ + QSharedPointer doc = document("template class basic_string;"); + QCOMPARE(doc->errorCount, 0U); + QCOMPARE(doc->globals->memberCount(), 1U); + + ExplicitInstantiation *inst = doc->globals->memberAt(0)->asExplicitInstantiation(); + QVERIFY(inst); + + ForwardClassDeclaration *fwd = inst->memberAt(0)->asForwardClassDeclaration(); + QVERIFY(fwd); + + QVERIFY(inst->name()->match(fwd->name())); + + Overview oo; + const QString name = oo.prettyName(inst->name()); + QCOMPARE(name, QString::fromLatin1("basic_string")); +} + void tst_Semantic::expression_under_cursor_1() { const QString plainText = "void *ptr = foo(10, bar"; diff --git a/tests/auto/valgrind/memcheck/parsertests.cpp b/tests/auto/valgrind/memcheck/parsertests.cpp index 61db42836dd..9a6dc218d1a 100644 --- a/tests/auto/valgrind/memcheck/parsertests.cpp +++ b/tests/auto/valgrind/memcheck/parsertests.cpp @@ -70,7 +70,7 @@ QT_END_NAMESPACE void dumpFrame(const Frame &f) { - qDebug() << f.instructionPointer() << f.directory() << f.file() << f.functionName() + qDebug() << f.instructionPointer() << f.directory() << f.fileName() << f.functionName() << f.line() << f.object(); } @@ -168,14 +168,14 @@ void ParserTests::testHelgrindSample1() frame11.setObject(QLatin1String("/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so")); frame11.setFunctionName(QLatin1String("QMutex::lock()")); frame11.setDirectory(QLatin1String("/build/buildd/valgrind-3.6.0~svn20100212/helgrind")); - frame11.setFile(QLatin1String("hg_intercepts.c")); + frame11.setFileName(QLatin1String("hg_intercepts.c")); frame11.setLine(1988); Frame frame12; frame12.setInstructionPointer(0x72E57EE); frame12.setObject(QLatin1String("/home/frank/local/qt4-4.6.3-shared-debug/lib/libQtCore.so.4.6.3")); frame12.setFunctionName(QLatin1String("QMutexLocker::relock()")); frame12.setDirectory(QLatin1String("/home/frank/source/tarballs/qt-4.6.3-build/src/corelib/../../include/QtCore/../../src/corelib/thread")); - frame12.setFile(QLatin1String("qmutex.h")); + frame12.setFileName(QLatin1String("qmutex.h")); frame12.setLine(120); stack1.setFrames(QVector() << frame11 << frame12); @@ -186,14 +186,14 @@ void ParserTests::testHelgrindSample1() frame21.setObject(QLatin1String("/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so")); frame21.setFunctionName(QLatin1String("QMutex::lock()")); frame21.setDirectory(QLatin1String("/build/buildd/valgrind-3.6.0~svn20100212/helgrind")); - frame21.setFile(QLatin1String("hg_intercepts.c")); + frame21.setFileName(QLatin1String("hg_intercepts.c")); frame21.setLine(1989); Frame frame22; frame22.setInstructionPointer(0x72E57EE); frame22.setObject(QLatin1String("/home/frank/local/qt4-4.6.3-shared-debug/lib/libQtCore.so.4.6.3")); frame22.setFunctionName(QLatin1String("QMutexLocker::relock()")); frame22.setDirectory(QLatin1String("/home/frank/source/tarballs/qt-4.6.3-build/src/corelib/../../include/QtCore/../../src/corelib/thread")); - frame22.setFile(QLatin1String("qmutex.h")); + frame22.setFileName(QLatin1String("qmutex.h")); frame22.setLine(121); stack2.setFrames(QVector() << frame21 << frame22); @@ -204,14 +204,14 @@ void ParserTests::testHelgrindSample1() frame31.setObject(QLatin1String("/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so")); frame31.setFunctionName(QLatin1String("QMutex::lock()")); frame31.setDirectory(QLatin1String("/build/buildd/valgrind-3.6.0~svn20100212/helgrind")); - frame31.setFile(QLatin1String("hg_intercepts.c")); + frame31.setFileName(QLatin1String("hg_intercepts.c")); frame31.setLine(1990); Frame frame32; frame32.setInstructionPointer(0x72E57EE); frame32.setObject(QLatin1String("/home/frank/local/qt4-4.6.3-shared-debug/lib/libQtCore.so.4.6.3")); frame32.setFunctionName(QLatin1String("QMutexLocker::relock()")); frame32.setDirectory(QLatin1String("/home/frank/source/tarballs/qt-4.6.3-build/src/corelib/../../include/QtCore/../../src/corelib/thread")); - frame32.setFile(QLatin1String("qmutex.h")); + frame32.setFileName(QLatin1String("qmutex.h")); frame32.setLine(122); stack3.setFrames(QVector() << frame31 << frame32); @@ -260,7 +260,7 @@ void ParserTests::testMemcheckSample1() f1.setObject(QLatin1String("/usr/lib/libQtGui.so.4.7.0")); f1.setFunctionName(QLatin1String("QFrame::frameStyle() const")); f1.setDirectory(QLatin1String("/build/buildd/qt4-x11-4.7.0/src/gui/widgets")); - f1.setFile(QLatin1String("qframe.cpp")); + f1.setFileName(QLatin1String("qframe.cpp")); f1.setLine(252); Frame f2; f2.setInstructionPointer(0x118F2AF7); @@ -270,13 +270,13 @@ void ParserTests::testMemcheckSample1() f3.setObject(QLatin1String("/usr/lib/libQtGui.so.4.7.0")); f3.setFunctionName(QLatin1String("QWidget::event(QEvent*)")); f3.setDirectory(QLatin1String("/build/buildd/qt4-x11-4.7.0/src/gui/kernel")); - f3.setFile(QLatin1String("qwidget.cpp")); + f3.setFileName(QLatin1String("qwidget.cpp")); f3.setLine(8273); Frame f4; f4.setInstructionPointer(0x6A2B6EB); f4.setObject(QLatin1String("/usr/lib/libQtGui.so.4.7.0")); f4.setDirectory(QLatin1String("/build/buildd/qt4-x11-4.7.0/src/gui/kernel")); - f4.setFile(QLatin1String("qapplication.cpp")); + f4.setFileName(QLatin1String("qapplication.cpp")); f4.setFunctionName(QLatin1String("QApplicationPrivate::notify_helper(QObject*, QEvent*)")); f4.setLine(4396); Stack s1; diff --git a/tests/auto/valgrind/memcheck/testrunner.cpp b/tests/auto/valgrind/memcheck/testrunner.cpp index 32c48cf426a..cf11e6bfed5 100644 --- a/tests/auto/valgrind/memcheck/testrunner.cpp +++ b/tests/auto/valgrind/memcheck/testrunner.cpp @@ -180,7 +180,7 @@ void TestRunner::testLeak1() QCOMPARE(frame.line(), 5 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak1")); } } @@ -214,7 +214,7 @@ void TestRunner::testLeak2() QCOMPARE(frame.line(), 7 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak2")); } else { QCOMPARE(frame.functionName(), QLatin1String("(below main)")); @@ -252,7 +252,7 @@ void TestRunner::testLeak3() QCOMPARE(frame.line(), 7 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak3")); } else { QCOMPARE(frame.functionName(), QLatin1String("(below main)")); @@ -293,7 +293,7 @@ void TestRunner::testLeak4() QCOMPARE(frame.line(), 6 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } { @@ -302,7 +302,7 @@ void TestRunner::testLeak4() QCOMPARE(frame.line(), 14 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -332,7 +332,7 @@ void TestRunner::testLeak4() QCOMPARE(frame.line(), 14 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -361,7 +361,7 @@ void TestRunner::uninit1() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } //BEGIN second stack @@ -375,7 +375,7 @@ void TestRunner::uninit1() QCOMPARE(frame.line(), 2 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -406,7 +406,7 @@ void TestRunner::uninit2() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } //BEGIN second stack @@ -420,7 +420,7 @@ void TestRunner::uninit2() QCOMPARE(frame.line(), 2 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -439,7 +439,7 @@ void TestRunner::uninit2() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -470,7 +470,7 @@ void TestRunner::uninit3() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } //BEGIN second stack @@ -484,7 +484,7 @@ void TestRunner::uninit3() QCOMPARE(frame.line(), 2 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -503,7 +503,7 @@ void TestRunner::uninit3() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -562,7 +562,7 @@ void TestRunner::syscall() QCOMPARE(frame.line(), 2 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -595,7 +595,7 @@ void TestRunner::free1() QCOMPARE(frame.line(), 7 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -615,7 +615,7 @@ void TestRunner::free1() QCOMPARE(frame.line(), 6 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -649,7 +649,7 @@ void TestRunner::free2() QCOMPARE(frame.line(), 6 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -673,7 +673,7 @@ void TestRunner::free2() QCOMPARE(frame.line(), 5 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -733,7 +733,7 @@ void TestRunner::overlap() QCOMPARE(frame.line(), 6 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } diff --git a/tests/manual/ssh/errorhandling/main.cpp b/tests/manual/ssh/errorhandling/main.cpp index 983617bcdc9..f5fa4088b5a 100644 --- a/tests/manual/ssh/errorhandling/main.cpp +++ b/tests/manual/ssh/errorhandling/main.cpp @@ -38,6 +38,8 @@ #include #include +#include + using namespace QSsh; class Test : public QObject { @@ -117,27 +119,27 @@ private slots: void handleConnected() { qDebug("Error: Received unexpected connected() signal."); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void handleDisconnected() { qDebug("Error: Received unexpected disconnected() signal."); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void handleDataAvailable(const QString &msg) { qDebug("Error: Received unexpected dataAvailable() signal. " "Message was: '%s'.", qPrintable(msg)); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void handleError(QSsh::SshError error) { if (m_testSet.isEmpty()) { qDebug("Error: Received error %d, but no test was running.", error); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } const TestItem testItem = m_testSet.takeFirst(); @@ -151,7 +153,7 @@ private slots: } } else { qDebug("Received unexpected error %d.", error); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } } @@ -159,7 +161,7 @@ private slots: { if (m_testSet.isEmpty()) { qDebug("Error: timeout, but no test was running."); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } const TestItem testItem = m_testSet.takeFirst(); qDebug("Error: The following test timed out: %s", testItem.description); diff --git a/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp b/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp index abe8a67091e..5619edf242d 100644 --- a/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp +++ b/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp @@ -82,14 +82,14 @@ void RemoteProcessTest::handleConnectionError() ? m_sshConnection->errorString() : m_remoteRunner->lastConnectionErrorString(); std::cerr << "Error: Connection failure (" << qPrintable(error) << ")." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void RemoteProcessTest::handleProcessStarted() { if (m_started) { std::cerr << "Error: Received started() signal again." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else { m_started = true; if (m_state == TestingCrash) { @@ -109,11 +109,11 @@ void RemoteProcessTest::handleProcessStdout() if (!m_started) { std::cerr << "Error: Remote output from non-started process." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else if (m_state != TestingSuccess && m_state != TestingTerminal) { std::cerr << "Error: Got remote standard output in state " << m_state << "." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else { m_remoteStdout += m_remoteRunner->readAllStandardOutput(); } @@ -124,11 +124,11 @@ void RemoteProcessTest::handleProcessStderr() if (!m_started) { std::cerr << "Error: Remote error output from non-started process." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else if (m_state == TestingSuccess) { std::cerr << "Error: Unexpected remote standard error output." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else { m_remoteStderr += m_remoteRunner->readAllStandardError(); } @@ -140,7 +140,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) case SshRemoteProcess::NormalExit: if (!m_started) { std::cerr << "Error: Process exited without starting." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } switch (m_state) { @@ -149,13 +149,13 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) if (exitCode != 0) { std::cerr << "Error: exit code is " << exitCode << ", expected zero." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } if (m_remoteStdout.isEmpty()) { std::cerr << "Error: Command did not produce output." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } @@ -171,12 +171,12 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) if (exitCode == 0) { std::cerr << "Error: exit code is zero, expected non-zero." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } if (m_remoteStderr.isEmpty()) { std::cerr << "Error: Command did not produce error output." << std::flush; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } @@ -191,7 +191,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) if (m_remoteRunner->processExitCode() == 0) { std::cerr << "Error: Successful exit from process that was " "supposed to crash." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else { // Some shells (e.g. mksh) don't report "killed", but just a non-zero exit code. handleSuccessfulCrashTest(); @@ -202,13 +202,13 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) if (exitCode != 0) { std::cerr << "Error: exit code is " << exitCode << ", expected zero." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } if (m_remoteStdout.isEmpty()) { std::cerr << "Error: Command did not produce output." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } std::cout << "Ok.\nTesting I/O device functionality... " << std::flush; @@ -256,7 +256,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) } else { std::cerr << "Error: Process failed to start." << std::endl; } - qApp->quit(); + qApp->exit(EXIT_FAILURE); break; case SshRemoteProcess::CrashExit: switch (m_state) { @@ -268,7 +268,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) break; default: std::cerr << "Error: Unexpected crash." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } } @@ -277,7 +277,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) void RemoteProcessTest::handleTimeout() { std::cerr << "Error: Timeout waiting for progress." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void RemoteProcessTest::handleConnected() @@ -305,7 +305,7 @@ void RemoteProcessTest::handleReadyRead() if (data != testString()) { std::cerr << "Testing of QIODevice functionality failed: Expected '" << qPrintable(testString()) << "', got '" << qPrintable(data) << "'." << std::endl; - qApp->exit(1); + qApp->exit(EXIT_FAILURE); } SshRemoteProcessRunner * const killer = new SshRemoteProcessRunner(this); killer->run("pkill -9 cat", m_sshParams); diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py index 7e8830d0902..ff013241c6f 100644 --- a/tests/system/shared/classes.py +++ b/tests/system/shared/classes.py @@ -172,3 +172,33 @@ class LibType: if libType == LibType.QT_PLUGIN: return "Qt Plugin" return None + +class Qt5Path: + DOCS = 0 + EXAMPLES = 1 + + @staticmethod + def getPaths(pathSpec): + if pathSpec == Qt5Path.DOCS: + path52 = "/doc" + path53 = "/Docs/Qt-5.3" + path54 = "/Docs/Qt-5.4" + elif pathSpec == Qt5Path.EXAMPLES: + path52 = "/examples" + path53 = "/Examples/Qt-5.3" + path54 = "/Examples/Qt-5.4" + else: + test.fatal("Unknown pathSpec given: %s" % str(pathSpec)) + return [] + if platform.system() in ('Microsoft', 'Windows'): + return ["C:/Qt/Qt5.2.1/5.2.1/msvc2010" + path52, + "C:/Qt/Qt5.3.1" + path53, "C:/Qt/Qt5.4.1" + path54] + elif platform.system() == 'Linux': + if __is64BitOS__(): + return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/gcc_64" + path52, + "~/Qt5.3.1" + path53, "~/Qt5.4.1" + path54]) + return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/gcc" + path52, + "~/Qt5.3.1" + path53, "~/Qt5.4.1" + path54]) + else: + return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/clang_64" + path52, + "~/Qt5.3.1" + path53]) diff --git a/tests/system/suite_APTW/tst_APTW03/test.py b/tests/system/suite_APTW/tst_APTW03/test.py index ce58243a01d..fa843f79e16 100644 --- a/tests/system/suite_APTW/tst_APTW03/test.py +++ b/tests/system/suite_APTW/tst_APTW03/test.py @@ -56,7 +56,7 @@ def handleInsertVirtualFunctions(expected): "Verifying whether all expected functions have been found.") selectFromCombo("{container={title='Insertion options:' type='QGroupBox' unnamed='1' " - " visible='1'} type='QComboBox' unnamed='1' visible='1'}", + " visible='1'} occurrence='2' type='QComboBox' unnamed='1' visible='1'}", "Insert definitions in implementation file") clickButton("{text='OK' type='QPushButton' unnamed='1' visible='1'}") @@ -88,11 +88,10 @@ def main(): targets = Targets.desktopTargetClasses() & ~Targets.DESKTOP_474_GCC checkedTargets, projectName, className = createNewQtPlugin(tempDir(), "SampleApp3", "MyPlugin", target=targets) - is12251Open = JIRA.isBugStillOpen(12251) virtualFunctionsAdded = False for kit, config in iterateBuildConfigs(len(checkedTargets), "Debug"): verifyBuildConfig(len(checkedTargets), kit, config, True, True) - if (virtualFunctionsAdded and is12251Open and platform.system() in ('Microsoft', 'Windows') + if (virtualFunctionsAdded and platform.system() in ('Microsoft', 'Windows') and "480" in Targets.getStringForTarget(checkedTargets[kit])): test.warning("Skipping building of Qt4.8 targets because of QTCREATORBUG-12251.") continue @@ -131,7 +130,7 @@ def main(): addReturn(editor, "QObject \*%s::create.*" % className, "0") virtualFunctionsAdded = True invokeMenuItem('File', 'Save All') - if (is12251Open and platform.system() in ('Microsoft', 'Windows') + if (platform.system() in ('Microsoft', 'Windows') # QTCREATORBUG-12251 and "480" in Targets.getStringForTarget(checkedTargets[kit])): test.warning("Skipping building of Qt4.8 targets because of QTCREATORBUG-12251.") continue diff --git a/tests/system/suite_CSUP/tst_CSUP01/test.py b/tests/system/suite_CSUP/tst_CSUP01/test.py index 4769d78a571..137c958fd5a 100644 --- a/tests/system/suite_CSUP/tst_CSUP01/test.py +++ b/tests/system/suite_CSUP/tst_CSUP01/test.py @@ -63,7 +63,7 @@ def main(): "Step 2: Verifying if: .cpp file is opened in Edit mode.") # Step 3: Insert text "re" to new line in Editor mode and press Ctrl+Space. editorWidget = findObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget") - if not placeCursorToLine(editorWidget, "QApplication app(argc, argv);"): + if not placeCursorToLine(editorWidget, "QGuiApplication app(argc, argv);"): earlyExit("Did not find first line in function block.") return type(editorWidget, "") diff --git a/tests/system/suite_CSUP/tst_CSUP03/test.py b/tests/system/suite_CSUP/tst_CSUP03/test.py index 2c6dc9b854e..074065babb8 100644 --- a/tests/system/suite_CSUP/tst_CSUP03/test.py +++ b/tests/system/suite_CSUP/tst_CSUP03/test.py @@ -30,10 +30,11 @@ source("../../shared/qtcreator.py") -inputDialog = "{type='QInputDialog' unnamed='1' visible='1'}" +inputDialog = "{type='QDialog' unnamed='1' visible='1' windowTitle='Extract Function Refactoring'}" def revertMainCpp(): invokeMenuItem('File', 'Revert "main.cpp" to Saved') + waitFor("object.exists(':Revert to Saved_QMessageBox')", 1000) clickButton(waitForObject(":Revert to Saved.Proceed_QPushButton")) def constructExpectedCode(original, codeLines, funcSuffix): @@ -109,9 +110,9 @@ def main(): markText(editor, "Right", 2) snooze(1) # avoid timing issue with the parser invokeContextMenuItem(editor, 'Refactor', 'Extract Function') - funcEdit = waitForObject("{buddy={text='Enter function name' type='QLabel' unnamed='1' " - "visible='1' window=%s} type='QLineEdit' unnamed='1' visible='1'}" - % inputDialog) + funcEdit = waitForObject("{buddy={text='Function name' type='QLabel' unnamed='1' " + "visible='1' window=%s} type='Utils::FancyLineEdit' " + "unnamed='1' visible='1'}" % inputDialog) replaceEditorContent(funcEdit, "myFunc%s" % funcSuffix) clickButton(waitForObject("{text='OK' type='QPushButton' unnamed='1' visible='1' window=%s}" % inputDialog)) diff --git a/tests/system/suite_HELP/tst_HELP05/test.py b/tests/system/suite_HELP/tst_HELP05/test.py index 5ec349e0d87..84325e251d1 100755 --- a/tests/system/suite_HELP/tst_HELP05/test.py +++ b/tests/system/suite_HELP/tst_HELP05/test.py @@ -52,14 +52,17 @@ def main(): startApplication("qtcreator" + SettingsPath) if not startedWithoutPluginError(): return - addHelpDocumentation([os.path.join(sdkPath, "Documentation", "qt.qch")]) + qchs = [] + for p in Qt5Path.getPaths(Qt5Path.DOCS): + qchs.append(os.path.join(p, "qtquick.qch")) + addHelpDocumentation(qchs) # create qt quick application createNewQtQuickApplication(tempDir(), "SampleApp") # verify Rectangle help - verifyInteractiveQMLHelp("Rectangle {", "QML Rectangle Element") + verifyInteractiveQMLHelp("Window {", "Window QML Type") # go back to edit mode switchViewTo(ViewConstants.EDIT) # verify MouseArea help - verifyInteractiveQMLHelp("MouseArea {", "QML MouseArea Element") + verifyInteractiveQMLHelp("MouseArea {", "MouseArea QML Type") # exit invokeMenuItem("File","Exit") diff --git a/tests/system/suite_QMLS/tst_QMLS07/test.py b/tests/system/suite_QMLS/tst_QMLS07/test.py index 55e75ff978c..eaf86465c80 100644 --- a/tests/system/suite_QMLS/tst_QMLS07/test.py +++ b/tests/system/suite_QMLS/tst_QMLS07/test.py @@ -31,7 +31,7 @@ source("../shared/qmls.py") def main(): - editorArea = startQtCreatorWithNewAppAtQMLEditor(tempDir(), "SampleApp", "Rectangle {") + editorArea = startQtCreatorWithNewAppAtQMLEditor(tempDir(), "SampleApp", "Window {") if not editorArea: return type(editorArea, "") diff --git a/tests/system/suite_QMLS/tst_QMLS08/test.py b/tests/system/suite_QMLS/tst_QMLS08/test.py index 6ee4837b98e..31cd705f55e 100644 --- a/tests/system/suite_QMLS/tst_QMLS08/test.py +++ b/tests/system/suite_QMLS/tst_QMLS08/test.py @@ -45,7 +45,7 @@ def verifyNextLineIndented(editorArea, expectedIndentation): def verifyIndentation(editorArea): #verify indentation - if not placeCursorToLine(editorArea, "id: rect"): + if not placeCursorToLine(editorArea, "id: wdw"): invokeMenuItem("File", "Save All") invokeMenuItem("File", "Exit") return False @@ -60,13 +60,13 @@ def main(): if not editorArea: return # prepare code for test - insert unindented code - lines = ['id: rect', 'property bool random: true', 'Text{', - 'anchors.bottom:parent.bottom', 'text: rect.random ? getRandom() : "I\'m fixed."', + lines = ['id: wdw', 'property bool random: true', 'Text {', + 'anchors.bottom: parent.bottom', 'text: wdw.random ? getRandom() : "I\'m fixed."', '', 'function getRandom(){', 'var result="I\'m random: ";', 'var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";', 'for(var i=0;i<8;++i)', 'result += chars.charAt(Math.floor(Math.random() * chars.length));', 'return result + ".";'] - if not placeCursorToLine(editorArea, "Rectangle {"): + if not placeCursorToLine(editorArea, "Window {"): invokeMenuItem("File", "Exit") return type(editorArea, "") diff --git a/tests/system/suite_WELP/tst_WELP03/test.py b/tests/system/suite_WELP/tst_WELP03/test.py index 3e15c8f4249..286be802dcd 100644 --- a/tests/system/suite_WELP/tst_WELP03/test.py +++ b/tests/system/suite_WELP/tst_WELP03/test.py @@ -31,36 +31,6 @@ source("../../shared/qtcreator.py") source("../../shared/suites_qtta.py") -class Qt5Path: - DOCS = 0 - EXAMPLES = 1 - - @staticmethod - def getPaths(pathSpec): - if pathSpec == Qt5Path.DOCS: - path52 = "/doc" - path53 = "/Docs/Qt-5.3" - path54 = "/Docs/Qt-5.4" - elif pathSpec == Qt5Path.EXAMPLES: - path52 = "/examples" - path53 = "/Examples/Qt-5.3" - path54 = "/Examples/Qt-5.4" - else: - test.fatal("Unknown pathSpec given: %s" % str(pathSpec)) - return [] - if platform.system() in ('Microsoft', 'Windows'): - return ["C:/Qt/Qt5.2.1/5.2.1/msvc2010" + path52, - "C:/Qt/Qt5.3.1" + path53, "C:/Qt/Qt5.4.1" + path54] - elif platform.system() == 'Linux': - if __is64BitOS__(): - return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/gcc_64" + path52, - "~/Qt5.3.1" + path53, "~/Qt5.4.1" + path54]) - return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/gcc" + path52, - "~/Qt5.3.1" + path53, "~/Qt5.4.1" + path54]) - else: - return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/clang_64" + path52, - "~/Qt5.3.1" + path53]) - def handlePackagingMessageBoxes(): if platform.system() == "Darwin": messageBox = "{type='QMessageBox' unnamed='1' visible='1'}" diff --git a/tests/system/suite_editors/tst_qml_indent/test.py b/tests/system/suite_editors/tst_qml_indent/test.py index 51b864d1a71..be0d8968f95 100644 --- a/tests/system/suite_editors/tst_qml_indent/test.py +++ b/tests/system/suite_editors/tst_qml_indent/test.py @@ -37,11 +37,8 @@ def main(): # using a temporary directory won't mess up a potentially existing createNewQtQuickApplication(tempDir(), "untitled") originalText = prepareQmlFile() - if not originalText: - invokeMenuItem("File", "Save All") - invokeMenuItem("File", "Exit") - return - testReIndent(originalText) + if originalText: + testReIndent(originalText) invokeMenuItem("File", "Save All") invokeMenuItem("File", "Exit") @@ -64,8 +61,9 @@ def prepareQmlFile(): markText(editor, "End") else: markText(editor, "Ctrl+End") - # unmark the last line - type(editor, "") + # unmark the 2 last lines + for _ in range(2): + type(editor, "") type(editor, "") for j in range(10): type(editor, "") diff --git a/tests/unit/unittest/lineprefixertest.cpp b/tests/unit/unittest/lineprefixertest.cpp new file mode 100644 index 00000000000..6f205e924de --- /dev/null +++ b/tests/unit/unittest/lineprefixertest.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, 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 +#include + +#include +#include +#include + +namespace { + +QByteArray runPrefixer(QList inputChunks) +{ + QByteArray actualOutput; + ClangBackEnd::LinePrefixer prefixer("PREFIX "); + foreach (const QByteArray &chunk, inputChunks) + actualOutput += prefixer.prefix(chunk); + return actualOutput; +} + +TEST(LinePrefixer, OneChunkEndsWithNewline) +{ + const QList inputChunks { "hello\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n")); +} + +TEST(LinePrefixer, OneChunkEndsWithoutNewline) +{ + const QList inputChunks { "hello" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello")); +} + +TEST(LinePrefixer, OneChunkStartsWithNewline) +{ + const QList inputChunks { "\nhello" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX \n" + "PREFIX hello")); +} + +TEST(LinePrefixer, OneChunkStartsAndEndsWithNewline) +{ + const QList inputChunks { "\nhello\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX \n" + "PREFIX hello\n")); +} + +TEST(LinePrefixer, OneChunkEndsWithExtraNewline) +{ + const QList inputChunks { "hello\n\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n" + "PREFIX \n")); +} + +TEST(LinePrefixer, OneChunkEndsWithTwoExtraNewlines) +{ + const QList inputChunks { "hello\n\n\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n" + "PREFIX \n" + "PREFIX \n")); +} + +TEST(LinePrefixer, ChunkWithoutNewlineAndChunkWithNewline) +{ + const QList inputChunks { "hello", "\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n")); +} + +TEST(LinePrefixer, ChunkWithoutNewlineAndChunkWithTwoNewlines) +{ + const QList inputChunks { "hello", "\n\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n" + "PREFIX \n")); +} + +TEST(LinePrefixer, ChunkWithTwoNewlinesAndChunkWithoutNewline) +{ + const QList inputChunks { "\n\n", "hello" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX \n" + "PREFIX \n" + "PREFIX hello")); +} + +} // anonymous namespace diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index a7cab75de44..8bdec64110a 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -56,7 +56,8 @@ SOURCES += main.cpp \ projecttest.cpp \ clangipcservertest.cpp \ translationunitstest.cpp \ - completionchunkstotextconvertertest.cpp + completionchunkstotextconvertertest.cpp \ + lineprefixertest.cpp HEADERS += \ gtest-qt-printing.h \