Merge remote-tracking branch 'origin/3.5'

Change-Id: Ied20c9cebbb51252a4173fb8189c357006b45e1b
This commit is contained in:
Eike Ziller
2015-07-01 14:15:50 +02:00
305 changed files with 5491 additions and 3285 deletions

View File

@@ -79,8 +79,10 @@ QML Profiler
C++ Support C++ Support
* Added separate icon for structs * 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 * Fixed *Convert to Stack Variable* refactoring action for empty
initializer lists (QTCREATORBUG-14279) initializer lists (QTCREATORBUG-14279)
* Fixed misplaced newlines of refactoring actions (QTCREATORBUG-13872)
* Fixed expanding items in class view with double-click * Fixed expanding items in class view with double-click
(QTCREATORBUG-2536) (QTCREATORBUG-2536)
* Fixed code folding issues after missing closing braces * Fixed code folding issues after missing closing braces
@@ -93,10 +95,7 @@ C++ Support
* Partially fixed STL containers (QTCREATORBUG-8937, QTCREATORBUG-8922) * Partially fixed STL containers (QTCREATORBUG-8937, QTCREATORBUG-8922)
* GCC implementation of `std::map`, `std::unique_ptr` (and other pointer wrappers) * GCC implementation of `std::map`, `std::unique_ptr` (and other pointer wrappers)
and `std::vector` are known to work and `std::vector` are known to work
* Known limitations:
* MSVC implementation is not supported * MSVC implementation is not supported
* types that contain a typedef for `pointer` are not supported
(For example: `std::unique_ptr<std::string>`)
QML Support QML Support
@@ -119,6 +118,10 @@ Todo
* Added option to excluding file patterns from parsing * Added option to excluding file patterns from parsing
Beautifier
* Added option to format only selected lines with Uncrustify (`--frag`)
Platform Specific Platform Specific
Windows Windows

View File

@@ -8,7 +8,8 @@
<InstallerWindowIcon>logo.png</InstallerWindowIcon> <InstallerWindowIcon>logo.png</InstallerWindowIcon>
<Watermark>watermark.png</Watermark> <Watermark>watermark.png</Watermark>
<UninstallerName>QtCreatorUninstaller</UninstallerName> <WizardDefaultHeight>520</WizardDefaultHeight>
<MaintenanceToolName>QtCreatorUninstaller</MaintenanceToolName>
<!-- @homeDir@ and @rootDir@ are some of the supported vars --> <!-- @homeDir@ and @rootDir@ are some of the supported vars -->
<TargetDir>@homeDir@/qtcreator-{version}</TargetDir> <TargetDir>@homeDir@/qtcreator-{version}</TargetDir>
<AdminTargetDir>/opt/qtcreator-{version}</AdminTargetDir> <AdminTargetDir>/opt/qtcreator-{version}</AdminTargetDir>

View File

@@ -8,7 +8,8 @@
<InstallerWindowIcon>logo.png</InstallerWindowIcon> <InstallerWindowIcon>logo.png</InstallerWindowIcon>
<Background>background.png</Background> <Background>background.png</Background>
<UninstallerName>Uninstall Qt Creator</UninstallerName> <WizardDefaultHeight>560</WizardDefaultHeight>
<MaintenanceToolName>Uninstall Qt Creator</MaintenanceToolName>
<!-- @homeDir@ and @rootDir@ are some of the supported vars --> <!-- @homeDir@ and @rootDir@ are some of the supported vars -->
<TargetDir>@homeDir@/Applications/Qt Creator {version}</TargetDir> <TargetDir>@homeDir@/Applications/Qt Creator {version}</TargetDir>
<AllowSpaceInPath>true</AllowSpaceInPath> <AllowSpaceInPath>true</AllowSpaceInPath>

View File

@@ -8,7 +8,8 @@
<InstallerWindowIcon>logo.png</InstallerWindowIcon> <InstallerWindowIcon>logo.png</InstallerWindowIcon>
<Watermark>watermark.png</Watermark> <Watermark>watermark.png</Watermark>
<UninstallerName>QtCreatorUninst</UninstallerName> <WizardDefaultHeight>560</WizardDefaultHeight>
<MaintenanceToolName>QtCreatorUninst</MaintenanceToolName>
<!-- @homeDir@ and @rootDir@ are some of the supported vars --> <!-- @homeDir@ and @rootDir@ are some of the supported vars -->
<TargetDir>@rootDir@/Qt/qtcreator-{version}</TargetDir> <TargetDir>@rootDir@/Qt/qtcreator-{version}</TargetDir>
</Installer> </Installer>

View File

@@ -566,6 +566,7 @@
\li As an exception, if there is only a single class declaration inside \li As an exception, if there is only a single class declaration inside
the namespace, all can go on a single line: the namespace, all can go on a single line:
\code \code
namespace MyPlugin { class MyClass; } namespace MyPlugin { class MyClass; }
\endcode \endcode

View File

@@ -20,29 +20,31 @@
\page creating-plugins.html \page creating-plugins.html
\title Creating Plugins \title Creating Plugins
At its very core, \QC consists of a plugin loader that loads At its very core, \QC consists of a plugin loader that loads and runs a set
and runs a set of plugins, which then actually provide the functionality of plugins, which then actually provide the functionality that you know from
that you know from \QC the IDE. So, even the main application window \QC the IDE. So, even the main application window and menus are all provided
and menus are all provided by plugins. Plugins can use different means by plugins. Plugins can use different means to provide other plugins access
to provide other plugins access to their functionality and to allow them to their functionality and to allow them to extend certain aspects of the
to extend certain aspects of the application. 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 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 for adding menu items, modes, editor types, navigation panels and many other
things. things.
The "TextEditor" plugin provides a framework and base implementation for
different text editors with highlighting, completion and folding, that The \c TextEditor plugin provides a framework and base implementation for
is then used by other plugins to add more specialized text editor types different text editors with highlighting, completion and folding, that is
to \QC, like for editing C/C++ or .pro files. 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, 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, how to write a plugin specification file, what the lifecycle of a plugin is,
what the general principles for extending existing plugins' what the general principles for extending existing plugins' functionality
functionality and providing interfaces for other plugins are, and will and providing interfaces for other plugins are, and will be able to write
be able to write your first plugin. your first plugin.
\section1 Basics \section1 Basics
\list \list
\li \l{Getting and Building Qt Creator} \li \l{Getting and Building Qt Creator}
\li \l{Creating Your First Plugin} \li \l{Creating Your First Plugin}
@@ -51,6 +53,7 @@
\endlist \endlist
\section1 Design Principles \section1 Design Principles
\list \list
\li \l{The Plugin Manager, the Object Pool, and Registered Objects} \li \l{The Plugin Manager, the Object Pool, and Registered Objects}
\li \l{Aggregations} \li \l{Aggregations}
@@ -58,6 +61,7 @@
\endlist \endlist
\section1 Creating 3rd-Party Plugins \section1 Creating 3rd-Party Plugins
\list \list
\li \l{A Note on Binary Compatibility} \li \l{A Note on Binary Compatibility}
\li \l{Creating User-Installable Plugins} \li \l{Creating User-Installable Plugins}

View File

@@ -21,28 +21,29 @@
\title Creating Your First Plugin \title Creating Your First Plugin
This section describes how to create a \QC plugin by using the 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 template provided by \QC, and get the first impression of what a plugin
a plugin consists of and what its general structure is. consists of and what its general structure is.
\section1 Creating a Plugin Project \section1 Creating a Plugin Project
\QC comes with a wizard for \QC plugins, that creates a \QC comes with a wizard for \QC plugins, that creates a runable, \e minimal
runable, \e minimal plugin for you. We strongly suggest that you plugin for you. We strongly suggest that you use two different \QC instances
use two different \QC instances for developing and testing for developing and testing your plugin with. Otherwise your plugin will also
your plugin with. Otherwise your plugin will also be loaded in your be loaded in your development environment, which can make that unstable
development environment, which can make that unstable while your while your plugin is still unstable. You can just create a copy of your \QC
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
build and use one for actually developing, and the other for testing plugin with.
your plugin with.
You need to make sure that you use the same \QC version that you want You need to make sure that you use the same \QC version that you want to
to develop for to create the plugin. Because of the develop for to create the plugin. Because of the \l{Binary and Source
\l{Binary and Source Compatibility} rules of \QC, the \QC plugin wizard Compatibility} rules of \QC, the \QC plugin wizard creates a plugin that
creates a plugin that might only compile and run with the same \QC might only compile and run with the same \QC version that it was created
version that it was created with. with.
\list 1 \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" \image firstplugin-wizard.png "Choose the \QC Plugin Wizard"
@@ -50,65 +51,73 @@
\image firstplugin-nameandpath.png "Choose Name and Place of the Project" \image firstplugin-nameandpath.png "Choose Name and Place of the Project"
\li Give your project a name and specify in which path \li Give your project a name and specify in which path this project will
this project will be created. The actual plugin's name can be different be created. The actual plugin's name can be different from the
from the project name. You will choose that name later in the wizard. project name. You will choose that name later in the wizard.
Continue to the next page. 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" \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. \li Select the \l{glossary-buildandrun-kit}{kit} to build and run your
For a \QC plugin this needs to be a kit with \uicontrol{Desktop} device type, project with. For a \QC plugin this needs to be a kit with
and a Qt version that is compatible with the Qt version that your \uicontrol Desktop device type, and a Qt version that is compatible
\QC was built with (in the best case the exact same build). with the Qt version that your \QC was built with (in the best case
If you use an incompatible Qt version to build your plugin, you the exact same build). If you use an incompatible Qt version to
will get errors while \QC tries to load your plugin. build your plugin, you will get errors while \QC tries to load your
Continue to the next page. 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" \image firstplugin-pluginsetup.png "Specify Your Plugin Details"
\li In the \uicontrol{Plugin name} field, type \uicontrol{Example}. The name of the plugin \li In the \uicontrol {Plugin name} field, type \uicontrol Example. The
is used as its identifier, and also is the base for the file names and name of the plugin is used as its identifier, and also is the base
classes in the code. for the file names and classes in the code.
\li The values of the following fields are mainly informational, and \li The values of the following fields are mainly informational, and
are shown in the detailed view in \QC's plugin overview are shown in the detailed view in \QC's plugin overview
(\uicontrol{Help > About Plugins}, or \uicontrol{Qt Creator > About Plugins} (\uicontrol Help > \uicontrol {About Plugins}, or
on Mac). \uicontrol {Qt Creator} > \uicontrol {About Plugins} on Mac).
\list \list
\li \uicontrol{Vendor name} is a short one-word name of the company \li \uicontrol {Vendor name} is a short one-word name of the
or organization that created the plugin. This is also used for company or organization that created the plugin. This is
the path name where the plugin will be deployed to. also used for the path name where the plugin will be
\li \uicontrol{Copyright} is a one-line, short copyright string. deployed to.
\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 Copyright is a one-line, short copyright string.
\li \uicontrol{Description} is a relatively short, but
possibly multi-line description of what the plugin does. \li \uicontrol License is a multi-line license text (but
\li \uicontrol{URL} is a website where the user can find more shouldn't be pages over pages long, since the interface
information about the plugin and/or organization providing it. 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 \endlist
\li Set the \uicontrol{Qt Creator sources} and \uicontrol{Qt Creator build} fields to \li Set the \uicontrol {Qt Creator sources} and
the source and build directory of the \QC \uicontrol{Qt Creator build} fields to the source and build
instance you want to use to test your plugin with, respectively. directory of the \QC instance you want to use to test your plugin
If you don't do that correctly you will get compile errors for your with, respectively. If you don't do that correctly you will get
plugin, and your plugin might not show up in \QC at all. 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 \li In the \uicontrol {Deploy into} list, select
your .pro file up to deploy your plugin directly into your \QC build's \uicontrol {Qt Creator build}. This sets your \c {.pro} file up to
plugin directory (requires you to have write permissions there). deploy your plugin directly into your \QC build's plugin directory
The other option, \uicontrol{Local user settings}, sets your .pro file up to (requires you to have write permissions there). The other option,
deploy your plugin into \QC's user plugin path \uicontrol {Local user settings}, sets your \c {.pro} file up to
(for example \c{~/.config/QtProject/qtcreator/plugins} on Unix systems). deploy your plugin into \QC's user plugin path (for example
We choose \uicontrol{Qt Creator build} because we use a self-compiled \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 \QC, and want the plugin to be only loaded by that \QC
instance. instance. Continue to the next page.
Continue to the next page.
The \uicontrol {Project Management} dialog opens. The \uicontrol {Project Management} dialog opens.
@@ -121,65 +130,74 @@
\section1 Building and Running the Plugin \section1 Building and Running the Plugin
If you passed the correct \QC source and build paths in the project If you passed the correct \QC source and build paths in the project wizard,
wizard, your plugin should just build fine when pressing the build button. your plugin should just build fine when pressing the build button. When you
When you try to run your project, \QC will ask you for the executable to run and try to run your project, \QC will ask you for the executable to run and you
you are presented the following dialog: are presented the following dialog:
\image firstplugin-runsettings.png "Specify the Executable to Run" \image firstplugin-runsettings.png "Specify the Executable to Run"
Select the path to the \QC executable from the build that you specified Select the path to the \QC executable from the build that you specified in
in the \uicontrol{Qt Creator build} setting in the project wizard and click \uicontrol OK. the \uicontrol {Qt Creator build} setting in the project wizard and click
\QC starts up, and you can verify that your plugin successfully loaded \uicontrol OK. \QC starts up, and you can verify that your plugin
by looking for a menu entry \uicontrol{Tools > Example} and by looking for successfully loaded by looking for a menu entry \uicontrol Tools >
the plugin in the \uicontrol{About Plugins} dialog. \uicontrol Example and by looking for the plugin in the
\uicontrol {About Plugins} dialog.
\image firstplugin-menuitem.png "Menu Registered by the Plugin" \image firstplugin-menuitem.png "Menu Registered by the Plugin"
\section1 File Structure \section1 File Structure
The plugin wizard creates a set of basic files that a plugin needs or should have. The plugin wizard creates a set of basic files that a plugin needs or should
We will have a look at some of them in detail in the following sections, here is a short have. We will have a look at some of them in detail in the following
overview: sections, here is a short overview:
\table \table
\header \header
\li File \li File
\li Role \li Role
\row \row
\li \c {Example.json.in} \li \c {Example.json.in}
\li Plugin meta data template. QMake creates an \c {Example.json} \li Plugin meta data template. QMake creates an \c {Example.json}
from this file, which is compiled into the plugin as meta data. 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. The meta data is read by \QC to find out about the plugin.
\row \row
\li \c {example.pro} \li \c {example.pro}
\li Project file, used by QMake to generate a Makefile that then is used to \li Project file, used by QMake to generate a Makefile that then is used to
build the plugin. build the plugin.
\row \row
\li \c {example_global.h} \li \c {example_global.h}
\li Contains macro definitions that are useful when this plugin should export \li Contains macro definitions that are useful when this plugin should export
symbols to other plugins. symbols to other plugins.
\row \row
\li \c {exampleconstants.h} \li \c {exampleconstants.h}
\li Header defining constants used by the plugin code. \li Header defining constants used by the plugin code.
\row \row
\li \c{exampleplugin.h/.cpp} \li \c{exampleplugin.h/.cpp}
\li C++ header and source files that define the plugin class that will be \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 \endtable
\section1 qmake Project \section1 qmake Project
The qmake project file \c{example.pro} defines how your plugin should be compiled. The qmake project file \c {example.pro} defines how your plugin should be
\QC plugins need to have a specific setup there, in addition to telling qmake compiled. \QC plugins need to have a specific setup there, in addition to
which files need to be compiled (or handled by \c moc or \c uic). telling qmake which files need to be compiled (or handled by \c moc or
Let us have a look at what the project wizard generated for you in detail. \c uic). Let us have a look at what the project wizard generated for you in
detail.
\snippet exampleplugin/example.pro 1 \snippet exampleplugin/example.pro 1
The first section of the .pro file lets the compiler pass an \c EXAMPLE_LIBRARY define to the The first section of the .pro file lets the compiler pass an
compiled code, which is used in the \c{example_global.h} header, but is not really of interest \c EXAMPLE_LIBRARY define to the compiled code, which is used in the
for now. You should not need to change that section of the .pro file. \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 \snippet exampleplugin/example.pro 2
@@ -189,75 +207,79 @@
\snippet exampleplugin/example.pro 3 \snippet exampleplugin/example.pro 3
To compile and deploy your plugin, the project needs access to the \QC sources and To compile and deploy your plugin, the project needs access to the \QC
build. This section contains the logic that looks for the information about sources and build. This section contains the logic that looks for the
the location of the sources and build in the \c{QTC_SOURCE} and \c{QTC_BUILD} information about the location of the sources and build in the
environment variables. If these are not defined, it uses the defaults you \c {QTC_SOURCE} and \c {QTC_BUILD} environment variables. If these are not
set in the project wizard. 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 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 need to edit the .pro file, but instead they should set the \c {QTC_SOURCE}
\c{QTC_BUILD} environment variables correctly for the plugin's build environment. 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 \snippet exampleplugin/example.pro 4
\QC plugins can either be installed into the \QC installation's plugin directory \QC plugins can either be installed into the \QC installation's plugin
(requires write access there), or to a user specific plugin directory. directory (requires write access there), or to a user specific plugin
The \c USE_USER_DESTDIR switch in the .pro file defines which method is used for building directory. The \c USE_USER_DESTDIR switch in the .pro file defines which
the plugin (which is independent from what you can later use for distributing your method is used for building the plugin (which is independent from what you
plugin to other users). can later use for distributing your plugin to other users).
\snippet exampleplugin/example.pro 5 \snippet exampleplugin/example.pro 5
This section defines the name and dependencies of your plugin. This section defines the name and dependencies of your plugin. The
The \c{QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name of the \c {QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name
dynamic library that is created for it. The \c{QTC_LIB_DEPENDS} variable is a list of of the dynamic library that is created for it. The \c {QTC_LIB_DEPENDS}
library names of the \QC utility libraries that your plugin depends on. variable is a list of library names of the \QC utility libraries that your
Typical values would be \c{aggregation}, \c{extensionsystem} and \c{utils}. plugin depends on. Typical values would be \c aggregation,
The \c{QTC_PLUGIN_DEPENDS} variable defines the \QC plugins that your plugin depends on. \c extensionsystem and \c utils. The \c {QTC_PLUGIN_DEPENDS} variable
Almost all \QC plugins will depend on the \c{coreplugin}. The \c{QTC_PLUGIN_RECOMMENDS} defines the \QC plugins that your plugin depends on. Almost all \QC plugins
variable defines the \QC plugins that your plugin optionally depends on. For more information, will depend on the \c coreplugin. The \c {QTC_PLUGIN_RECOMMENDS} variable
see \l{Optional Dependencies}. defines the \QC plugins that your plugin optionally depends on. For more
information, see \l{Optional Dependencies}.
\snippet exampleplugin/example.pro 6 \snippet exampleplugin/example.pro 6
The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin that is suitable The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin
for use in \QC, by using the information you gave above. 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}. see the \l{qmake Manual}.
\section1 Plugin Meta Data Template \section1 Plugin Meta Data Template
The .json file is a JSON file that contains information that is needed by The \c {.json} file is a JSON file that contains information that is needed
the plugin manager to find your plugin and resolve its dependencies before actually by the plugin manager to find your plugin and resolve its dependencies
loading your plugin's library file. We will only have a short look at it here. before actually loading your plugin's library file. We will only have a
For more information, see \l{Plugin Meta Data}. 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 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 \c {.json.in} file. qmake uses this to generate the actual plugin .json
file, replacing variables like \c{QTCREATOR_VERSION} with their actual values. meta data file, replacing variables like \c {QTCREATOR_VERSION} with their
Therefore you need to escape all backslashes and quotes in the .json.in file actual values. Therefore you need to escape all backslashes and quotes in
(i.e. you need to write \c{\\} to get a backslash and \c{\"} to get a quote the \c {.json.in} file (i.e. you need to write \c {\} to get a backslash
in the generated plugin JSON meta data). and \c{\"} to get a quote in the generated plugin JSON meta data).
\snippet exampleplugin/Example.json.in 1 \snippet exampleplugin/Example.json.in 1
The first items in the meta data that is created by the wizard The first items in the meta data that is created by the wizard define the
define the name of your plugin, its version, and with what version of this plugin name of your plugin, its version, and with what version of this plugin the
the current version is binary compatible with. current version is binary compatible with.
\snippet exampleplugin/Example.json.in 2 \snippet exampleplugin/Example.json.in 2
After that you'll find the information about the plugin After that you'll find the information about the plugin that you gave in the
that you gave in the project wizard. project wizard.
\snippet exampleplugin/Example.json.in 3 \snippet exampleplugin/Example.json.in 3
The \c{$$dependencyList} variable is automatically replaced by the dependency information The \c {$$dependencyList} variable is automatically replaced by the
in \c{QTC_PLUGIN_DEPENDS} and \c{QTC_PLUGIN_RECOMMENDS} from your plugin's .pro file. dependency information in \c {QTC_PLUGIN_DEPENDS} and
\c {QTC_PLUGIN_RECOMMENDS} from your plugin's \c {.pro} file.
\section1 Plugin Class \section1 Plugin Class
@@ -267,28 +289,29 @@
\section2 Header File \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 \snippet exampleplugin/exampleplugin.h namespaces
The plugin is defined in a \c{Example::Internal} namespace, which conforms to The plugin is defined in a \c {Example::Internal} namespace, which conforms
the coding rules for \l{coding-rules-namespacing}{namespacing} to the coding rules for \l{coding-rules-namespacing}{namespacing}
in \QC sources. in \QC sources.
\snippet exampleplugin/exampleplugin.h base class \snippet exampleplugin/exampleplugin.h base class
All \QC plugins must be derived from \l{ExtensionSystem::IPlugin} and 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. are QObjects. The \c {Q_PLUGIN_METADATA} macro is necessary to create a
The \c IID given in the macro must be \c{org.qt-project.Qt.QtCreatorPlugin}, to identify it valid Qt plugin. The \c IID given in the macro must be
as a \QC plugin, and \c FILE must point to the plugin's meta data file as described \c {org.qt-project.Qt.QtCreatorPlugin}, to identify it as a \QC plugin, and
in \l{Plugin Meta Data}. \c FILE must point to the plugin's meta data file as described in
\l{Plugin Meta Data}.
\snippet exampleplugin/exampleplugin.h plugin functions \snippet exampleplugin/exampleplugin.h plugin functions
The base class defines basic functions that are called during the life cycle The base class defines basic functions that are called during the life cycle
of a plugin, which are here implemented for your new plugin. of a plugin, which are here implemented for your new plugin. These functions
These functions and their roles are described in detail in and their roles are described in detail in \l{The Plugin Life Cycle}.
\l{The Plugin Life Cycle}.
\snippet exampleplugin/exampleplugin.h slot \snippet exampleplugin/exampleplugin.h slot
@@ -297,34 +320,36 @@
\section2 Source File \section2 Source File
The source file contains the actual implementation of the plugin, which registers The source file contains the actual implementation of the plugin, which
a new menu and menu item, and opens a message box when that item is triggered. 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, All the necessary header files from the plugin code itself, from the \c
from the Core plugin, and from Qt are included in the beginning of the file. Core plugin, and from Qt are included in the beginning of the file. The
The setup of the menu and menu item setup of the menu and menu item is done in the plugin's \c initialize
is done in the plugin's \c{initialize} function, which is the first thing called function, which is the first thing called after the plugin constructor. In
after the plugin constructor. In that function, the plugin can be sure that the basic that function, the plugin can be sure that the basic setup of plugin's that
setup of plugin's that it depends on has been done, for example the Core plugin's it depends on has been done, for example the Core plugin's \c ActionManager
\c{ActionManager} instance has been created. instance has been created.
For more information about implementing the plugin interface, see the For more information about implementing the plugin interface, see the
\l{ExtensionSystem::IPlugin} API documentation and \l{Plugin Life Cycle}. \l{ExtensionSystem::IPlugin} API documentation and \l{Plugin Life Cycle}.
\snippet exampleplugin/exampleplugin.cpp add action \snippet exampleplugin/exampleplugin.cpp add action
This part of the code creates a new \c{QAction}, registers it as a new 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. \c Command in the action manager, and connects it to the plugin's slot. The
The action manager provides a central place where the user can assign and action manager provides a central place where the user can assign and change
change keyboard shortcuts, and manages cases where for example a menu item should be keyboard shortcuts, and manages cases where for example a menu item should
directed to different plugins under different circumstances, as well as a few be directed to different plugins under different circumstances, as well as a
other things. This is described in more detail in \l{Menus and Menu Items}. few other things. This is described in more detail in
\l{Menus and Menu Items}.
\snippet exampleplugin/exampleplugin.cpp add menu \snippet exampleplugin/exampleplugin.cpp add menu
Here a new menu item is created, the created command added to it, and the menu Here a new menu item is created, the created command added to it, and the
added to the \uicontrol{Tools} menu in the menu bar. Again, this is covered in more menu added to the \uicontrol Tools menu in the menu bar. Again, this is
detail in \l{Menus and Menu Items}. covered in more detail in \l{Menus and Menu Items}.
\snippet exampleplugin/exampleplugin.cpp slot implementation \snippet exampleplugin/exampleplugin.cpp slot implementation

View File

@@ -26,33 +26,38 @@
\endcode \endcode
There are several reasons why you might want to do your own build of \QC, 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 like using the most current development version and being able to tweak \QC
\QC at one or the other place. It is also necessary if you want to at one or the other place. It is also necessary if you want to create your
create your own \QC plugin. own \QC plugin.
\section1 Getting Qt \section1 Getting Qt
Prebuilt \QC packages usually use the latest stable release of Qt. Prebuilt \QC packages usually use the latest stable release of Qt. You can
You can see the exact minimum requirement at the top of \QC's qtcreator.pro. 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: (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}.) \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}. You can get prebuilt Qt packages from
If you want to use Qt as provided by your Linux distribution, you need to make sure that all \l{https://download.qt.io}{Qt Downloads}. If you want to use Qt as provided
Qt development packages and private header packages are also installed. 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 \section1 Getting and Building \QC
You can get the \QC sources for a specific version either by using one of the You can get the \QC sources for a specific version either by using one of
released source bundles, or from the Git repository 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 \l{https://code.qt.io/cgit/qt-creator/qt-creator.git}. If you intend to
itself, you should use the repository from our Gerrit review tool as described contribute to \QC itself, you should use the repository from our Gerrit
in: \l{https://wiki.qt.io/Setting_up_Gerrit}{Setting up 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 We strongly encourage you to do out-of-source builds of \QC (also called
shadow-builds). shadow-builds).
After you put the \QC sources somewhere (lets call the path \c{<QtCreatorSources>})
After you put the \QC sources somewhere (lets call the path
\c {<QtCreatorSources>})
you build it on Linux and Mac with you build it on Linux and Mac with
\code \code
cd <QtCreatorSources>/.. cd <QtCreatorSources>/..
mkdir qtcreator-build mkdir qtcreator-build
@@ -60,5 +65,6 @@
<QtInstall>/bin/qmake -r <QtCreatorSources> <QtInstall>/bin/qmake -r <QtCreatorSources>
make make
\endcode \endcode
or the corresponding commands on Windows systems. or the corresponding commands on Windows systems.
*/ */

View File

@@ -21,12 +21,11 @@
\title Qt Creator API Reference \title Qt Creator API Reference
The core of Qt Creator is The core of \QC is basically only a \l{ExtensionSystem}{plugin loader}. All
basically only a \l{ExtensionSystem}{plugin loader}. functionality is implemented in plugins. The basis of \QC is implemented in
All functionality is implemented in plugins. The basis of Qt Creator is the \l{Core}{Core} Plugin. The plugin manager provides simple means for
implemented in the \l{Core} {Core} Plugin. The plugin manager provides plugin cooperation that allow plugins to provide hooks for other plugin's
simple means for plugin cooperation that allow plugins to provide extensions.
hooks for other plugin's extensions.
\section1 Libraries \section1 Libraries
@@ -41,13 +40,14 @@
\row \row
\li \l{Aggregation} \li \l{Aggregation}
\li Adds functionality for "glueing" QObjects of different \li Adds functionality for "glueing" QObjects of different types
types together, so you can "cast" between them. together, so you can "cast" between them.
\row \row
\li \l{ExtensionSystem} \li \l{ExtensionSystem}
\li Implements the plugin loader framework. Provides a base class for plugins and \li Implements the plugin loader framework. Provides a base class
basic mechanisms for plugin interaction like an object pool. for plugins and basic mechanisms for plugin interaction like an
object pool.
\row \row
\li \l{Utils} \li \l{Utils}
@@ -69,15 +69,13 @@
\row \row
\li \l{qtcreatorcdbext} \li \l{qtcreatorcdbext}
\li Windows CDB debugger extension \li Windows CDB debugger extension
\endtable \endtable
\section1 Plugins \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 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. later to integrate e.g. editors or mode windows.
\table \table
@@ -87,16 +85,19 @@
\row \row
\li \l{Core} \li \l{Core}
\li The core plugin. Provides the main window and managers for editors, \li The core plugin. Provides the main window and managers for
actions, mode windows and files, just to mention the most important ones. editors, actions, mode windows and files, just to mention the
most important ones.
\row \row
\li \l{ProjectExplorer} \li \l{ProjectExplorer}
\li The project explorer plugin. Provides base classes for project handling. \li The project explorer plugin. Provides base classes for project
handling.
\row \row
\li \l{Find} \li \l{Find}
\li Support for searching text in arbitrary widgets, and arbitrary other things. \li Support for searching text in arbitrary widgets, and arbitrary
other things.
\row \row
\li \l{Locator} \li \l{Locator}
@@ -112,11 +113,11 @@
\row \row
\li \l{TextEditor} \li \l{TextEditor}
\li This is where everything starts if you want to create a text editor. Besides \li This is where everything starts if you want to create a text
the base editor itself, this plugin contains APIs for supporting functionality editor. Besides the base editor itself, this plugin contains
like \l{Snippets}{snippets}, highlighting, \l{CodeAssist}{code assist}, indentation APIs for supporting functionality like \l{Snippets}{snippets},
and style, and others. highlighting, \l{CodeAssist}{code assist}, indentation and
style, and others.
\endtable \endtable
*/ */
@@ -154,7 +155,7 @@
\title Common Extension Tasks \title Common Extension Tasks
This section summarizes the API functions that you can use to add UI This section summarizes the API functions that you can use to add UI
components to Qt Creator. components to \QC.
\table \table
\header \header
@@ -169,13 +170,14 @@
\row \row
\li Add a configurable keyboard shortcut. \li Add a configurable keyboard shortcut.
\li Registering shortcuts makes it possible for users to configure them in \li Registering shortcuts makes it possible for users to configure
the common shortcut settings dialog. them in the common shortcut settings dialog.
\li \l{Core::ActionManager}, \l{Core::Command} \li \l{Core::ActionManager}, \l{Core::Command}
\row \row
\li Add a mode. \li Add a mode.
\li Modes correspond to complete screens of controls, specialized for a task. \li Modes correspond to complete screens of controls, specialized
for a task.
\li \l{Core::IMode} \li \l{Core::IMode}
\row \row
@@ -185,25 +187,27 @@
\row \row
\li Add a new wizard. \li Add a new wizard.
\li You can extend the wizards in File > New File or Project with your own \li You can extend the wizards in File > New File or Project with
file and project templates. your own file and project templates.
\li \l{Core::IWizard}, \l{Core::StandardFileWizard}, \li \l{Core::IWizard}, \l{Core::StandardFileWizard},
\l{Core::BaseFileWizard}, \l{Core::BaseFileWizardParameters} \l{Core::BaseFileWizard}, \l{Core::BaseFileWizardParameters}
\row \row
\li Add support for a new version control system. \li Add support for a new version control system.
\li Version control systems integrated in QtCreator are Bazaar, CVS, Git, \li Version control systems integrated in \QC are Bazaar, CVS, Git,
Mecurial, Perforce, and Subversion. Mecurial, Perforce, and Subversion.
\li \l{Core::IVersionControl} \li \l{Core::IVersionControl}
\row \row
\li Add a view to the navigation sidebar. \li Add a view to the navigation sidebar.
\li The one which shows the project tree, filesystem, open documents or bookmarks. \li The one which shows the project tree, filesystem, open documents
or bookmarks.
\li \l{Core::INavigationWidgetFactory} \li \l{Core::INavigationWidgetFactory}
\row \row
\li Add an options page to the \uicontrol Options dialog. \li Add an options page to the \uicontrol Options dialog.
\li Add a new page to existing or new category in Tools > Options. \li Add a new page to existing or new category in
\uicontrol Tools > \uicontrol Options.
\li \l{Core::IOptionsPage} \li \l{Core::IOptionsPage}
\row \row
@@ -213,8 +217,8 @@
\row \row
\li Add support for the find tool bar to a widget. \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 \li The widget that has focus is asked whether it supports text
add support for widgets under your control. search. You can add support for widgets under your control.
\li \l{Core::IFindSupport}, \l{Find::BaseTextFind} \li \l{Core::IFindSupport}, \l{Find::BaseTextFind}
\row \row
@@ -229,14 +233,17 @@
\row \row
\li Add a new filter to the locator. \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. \li For a text typed in by the user you provide a list of things to
When the user selects an entry you are requested to do whatever you want. show in the popup. When the user selects an entry you are
\li \l{Core::ILocatorFilter}, \l{Core::LocatorFilterEntry}, \l{Locator::BaseFileFilter} requested to do whatever you want.
\li \l{Core::ILocatorFilter}, \l{Core::LocatorFilterEntry},
\l{Locator::BaseFileFilter}
\row \row
\li Show a progress indicator for a concurrently running task. \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, \li You can show a progress indicator for your tasks in the left
and also in the application icon (on platforms that support it). hand tool bar, and also in the application icon (on platforms
that support it).
\li \l{Core::ProgressManager}, \l{Core::FutureProgress} \li \l{Core::ProgressManager}, \l{Core::FutureProgress}
\row \row

View File

@@ -20,37 +20,35 @@
\page extending-index.html \page extending-index.html
\title Extending Qt Creator Manual \title Extending Qt Creator Manual
Qt Creator is a cross-platform integrated development environment (IDE) \QC is a cross-platform integrated development environment (IDE) tailored to
tailored to the needs of Qt developers. the needs of Qt developers.
Qt Creator is extensible in various ways. For example, Qt Creator \QC is extensible in various ways. For example, \QC architecture is based on
architecture is based on a plugin loader, which means that all a plugin loader, which means that all functionality beyond plugin loading
functionality beyond plugin is implemented in plugins. However, you can extend and tweak many parts of
loading is implemented in plugins. However, you can extend and tweak \QC without the need to resort to coding in C++ and implementing such a
many parts of Qt Creator without the need to resort to coding in C++ and plugin.
implementing such a plugin.
This document gives you an overview of the various ways in which This document gives you an overview of the various ways in which you can
you can extend Qt Creator, extend \QC, depending on what you want to achieve, and points you to the
depending on what you want to achieve, and points you to the relevant relevant documentation.
documentation.
\section1 Generating Domain Specific Code and Templates \section1 Generating Domain Specific Code and Templates
If you regularly need to write the same code, be it little code snippets, 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, whole files or classes spread over multiple files, or complete projects, you
you can create code snippets, templates, and wizards for that purpose. can create code snippets, templates, and wizards for that purpose.
\section2 Snippets \section2 Snippets
Typically, snippets consist of a few lines of code (although they Typically, snippets consist of a few lines of code (although they can also
can also be plain text) that you regularly be plain text) that you regularly want to insert into a bigger body of code,
want to insert into a bigger body of code, but do not want to type each but do not want to type each time. For example, \c while and \c for loops,
time. For example, \c while and \c for loops, \c if-else and \c try-catch \c if-else and \c try-catch constructs, and class skeletons. Snippets are
constructs, and class skeletons. Snippets are triggered in the same way as triggered in the same way as normal code completion (see
normal code completion (see \l{Code Assist}{Providing Code Assist}). \l{Code Assist}{Providing Code Assist}).
Qt Creator contains a set of preconfigured snippets groups \QC contains a set of preconfigured snippets groups to which you can add
to which you can add your own snippets. your own snippets.
\list \list
\li \l{http://doc.qt.io/qtcreator/creator-completing-code.html#editing-code-snippets} \li \l{http://doc.qt.io/qtcreator/creator-completing-code.html#editing-code-snippets}
@@ -58,11 +56,11 @@
\li \l{Snippets}{Adding Snippets Groups} \li \l{Snippets}{Adding Snippets Groups}
\endlist \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 You can extend the wizards in \uicontrol File >
own \uicontrol {New File or Project} with your own file and project templates by
file and project templates by writing XML definition files for them. writing JSON definition files for them.
\list \list
\li \l{http://doc.qt.io/qtcreator/creator-project-wizards.html} \li \l{http://doc.qt.io/qtcreator/creator-project-wizards.html}
{Adding New Custom Wizards} {Adding New Custom Wizards}
@@ -71,10 +69,11 @@
\section2 Custom Wizards \section2 Custom Wizards
If the above methods for code snippets and templates are not sufficient If the above methods for code snippets and templates are not sufficient for
for your use case, you can create a custom Qt Creator plugin. your use case, you can create a custom \QC plugin. While this gives you
While this gives you complete control over the wizard, it complete control over the wizard, it also requires you to write most of the
also requires you to write most of the UI and the logic yourself. UI and the logic yourself.
\list \list
\li \l{Creating Plugins} \li \l{Creating Plugins}
\li \l{Qt Creator Coding Rules} \li \l{Qt Creator Coding Rules}
@@ -84,17 +83,18 @@
\section1 Supporting Additional File Types \section1 Supporting Additional File Types
If you have files with extensions or MIME types that Qt Creator does not If you have files with extensions or MIME types that \QC does not handle by
handle by default, you can edit the MIME type definitions, add highlight default, you can edit the MIME type definitions, add highlight definition
definition files, and create your own text editors. files, and create your own text editors.
\section2 MIME Types \section2 MIME Types
You might find that Qt Creator could handle a particular file of yours if You might find that \QC could handle a particular file of yours if it knew
it knew about the type of its contents. For example, C++ header or source about the type of its contents. For example, C++ header or source files
files with file extensions that are not known to Qt Creator. You can adapt with file extensions that are not known to \QC. You can adapt the MIME type
the MIME type definitions in Qt Creator to your specific setup, definitions in \QC to your specific setup, by adding or removing file
by adding or removing file extensions and specifying magic headers. extensions and specifying magic headers.
\list \list
\li \l{http://doc.qt.io/qtcreator/creator-mime-types.html} \li \l{http://doc.qt.io/qtcreator/creator-mime-types.html}
{Editing MIME Types} {Editing MIME Types}
@@ -104,11 +104,12 @@
\section2 Text Highlighting and Indentation \section2 Text Highlighting and Indentation
For text files, Qt Creator provides an easy way to add highlighting and For text files, \QC provides an easy way to add highlighting and indentation
indentation for file types that are not known to it by default. for file types that are not known to it by default. Generic highlighting is
Generic highlighting is based on highlight definition files that are based on highlight definition files that are provided by the Kate Editor.
provided by the Kate Editor. You can download highlight definition files You can download highlight definition files for use with \QC and create
for use with Qt Creator and create your own definition files. your own definition files.
\list \list
\li \l{http://doc.qt.io/qtcreator/creator-editor-options.html#generic-highlighting} \li \l{http://doc.qt.io/qtcreator/creator-editor-options.html#generic-highlighting}
{Generic Highlighting} {Generic Highlighting}
@@ -120,10 +121,11 @@
If you need more advanced features than the MIME type and highlighting If you need more advanced features than the MIME type and highlighting
features described above, such as custom text completion or features that 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 rely on semantic analysis, you can extend \QC with a text editor of your
your own. Qt Creator provides a special API for text editors that gives you own. \QC provides a special API for text editors that gives you a basis to
a basis to build on, taking away some of the pain of implementing build on, taking away some of the pain of implementing a text editor from
a text editor from the ground up. the ground up.
\list \list
\li \l{Creating Plugins} \li \l{Creating Plugins}
\li \l{Qt Creator Coding Rules} \li \l{Qt Creator Coding Rules}
@@ -133,8 +135,9 @@
\section2 Other Custom Editors \section2 Other Custom Editors
You can also add a completely custom editor to gain complete You can also add a completely custom editor to gain complete control over
control over its appearance and behavior. its appearance and behavior.
\list \list
\li \l{Creating Plugins} \li \l{Creating Plugins}
\li \l{Qt Creator Coding Rules} \li \l{Qt Creator Coding Rules}
@@ -145,22 +148,22 @@
Most software projects and development processes require various external Most software projects and development processes require various external
tools. Several external tools, such as popular version control systems and tools. Several external tools, such as popular version control systems and
build tool chains are integrated into Qt Creator. However, it is impossible build tool chains are integrated into \QC. However, it is impossible for a
for a single tool to cover all the use cases, and therefore you can single tool to cover all the use cases, and therefore you can integrate
integrate additional tools to Qt Creator. additional tools to \QC.
\section2 Simple External Tools \section2 Simple External Tools
In Qt Creator, you can specify tools that you can then run from a In \QC, you can specify tools that you can then run from a menu or by using
menu or by using a keyboard shortcut that you assign. This allows you to a keyboard shortcut that you assign. This allows you to accomplish several
accomplish several things, with some limitations. You specify a command things, with some limitations. You specify a command to run, arguments and
to run, arguments and input for running it, and how to handle the output. input for running it, and how to handle the output. To specify the values,
To specify the values, you can use a set of internal Qt Creator variables, you can use a set of internal \QC variables, such as the file name of the
such as the file name of current document or project, or the currently selected text in a text
the current document or project, or the currently selected text in editor. If you find variables missing, please do not hesitate to fill a
a text editor. If you find variables missing, please do not hesitate feature suggestion. The tool descriptions are saved as XML files that you
to fill a feature suggestion. can share.
The tool descriptions are saved as XML files that you can share.
\list \list
\li \l{http://doc.qt.io/qtcreator/creator-editor-external.html} \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html}
{Using External Tools} {Using External Tools}
@@ -171,26 +174,23 @@
When you plan to integrate more complex tools, carefully consider whether When you plan to integrate more complex tools, carefully consider whether
there really are advantages to be gained by tightly integrating the tool there really are advantages to be gained by tightly integrating the tool
into Qt Creator over loosely integrating it by mainly into \QC over loosely integrating it by mainly providing a means of starting
providing a means of starting the tool with fitting parameters. the tool with fitting parameters.
\section3 Loosely Integrating Tools \section3 Loosely Integrating Tools
If no interaction is needed between Qt Creator and the If no interaction is needed between \QC and the external tool, just starting
external tool, just starting an external an external application with its own user interface is preferable. That way
application with its own user interface is preferable. That way cluttering the \QC UI is avoided, and the tool will be available with a
cluttering the Qt Creator UI is avoided, and the tool will be nice interface even without using \QC at all.
available with a nice interface even without using Qt Creator
at all.
Usually, you can use the external tool specification files to start the Usually, you can use the external tool specification files to start the
tool. If starting the tool and handling its output require more complex 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. logic, you can add a menu item to \QC with a plugin. If you need a way to
If you need a way to configure the tool in Qt Creator, you can add an configure the tool in \QC, you can add an \uicontrol Options page for it.
\uicontrol Options page for it.
\list \list
\li \l{http://doc.qt.io/qtcreator/creator-editor-external.html} \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html}{Using External Tools}
{Using External Tools}
\li \l{External Tool Specification Files} \li \l{External Tool Specification Files}
\li \l{Creating Plugins} \li \l{Creating Plugins}
\li \l{Qt Creator Coding Rules} \li \l{Qt Creator Coding Rules}
@@ -200,19 +200,18 @@
\section3 Interacting with Tool Output \section3 Interacting with Tool Output
In some cases, running an external tool would not require tight In some cases, running an external tool would not require tight integration
integration with Qt Creator, but investigating the output of the tool would with \QC, but investigating the output of the tool would benefit from it.
benefit from it. For example, some tools generate lists of issues in files For example, some tools generate lists of issues in files that are part of
that are part of the project and some tools create output that is related the project and some tools create output that is related to the code. For
to the code. For these tools, it is useful to interactively switch between these tools, it is useful to interactively switch between the output and
the output and the corresponding code. 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 \list
\li \l{http://doc.qt.io/qtcreator/creator-task-lists.html} \li \l{http://doc.qt.io/qtcreator/creator-task-lists.html}
{Showing Task List Files in the Issues Pane} {Showing Task List Files in the Issues Pane}
@@ -248,6 +247,5 @@
\li \l{Qt Creator Coding Rules} \li \l{Qt Creator Coding Rules}
\li \l{Qt Creator API Reference} \li \l{Qt Creator API Reference}
\endlist \endlist
\endlist \endlist
*/ */

View File

@@ -24,10 +24,10 @@
\title Writing Documentation \title Writing Documentation
When you add plugins or contribute new features to \QC, you probably want 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, other people to know about them and to be able to use them. Therefore, you
you should also contribute documentation for them. Follow the guidelines in should also contribute documentation for them. Follow the guidelines in this
this section to make sure that your documentation fits in well with the rest section to make sure that your documentation fits in well with the rest of
of the \QC documentation. the \QC documentation.
When you contribute a plugin, you should write documentation both for the When you contribute a plugin, you should write documentation both for the
developers who use \QC and for the ones who develop it. 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: Write the following user documentation for addition to the \QC Manual:
\list \list
\li Overview topic, which describes the purpose of your plugin from the \li Overview topic, which describes the purpose of your plugin from the
viewpoint of \QC users viewpoint of \QC users
@@ -43,58 +42,52 @@
\li Reference topics, which contain information that developers \li Reference topics, which contain information that developers
occasionally need to look up (optional) occasionally need to look up (optional)
\endlist \endlist
Write the following developer documentation for addition to the Extending Write the following developer documentation for addition to the Extending
\QC Manual: \QC Manual:
\list \list
\li Overview topic, which describes the architecture and use cases for \li Overview topic, which describes the architecture and use cases for
your plugin from the viewpoint of \QC developers your plugin from the viewpoint of \QC developers
\li API documentation, which is generated from code comments \li API documentation, which is generated from code comments
\endlist \endlist
\section1 Configuring the Documentation Project \section1 Configuring the Documentation Project
\QC documentation is written by using QDoc. For more information about using \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, see the \l{http://doc.qt.io/qt-5/qdoc-index.html}{QDoc Manual}.
{QDoc Manual}.
QDoc finds the new topics automatically, when you place them as .qdoc files QDoc finds the new topics automatically, when you place them as \c {.qdoc}
in the correct folder. However, to make the topics accessible to readers, files in the correct folder. However, to make the topics accessible to
you must also add them to the table of contents and fix the next page and readers, you must also add them to the table of contents and fix the next
previous page links to them from other topics. page and previous page links to them from other topics.
\section2 Creating Folders and Files \section2 Creating Folders and Files
These instructions apply only to the \QC Manual. Add API documentation These instructions apply only to the \QC Manual. Add API documentation
directly to the code source files. However, you can write an API overview 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 Create a subfolder for your documentation in the \QC project folder in the
\c {doc\src} folder. Create a separate file for each topic. \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, 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 modify it. This way, you already have samples of the necessary bits and
and pieces in place, such as topic start and end commands, copyright pieces in place, such as topic start and end commands, copyright statement,
statement, links to next and previous topics, and topic title. links to next and previous topics, and topic title.
\section2 Integrating Topics to Documentation \section2 Integrating Topics to Documentation
You must integrate your new topics to the \QC Manual and Extending You must integrate your new topics to the \QC Manual and Extending \QC
\QC Manual by adding links to them to the table of contents and to other Manual by adding links to them to the table of contents and to other
relevant topics. relevant topics.
To link to the topic, you can use the topic title. For example: To link to the topic, you can use the topic title. For example:
\code \code
\l{Integrating Topics to Documentation} \l{Integrating Topics to Documentation}
\endcode \endcode
This does not work if topic titles are not unique. Also, if you change the 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 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 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} the script to work, you must add the \c {\nextpage} and \c {\previouspage}
commands to the topic, with dummy values (for example, commands to the topic, with dummy values (for example,
\c {\nextpage=anything.html}). \c {\nextpage=anything.html}).
@@ -121,23 +114,20 @@
To run the script, enter the following command in the doc folder: To run the script, enter the following command in the doc folder:
\list \list
\li nmake fixnavi (on Windows) \li nmake fixnavi (on Windows)
\li make fixnavi (on Linux) \li make fixnavi (on Linux)
\endlist \endlist
\section1 Writing Text \section1 Writing Text
Follow the guidelines for Follow the guidelines for
\l{http://wiki.qt.io/Writing_Qt_Documentation} \l{http://wiki.qt.io/Writing_Qt_Documentation}{writing Qt documentation}.
{writing Qt documentation}.
The documentation must be grammatically correct English and use the standard The documentation must be grammatically correct English and use the standard
form of written language. Do not use dialect or slang words. Use idiomatic form of written language. Do not use dialect or slang words. Use idiomatic
language, that is, expressions that are characteristic for English. language, that is, expressions that are characteristic for English. If
If possible, ask a native English speaker for a review. possible, ask a native English speaker for a review.
\section2 Capitalizing Headings \section2 Capitalizing Headings
@@ -159,11 +149,11 @@
\section2 Taking Screen Shots \section2 Taking Screen Shots
\QC has the native look and feel on Windows, Linux, and OS X, and \QC has the native look and feel on Windows, Linux, and OS X, and therefore,
therefore, screen shots can end up looking very different, depending on who screen shots can end up looking very different, depending on who takes them
takes them and which system they use. To try to preserve a consistent look and which system they use. To try to preserve a consistent look and feel in
and feel in the \QC Manual, observe the guidelines listed in this section the \QC Manual, observe the guidelines listed in this section when taking
when taking screen shots. screen shots.
To make the images look similar regardless of the operating system they were 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 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. place example values also in the text.
\list \list
\li Use the screen resolution of 1024x768 (this is available on all \li Use the screen resolution of 1024x768 (this is available on all
screens). screens).
@@ -194,7 +183,6 @@
\li Before you submit the images to the repository, optimize them to \li Before you submit the images to the repository, optimize them to
save space. save space.
\endlist \endlist
\section2 Optimizing Images \section2 Optimizing Images
@@ -210,10 +198,9 @@
it. it.
You can use a web service, such as \l{https://tinypng.com}, or an image You can use a web service, such as \l{https://tinypng.com}, or an image
optimization tool to shrink the images. For example, you optimization tool to shrink the images. For example, you can use the Radical
can use the Radical Image Optimization Tool (RIOT) on Windows (very Image Optimization Tool (RIOT) on Windows (very efficient) or ImageOptim on
efficient) or ImageOptim on OS X (much less efficient), or some other tool OS X (much less efficient), or some other tool available on Linux.
available on Linux.
With ImageOptim, you simply drag and drop the image files to the With ImageOptim, you simply drag and drop the image files to the
application. The following section describes the settings to use for RIOT. 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: Open your images in RIOT and use the following settings for them:
\list \list
\li Color reduction: Optimal 256 colors palette \li Color reduction: Optimal 256 colors palette
\li Reduce colors to: 256 \li Reduce colors to: 256
@@ -237,7 +223,6 @@
\li Color quantization algorithm: NeuQuant neural-net (slow) \li Color quantization algorithm: NeuQuant neural-net (slow)
\li External optimizers: OptiPNG o3 \li External optimizers: OptiPNG o3
\endlist \endlist
Compare the initial and optimized images to check that image quality is Compare the initial and optimized images to check that image quality is
@@ -264,7 +249,6 @@
qdocconf file: qdocconf file:
\list \list
\li \c {include ($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)} \li \c {include ($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)}
for help files for help files
\li \c {include ($QT_INSTALL_DOCS/global/qt-html-templates-online.qdocconf)} \li \c {include ($QT_INSTALL_DOCS/global/qt-html-templates-online.qdocconf)}
@@ -285,27 +269,25 @@
commands from the project folder (after running qmake): commands from the project folder (after running qmake):
\list \list
\li nmake docs (on Windows) \li nmake docs (on Windows)
\li make docs (on Linux and OS X)
\li make docs (on Linux and OS X)
\endlist \endlist
The \QC Manual HTML files are generated in the \c {doc/html} directory. The \QC Manual HTML files are generated in the \c {doc/html} directory.
The Extending \QC Manual files are generated in the 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 \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 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 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 the \QC \uicontrol Help mode. For more information about adding the help
\QC, see files to \QC, see
\l{http://doc.qt.io/qtcreator/creator-help.html#adding-external-documentation} \l{http://doc.qt.io/qtcreator/creator-help.html#adding-external-documentation}
{Adding External Documentation}. {Adding External Documentation}.
Besides \c docs, you have the following options: Besides \c docs, you have the following options:
\list \list
\li html_docs - build \QC Manual in help format, but do not generate a \li html_docs - build \QC Manual in help format, but do not generate a
help file help file
@@ -324,7 +306,6 @@
\li html_docs_online - build \QC Manual in online format \li html_docs_online - build \QC Manual in online format
\li dev_html_docs_online - build Extending \QC Manual in online format \li dev_html_docs_online - build Extending \QC Manual in online format
\endlist \endlist
*/ */

View File

@@ -121,14 +121,8 @@
short, canonical HTML in the source tab of the rich text editor: short, canonical HTML in the source tab of the rich text editor:
\c {<html><head/><body><b>Note:</b> text.} \c {<html><head/><body><b>Note:</b> text.}
In Qt 4.7, use only the \uicontrol Source tab of the Qt Designer rich text Qt Designer has a feature that simplifies the rich text (on by default),
editor. The automatic conversion performed by the rich text editor tab but still, you should verify by looking at the \uicontrol Source 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.
\section2 Writing Messages \section2 Writing Messages
@@ -279,9 +273,11 @@
\table \table
\header \header
\li Features of Languages or Writing Systems \li Features of Languages or Writing Systems
\li Impact on Implementation \li Impact on Implementation
\row \row
\li Word order \li Word order
\li Different languages have different word order rules. \li Different languages have different word order rules.
Do not use run-time concatenation. Use complete phrases Do not use run-time concatenation. Use complete phrases
@@ -294,6 +290,7 @@
\c {tr("Foo failed: ") + message} \c {tr("Foo failed: ") + message}
\row \row
\li Singular vs. plural vs. dual forms \li Singular vs. plural vs. dual forms
\li Some languages do not have plural form (for example, Chinese \li Some languages do not have plural form (for example, Chinese
and Japanese), whereas some have a different form for dual. and Japanese), whereas some have a different form for dual.
@@ -310,6 +307,7 @@
\c {tr("%1 files found").arg(number)} \c {tr("%1 files found").arg(number)}
\row \row
\li Gender \li Gender
\li Some languages have gender (feminine, masculine, neutral), \li Some languages have gender (feminine, masculine, neutral),
whereas some do not (for example, Finnish) or do not use it whereas some do not (for example, Finnish) or do not use it
extensively (for example, English). extensively (for example, English).
@@ -340,15 +338,21 @@
\table \table
\header \header
\li UI Text \li UI Text
\li Usage \li Usage
\li Conventions \li Conventions
\row \row
\li Context menu \li Context menu
\li Opens when users right-click on the screen. Contents depend on \li Opens when users right-click on the screen. Contents depend on
the context. the context.
\image qtcreator-context-menu.png "Context menu" \image qtcreator-context-menu.png "Context menu"
\li You can add menu items that are relevant in a particular \li You can add menu items that are relevant in a particular
context. Follow the conventions for naming menu items. context. Follow the conventions for naming menu items.
\row \row
\li Dialog \li Dialog
\li User interface element that usually contains a number of \li User interface element that usually contains a number of
@@ -362,19 +366,25 @@
\uicontrol {Add Documentation} dialog. \uicontrol {Add Documentation} dialog.
\row \row
\li Locator \li Locator
\li Allows you to browse not only files, but any items defined by \li Allows you to browse not only files, but any items defined by
locator filters. locator filters.
\image qtcreator-locator.png "Locator" \image qtcreator-locator.png "Locator"
\li You can add locator filters. Check that the filter is not \li You can add locator filters. Check that the filter is not
already in use and give the filter a descriptive name. already in use and give the filter a descriptive name.
\row \row
\li Menu \li Menu
\li Contains menu items that represent commands or options and that \li Contains menu items that represent commands or options and that
are logically grouped and displayed. A menu can also contain are logically grouped and displayed. A menu can also contain
submenus. submenus.
\image qtcreator-menu.png "Menu" \image qtcreator-menu.png "Menu"
\li You can create new menus. Use short, but descriptive names that \li You can create new menus. Use short, but descriptive names that
are consistent with existing menu names. Use unambigious names. are consistent with existing menu names. Use unambigious names.
\row \row
\li Menu item \li Menu item
\li Represents a command or an option for users to choose. \li Represents a command or an option for users to choose.

View File

@@ -7,6 +7,7 @@ sourcedirs = $SRCDIR/src
imagedirs = $SRCDIR/images $SRCDIR/templates/images imagedirs = $SRCDIR/images $SRCDIR/templates/images
outputdir = $OUTDIR outputdir = $OUTDIR
exampledirs = $SRCDIR/examples exampledirs = $SRCDIR/examples
examples.fileextensions += *.qml *.svg
HTML.extraimages = images/commercial.png HTML.extraimages = images/commercial.png
qhp.QtCreator.extraFiles = images/commercial.png qhp.QtCreator.extraFiles = images/commercial.png

View File

@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny">
<defs>
<radialGradient id="grad1" cx="0.5" cy="0.7" r="0.7" fx="0.5" fy="0.4">
<stop offset="0" style="stop-color:rgb(255,255,255)" />
<stop offset="1.5" style="stop-color:rgb(0,102,153)" />
</radialGradient>
</defs>
<circle cx="100" cy="80" r="42" fill="url(#grad1)"/>
</svg>

After

Width:  |  Height:  |  Size: 399 B

View File

@@ -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)

View File

@@ -35,8 +35,8 @@
** **
**************************************************************************/ **************************************************************************/
import QtQuick 2.2 import QtQuick 2.5
import QtQuick.Controls 1.1 import QtQuick.Controls 1.4
import QtSensors 5.0 import QtSensors 5.0
@@ -47,6 +47,20 @@ ApplicationWindow {
height: 480 height: 480
visible: true 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 { Image {
id: bubble id: bubble
source: "Bluebubble.svg" source: "Bluebubble.svg"
@@ -105,18 +119,4 @@ ApplicationWindow {
function calcRoll(x, y, z) { function calcRoll(x, y, z) {
return -(Math.atan(x / Math.sqrt(y * y + z * z)) * 57.2957795); 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();
}
}
}
} }

View File

@@ -1,24 +1,41 @@
import QtQuick 2.1 import QtQuick 2.5
import QtQuick.Window 2.1 import QtQuick.Controls 1.4
Window { ApplicationWindow {
id: page id: page
visible: true visible: true
width: 360 width: 360
height: 360 height: 360
color: "#343434" 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 { Image {
id: icon id: icon
x: 10 x: 10
y: 20 y: 20
source: "states.png" source: "states.svg"
} }
Rectangle { Rectangle {
id: topLeftRect id: topLeftRect
width: 64 x: 10
height: 64 y: 20
width: 44
height: 44
color: "#00000000" color: "#00000000"
radius: 6 radius: 6
opacity: 1 opacity: 1
@@ -37,8 +54,8 @@ Window {
Rectangle { Rectangle {
id: middleRightRect id: middleRightRect
width: 64 width: 44
height: 64 height: 44
color: "#00000000" color: "#00000000"
radius: 6 radius: 6
anchors.right: parent.right anchors.right: parent.right
@@ -55,8 +72,8 @@ Window {
Rectangle { Rectangle {
id: bottomLeftRect id: bottomLeftRect
width: 64 width: 44
height: 64 height: 44
color: "#00000000" color: "#00000000"
radius: 6 radius: 6
border.width: 1 border.width: 1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="44px"
version="1.1"
viewBox="0 0 44 44"
width="44px"
x="0px"
y="0px"
id="svg2"
inkscape:version="0.47 r22583"
sodipodi:docname="qt.svg">
<metadata
id="metadata18">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs16">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 22 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="44 : 22 : 1"
inkscape:persp3d-origin="22 : 14.666667 : 1"
id="perspective2836" />
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview14"
showgrid="false"
inkscape:zoom="21.454545"
inkscape:cx="49.412871"
inkscape:cy="21.894358"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1"
inkscape:current-layer="g3" />
<g
transform="matrix(0.18308778,0,0,0.18308778,6.6100946,3.2385199)"
id="g3">
<path
d="M 43.09,0.3586 C 40.94,0.0036 38.84,-0.0824 36.81,0.0776 31.968136,0.39505671 27.122677,0.73638425 22.28,1.0696 9.62,2.0816 0,12.4996 0,26.8896 l 0,169.7 14.19,13.2 28.87,-209.42 0.03,-0.011 z"
style="fill:#006225"
id="path5"
sodipodi:nodetypes="cccccccc" />
<path
d="m 174.4,160 c 0,12.5 -7.75,24.07 -17.57,25.77 L 14.23,209.73 V 25.93 C 14.23,9.21 27.57,-2.27 43.12,0.3 l 131.3,21.52 v 138.2 z"
style="fill:#80c342"
id="path7" />
<path
d="m 154.9,80.96 -12.96,-0.598 0,0.278 6.945,0.32 6.016,0 z"
style="fill:#006225"
id="path11" />
<path
d="m 144.6,135.6 c 0.66,0.328 1.43,0.476 2.351,0.476 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 h -6.015 c -1.821,0.832 -3.532,1.457 -5.176,1.848 z"
style="fill:#006225"
id="path13" />
<path
id="path17"
style="fill:#ffffff"
d="m 91.15,132.4 c 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -4.34,0 -7.68,2.535 -10.01,7.625 -2.52,5.543 -3.793,17.04 -3.793,34.44 0,16.82 1.238,28.75 3.734,35.75 2.356,6.672 5.879,9.976 10.5,9.976 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 m 17.98,3.75 c -4.117,9.707 -10.39,16.06 -18.99,19 0.867,4.449 2.176,7.441 3.922,9.019 1.351,1.211 3.433,1.821 6.222,1.821 0.805,0 1.668,-0.055 2.59,-0.157 v 13.12 l -5.961,0.782 c -1.758,0.23 -3.426,0.343 -5.004,0.343 -5.218,0 -9.445,-1.265 -12.62,-3.824 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 1.629,0 3.309,0.102 5.043,0.305 11.95,1.375 20.62,7.016 26.26,16.79 5.535,9.562 8.254,23.27 8.254,41.26 0,16.48 -2,29.45 -6.043,39.02 z M 130.4,45.91 l 11.52,1.238 0,20.21 12.96,0.914 0,12.68 -12.96,-0.598 0,46.33 c 0,4.032 0.445,6.625 1.34,7.789 0.8,1.067 2.046,1.594 3.71,1.594 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 v 11.65 c -5.136,2.258 -10.18,3.598 -15.12,4.02 -0.718,0.055 -1.41,0.086 -2.078,0.086 -4.48,0 -7.906,-1.301 -10.25,-3.934 -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.535 L 118.046,79.25 V 65.66 l 7.586,0.547 4.773,-20.3 z" />
<path
d="m 100.3,166 c 0.809,0 1.672,-0.055 2.59,-0.157 H 98.054 C 98.73,165.949 99.507,166 100.3,166 z"
style="fill:#006225"
id="path19" />
<path
id="path21"
style="fill:#006225"
d="m 84.85,63.98 c 2.336,5.997 3.484,16.92 3.484,32.81 0,17.7 -1.16,29.57 -3.512,35.62 -1.894,4.879 -4.527,7.902 -7.863,9.07 0.965,0.368 1.992,0.551 3.078,0.551 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -1.09,0 -2.117,0.16 -3.082,0.481 h -0.004 c 3.601,1.121 6.379,4.215 8.336,9.261 z m -2.344,114.3 c -0.113,-0.05 -0.227,-0.105 -0.336,-0.16 -0.012,-0.004 -0.023,-0.012 -0.035,-0.015 -0.102,-0.051 -0.207,-0.106 -0.309,-0.157 -0.019,-0.011 -0.039,-0.019 -0.058,-0.031 -0.09,-0.051 -0.184,-0.098 -0.278,-0.148 -0.027,-0.016 -0.054,-0.036 -0.086,-0.051 -0.082,-0.043 -0.164,-0.09 -0.242,-0.137 -0.039,-0.023 -0.078,-0.047 -0.113,-0.07 -0.07,-0.039 -0.145,-0.082 -0.215,-0.125 -0.047,-0.031 -0.094,-0.059 -0.14,-0.09 -0.059,-0.039 -0.118,-0.074 -0.176,-0.113 -0.059,-0.039 -0.114,-0.075 -0.168,-0.114 -0.051,-0.031 -0.102,-0.066 -0.149,-0.097 -0.066,-0.047 -0.132,-0.094 -0.195,-0.137 -0.039,-0.027 -0.078,-0.055 -0.113,-0.082 -0.078,-0.055 -0.153,-0.113 -0.231,-0.172 -0.023,-0.016 -0.05,-0.035 -0.078,-0.055 -0.098,-0.078 -0.199,-0.156 -0.297,-0.234 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 h -6.351 c -10.15,0.008 -18.22,3.977 -24,12.04 -6.855,9.563 -10.34,24.64 -10.34,45.07 0,18.95 2.547,33.44 7.551,43.34 4.934,9.75 12.05,15.56 21.19,17.5 1.989,9.641 5.09,16.16 9.297,19.54 3.176,2.559 7.403,3.824 12.62,3.824 0.098,0 0.199,0 0.297,-0.004 h 5.539 c -3.406,-0.05 -6.383,-0.66 -8.906,-1.828 L 82.498,178.28 z M 128.4,145.6 c -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.57 l -6.226,-0.285 v -13.59 h -6.016 v 3.035 c 0.871,3.273 1.555,6.82 2.063,10.64 l 4.164,0.192 v 51.36 c 0,6.723 1.367,11.62 4.09,14.67 2.343,2.633 5.765,3.934 10.25,3.934 h 6.015 c -4.48,0 -7.906,-1.301 -10.25,-3.934 z m 2.043,-99.66 -6.016,0 -4.668,19.88 5.911,0.422 4.773,-20.3 z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@@ -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$"
}
}

View File

@@ -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
}
}

View File

@@ -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()
}

View File

@@ -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 {
}
}

View File

@@ -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"
}
}
}
}

View File

@@ -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()
}

View File

@@ -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
}
}
}

View File

@@ -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()
}

View File

@@ -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
}
}
}

View File

@@ -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)

View File

@@ -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 <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
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();
}

View File

@@ -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.")
}
}

View File

@@ -0,0 +1,14 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>MainForm.ui.qml</file>
<file>CustomerModelSingleton.qml</file>
<file>Settings.qml</file>
<file>SettingsForm.ui.qml</file>
<file>Notes.qml</file>
<file>NotesForm.ui.qml</file>
<file>History.qml</file>
<file>HistoryTableView.qml</file>
<file>CustomerTableView.qml</file>
</qresource>
</RCC>

View File

@@ -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 +=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -534,30 +534,5 @@
\uicontrol {Copy Table} or \uicontrol {Copy Row} in the context menu. \uicontrol {Copy Table} or \uicontrol {Copy Row} in the context menu.
JavaScript events are shown in the \uicontrol Events view only for applications 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 compiled with Qt 5.3 or later.
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 {<bytecode>} 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
*/ */

View File

@@ -30,8 +30,8 @@
\title Working in Edit Mode \title Working in Edit Mode
This section describes how to use the \uicontrol Edit mode. For more information This section describes how to use the \uicontrol Edit mode. For more
about using the sidebar, see \l{Browsing Project Contents}. information about using the sidebar, see \l{Browsing Project Contents}.
\section1 Using the Editor Toolbar \section1 Using the Editor Toolbar
@@ -41,30 +41,30 @@
\image qtcreator-editortoolbar-symbols.png \image qtcreator-editortoolbar-symbols.png
Use the toolbar to navigate between open files and symbols in use. Use the toolbar to navigate between open files and symbols in use. To browse
To browse backward or forward through your location history, click backward or forward through your location history, click
\inlineimage qtcreator-back.png \inlineimage qtcreator-back.png
(\uicontrol {Go Back}) and \inlineimage qtcreator-forward.png (\uicontrol {Go Back}) and \inlineimage qtcreator-forward.png
(\uicontrol {Go Forward}). (\uicontrol {Go Forward}).
To go to any open file, select it from the \uicontrol{Open files} drop-down menu (1). To go to any open file, select it from the \uicontrol {Open files} drop-down
Right-click the menu title and select \uicontrol {Copy Full Path} to menu (1). Right-click the menu title and select \uicontrol {Copy Full Path}
copy the path and name of the current file to the clipboard. 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 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 \uicontrol Symbols drop-down menu (2). By default, the symbols are displayed
order in which they appear in the file. Right-click the menu title and in the order in which they appear in the file. Right-click the menu title
select \uicontrol {Sort Alphabetically} to arrange the symbols in alphabetic and select \uicontrol {Sort Alphabetically} to arrange the symbols in
order. alphabetic order.
To jump to a line and column in the current file, select the line and column 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 indicator (3) or press \key {Ctrl+L} (or \key {Cmd+L} on OS X) to open the
the locator. Enter the line number and column number in the locator, locator. Enter the line number and column number in the locator, separated
separated by a colon (:). by a colon (:).
To show the file encoding of the current file on the editor toolbar (4), To show the file encoding of the current file on the editor toolbar (4),
select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Display > select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} >
\uicontrol {Display file encoding}. \uicontrol Display > \uicontrol {Display file encoding}.
\note Other convenient ways of navigating in \QC are provided by the \note Other convenient ways of navigating in \QC are provided by the
\l{Searching with the Locator}{locator}, \l{Keyboard Shortcuts} \l{Searching with the Locator}{locator}, \l{Keyboard Shortcuts}
@@ -82,15 +82,16 @@
\list \list
\li To split the editor view into a top and bottom view, select \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 \uicontrol Window > \uicontrol Split, press \key {Ctrl+E, 2}, or
\inlineimage qtcreator-split-button.png select the \inlineimage qtcreator-split-button.png
(\uicontrol Split) button and then select \uicontrol Split. (\uicontrol Split) button and then select \uicontrol Split.
Split command creates views below the currently active editor view. Split command creates views below the currently active editor view.
\li To split the editor view into adjacent views, select \li To split the editor view into adjacent views, select
\uicontrol Window > \uicontrol{Split Side by Side}, press \key{Ctrl+E, 3}, or \uicontrol Window > \uicontrol {Split Side by Side}, press
select \uicontrol {Split > Split Side by Side}. \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 Side by side split command creates views to the right of the
currently active editor view. currently active editor view.
@@ -104,16 +105,17 @@
\endlist \endlist
To move between split views and detached editor windows, select \uicontrol Window To move between split views and detached editor windows, select
> \uicontrol{Go to Next Split or Window} or press \key{Ctrl+E, O}. \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 To remove a split view, place the cursor within the view you want to
remove and select \uicontrol Window > \uicontrol{Remove Current Split}, press remove and select \uicontrol Window > \uicontrol {Remove Current Split},
\key{Ctrl+E, 0}, or select the press \key {Ctrl+E, 0}, or select the
\inlineimage qtcreator-remove-split-button.png \inlineimage qtcreator-remove-split-button.png
(\uicontrol {Remove Split}) button. To remove all but the currently selected split (\uicontrol {Remove Split}) button. To remove all but the currently selected
view, split view, select \uicontrol Window > \uicontrol {Remove All Splits} or
select \uicontrol Window > \uicontrol{Remove All Splits} or press \key{Ctrl+E, 1}. press \key {Ctrl+E, 1}.
\section1 Using Bookmarks \section1 Using Bookmarks
@@ -132,8 +134,8 @@
\image qtcreator-togglebookmark.png \image qtcreator-togglebookmark.png
To add a note to a bookmark, right-click the bookmark and select 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 \uicontrol {Edit Bookmark}. To view the note, move the mouse pointer over
bookmark. the bookmark.
To go to previous bookmark in the current session, press \key {Ctrl+,}. To go to previous bookmark in the current session, press \key {Ctrl+,}.
@@ -142,40 +144,42 @@
\section1 Moving to Symbol Definition or Declaration \section1 Moving to Symbol Definition or Declaration
You can move directly to the definition or the declaration of a symbol by 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 holding the \key Ctrl key and clicking the symbol. If you have multiple
opened, you can open the link in the next split by holding \key Ctrl and splits opened, you can open the link in the next split by holding \key Ctrl
\key Alt while clicking the symbol. and \key Alt while clicking the symbol.
To enable this moving function, select \uicontrol Tools > \uicontrol{Options} > To enable this moving function, select \uicontrol Tools >
\uicontrol{Text Editor} > \uicontrol Behavior > \uicontrol{Enable mouse navigation}. \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 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 and select \uicontrol {Follow Symbol Under Cursor} to move to its definition
declaration. This feature is supported for namespaces, classes, functions, or declaration. This feature is supported for namespaces, classes,
variables, include statements, and macros. functions, variables, include statements, and macros.
To switch between the definition and declaration of a function, place the 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 cursor on either and press \key {Shift+F2} or right-click and select
{Switch Between Function Declaration/Definition}. For example, this allows \uicontrol {Switch Between Function Declaration/Definition}. For example,
you to navigate from anywhere within a function body directly to the function this allows you to navigate from anywhere within a function body directly to
declaration. the function declaration.
Links are opened in the same split by default. To open links in the next 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} split, prepend \key {Ctrl+E} to the shortcut. For example, press
to follow the symbol in the next split. If necessary, the view is \key {Ctrl+E,F2} to follow the symbol in the next split. If necessary, the
automatically split. To change the default behavior, select \uicontrol Tools > view is automatically split. To change the default behavior, select
\uicontrol{Options} > \uicontrol{Text Editor} > \uicontrol Display, and then select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} >
\uicontrol{Always Open Links in Next Split}. Additional symbols are displayed and \uicontrol Display, and then select
switching between definition and declaration is done in another split. \uicontrol {Always Open Links in Next Split}. Additional symbols are
If you change the default behavior, the shortcuts for opening link targets displayed and switching between definition and declaration is done in
in the next split are used to open them in the current split. 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 \section1 Reparsing Externally Changed Files
If source files are modified from outside \QC, the opened files will be If source files are modified from outside \QC, the opened files will be
reparsed automatically. For all other files, you can use \uicontrol{Tools} > reparsed automatically. For all other files, you can use \uicontrol Tools >
\uicontrol{C++} > \uicontrol{Reparse Externally Changed Files} to update the code \uicontrol {C++} > \uicontrol {Reparse Externally Changed Files} to update
model. the code model.
\section1 Inspecting the Code Model \section1 Inspecting the Code Model
@@ -185,14 +189,13 @@
inspection. inspection.
To view information about the C++ code model in the 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 {C++ Code Model Inspector} dialog and write it to a log file,
\uicontrol Tools > \uicontrol C++ > \uicontrol {Inspect C++ Code Model} or press select \uicontrol Tools > \uicontrol {C++} >
\key {Ctrl+Shift+F12}. \uicontrol {Inspect C++ Code Model} or press \key {Ctrl+Shift+F12}.
\QC generates the code model inspection log file in a temporary folder. \QC generates the code model inspection log file in a temporary folder.
\QC underlines semantic errors in olive in the C++ code editor. To \QC underlines semantic errors in olive in the C++ code editor. To check the
check the correct paths for includes that are not resolved or that are correct paths for includes that are not resolved or that are resolved to the
resolved to the wrong file, select \uicontrol {Project Parts} > wrong file, select \uicontrol {Project Parts} > \uicontrol {Include Paths}.
\uicontrol {Include Paths}.
*/ */

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,7 @@
\contentspage {Qt Creator Manual} \contentspage {Qt Creator Manual}
\previouspage creator-build-example-application.html \previouspage creator-build-example-application.html
\page creator-tutorials.html \page creator-tutorials.html
\nextpage creator-qml-application.html \nextpage {Creating a Qt Quick Application}
\title Tutorials \title Tutorials
@@ -51,6 +51,14 @@
Learn how to create a Qt Quick application using Qt Quick Controls Learn how to create a Qt Quick application using Qt Quick Controls
for Android and iOS devices. 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 \endlist
*/ */

View File

@@ -24,7 +24,7 @@
/*! /*!
\contentspage {Qt Creator Manual} \contentspage {Qt Creator Manual}
\previouspage creator-mobile-app-tutorial.html \previouspage {Using Qt Quick UI Forms}
\page creator-project-managing.html \page creator-project-managing.html
\nextpage creator-project-creating.html \nextpage creator-project-creating.html

View File

@@ -139,6 +139,7 @@
\li \l{Creating a Qt Quick Application} \li \l{Creating a Qt Quick Application}
\li \l{Creating a Qt Widget Based Application} \li \l{Creating a Qt Widget Based Application}
\li \l{Creating a Mobile Application} \li \l{Creating a Mobile Application}
\li \l{Using Qt Quick UI Forms}
\endlist \endlist
\endlist \endlist
\li \l{Managing Projects} \li \l{Managing Projects}

View File

@@ -25,8 +25,8 @@
/*! /*!
\contentspage {Qt Creator Manual} \contentspage {Qt Creator Manual}
\previouspage creator-writing-program.html \previouspage creator-writing-program.html
\page creator-mobile-app-tutorial.html \example accelbubble
\nextpage creator-project-managing.html \nextpage {Using Qt Quick UI Forms}
\title Creating a Mobile Application \title Creating a Mobile Application
@@ -61,17 +61,23 @@
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \uicontrol Application > \li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol {Qt Quick Application} > \uicontrol Choose. \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. \li In the \uicontrol {Create in} field, enter the path for the project
For example, \c {C:\Qt\examples}, and then click \uicontrol{Next} (or files, and then click \uicontrol Next (or \uicontrol Continue on
\uicontrol Continue on OS X). OS X).
\li In the \uicontrol {Qt Quick component set} field, select \li In the \uicontrol {Minimal required Qt version} field, select the Qt
\uicontrol {Qt Quick Controls 1.1}. 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 \li Select \l{glossary-buildandrun-kit}{kits} for Android ARM and iPhone
OS, and click \uicontrol{Next}. OS, and click \uicontrol{Next}.
@@ -97,11 +103,8 @@
The main view of the application displays an SVG bubble image at the center The main view of the application displays an SVG bubble image at the center
of the main window. of the main window.
To use the Bluebubble.svg used by the Qt Sensors example, Accel Bubble, in To use \l{accelbubble/Bluebubble.svg}{Bluebubble.svg} in your project,
your project, you must copy it to the project directory (same subdirectory copy it to the project directory (same subdirectory as the QML file).
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}.
The image appears in \uicontrol Resources. You can also use any other The image appears in \uicontrol Resources. You can also use any other
image or a QML type, instead. image or a QML type, instead.
@@ -110,20 +113,21 @@
\li In the \uicontrol Projects view, double-click the main.qml file \li In the \uicontrol Projects view, double-click the main.qml file
to open it in the code editor. 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 Click \uicontrol Design to open the file in \QMLD.
\li In the \uicontrol Navigator, select \uicontrol Label and press \key Delete \li In the \uicontrol Navigator, select \uicontrol Label and press
to delete it. \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 \li In \uicontrol Library > \uicontrol Resources, select Bluebubble.svg
and drag and drop it to the canvas. and drag and drop it to the canvas.
@@ -132,34 +136,23 @@
able to reference the image from other places. able to reference the image from other places.
\li In the code editor, add the following new properties to the image to \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: application starts:
\quotefromfile accelbubble/main.qml \quotefromfile accelbubble/main.qml
\skipto Image \skipto Image
\printuntil bubble.width \printuntil bubble.width
\li Set the x and y position of the image based on the new \li Set the x and y position of the image based on the new properties:
properties:
\dots \dots
\printuntil centerY \printuntil centerY
\skipto /^\}/ \skipto /^\}/
\printuntil } \printuntil }
\endlist \endlist
Here is how the accelbubble.qml file looks after you made the changes: For an example, see \l{accelbubble/main.qml}{main.qml}.
\quotefromfile accelbubble/main.qml
\skipto import QtQuick
\printuntil 1.1
\codeline
\skipto ApplicationWindow
\printuntil true
\skipto Image
\printuntil y:
\skipto /^\}/
\printuntil }
\section1 Moving the Bubble \section1 Moving the Bubble
@@ -275,19 +268,11 @@
If you are using a device running Android v4.2.2, it should prompt you to 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 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 to. To avoid such prompts every time you connect the device, select the
"Always allow from the computer" and select \uicontrol OK. \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}. \li To run the application on the device, press \key {Ctrl+R}.
\endlist \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 /^\}/
*/ */

View File

@@ -25,7 +25,7 @@
/*! /*!
\contentspage {Qt Creator Manual} \contentspage {Qt Creator Manual}
\previouspage creator-tutorials.html \previouspage creator-tutorials.html
\page creator-qml-application.html \example transitions
\nextpage creator-writing-program.html \nextpage creator-writing-program.html
\title Creating a Qt Quick Application \title Creating a Qt Quick Application
@@ -43,6 +43,9 @@
For more information about using \QMLD, see For more information about using \QMLD, see
\l{Developing Qt Quick Applications}. \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 \section1 Creating the Project
\list 1 \list 1
@@ -50,20 +53,19 @@
\li Select \uicontrol{File > New File or Project > Application > \li Select \uicontrol{File > New File or Project > Application >
Qt Quick Application > Choose}. 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. \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 For example, \c {C:\Qt\examples}, and then click \uicontrol{Next} (on
Windows and Linux) or \uicontrol Continue (on OS X). Windows and Linux) or \uicontrol Continue (on OS X).
\li In the \uicontrol {Qt Quick component set} field, select \li In the \uicontrol {Minimal required Qt version} field, select the Qt
\uicontrol {Qt Quick 2.1}. 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 generates and their contents. The instructions in this tutorial
might not apply if you select some other component set, such as Qt might not apply if you select the \uicontrol {With .ui.qml file}
Quick 2.4. The wizard indicates which Qt version each component set check box.
requires at minimum.
\li Select \l{glossary-buildandrun-kit}{kits} for running and building your project, \li Select \l{glossary-buildandrun-kit}{kits} for running and building your project,
and then click \uicontrol{Next}. and then click \uicontrol{Next}.
@@ -93,7 +95,7 @@
The main view of the application displays a Qt logo in the top left corner The main view of the application displays a Qt logo in the top left corner
of the screen and two empty rectangles. 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 project directory (same subdirectory as the QML file) from the examples
directory in the Qt installation directory. For example: directory in the Qt installation directory. For example:
\c {C:\Qt\Examples\Qt-5.4\declarative\animation\states}. The image appears \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" \image qmldesigner-tutorial-design-mode.png "Transitions project in Design Mode"
\li In the \uicontrol Navigator, select \uicontrol MouseArea and \li In the \uicontrol Navigator, select \uicontrol Label and press
\uicontrol Text and press \key Delete to delete them. \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" \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 \li In the \uicontrol Id field, enter \e page, to be able to reference the
window from other places. 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 \li In the \uicontrol Color field, set the window background color
to #343434. to \e #343434.
\endlist \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. drag and drop it to the canvas.
\image qmldesigner-tutorial-user-icon.png "Image properties" \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 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 \endlist
\li Right-click the resource file, qml.qrc, in the \uicontrol Projects \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. 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, \li In the \uicontrol Design mode, \uicontrol Library view, \uicontrol {QML Types} tab,
select \uicontrol Rectangle, select \uicontrol Rectangle,
@@ -155,26 +164,21 @@
\li In the \uicontrol Id field, enter \e topLeftRect. \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 \li In the \uicontrol Size field, set \uicontrol W and \uicontrol H
rectangle size to match the image size. to \e 44, for the rectangle size to match the image size.
\li In the \uicontrol Color field, click the \li In the \uicontrol Color field, click the
\inlineimage qmldesigner-transparent-button.png \inlineimage qmldesigner-transparent-button.png
(\uicontrol Transparent) button to make the rectangle transparent. (\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 \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 \li In the \uicontrol Radius field, select \e 6 to create rounded
border color, try setting the border color to solid by clicking corners for the rectangle.
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 Click \uicontrol {Layout}, and then click the top and left anchor \li Click \uicontrol {Layout}, and then click the top and left anchor
buttons to anchor the rectangle to the top left corner of the buttons to anchor the rectangle to the top left corner of the
@@ -182,8 +186,8 @@
\image qmldesigner-tutorial-topleftrect-layout.png "Layout tab" \image qmldesigner-tutorial-topleftrect-layout.png "Layout tab"
\li In the \uicontrol Margin field, select 20 for the top anchor and 10 \li In the \uicontrol Margin field, select \e 20 for the top anchor
for the left anchor. and \e 10 for the left anchor.
\endlist \endlist
@@ -235,8 +239,8 @@
then the right anchor button to then the right anchor button to
anchor the rectangle to the middle right margin of the screen. 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 \li In the \uicontrol Margin field, select \e 10 for the right
for the vertical center anchor. anchor and \e 0 for the vertical center anchor.
\li In the code editor, add a pointer to a clicked expression to the \li In the code editor, add a pointer to a clicked expression to the
mouse area. The following expression sets the state to 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 \li In \uicontrol {Layout}, select the bottom and left anchor buttons to
anchor the rectangle to the bottom left margin of the screen. 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 \li In the \uicontrol Margin field, select \e 20 for the bottom
for the left anchor. anchor and \e 10 for the left anchor.
\li In the code editor, add a pointer to a clicked expression to the \li In the code editor, add a pointer to a clicked expression to the
mouse area. The following expression sets the state to mouse area. The following expression sets the state to
@@ -370,13 +374,4 @@
\endlist \endlist
Click the rectangles to view the animated transitions. 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 /^\}/
*/ */

View File

@@ -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}.
*/

View File

@@ -24,9 +24,9 @@
/*! /*!
\contentspage {Qt Creator Manual} \contentspage {Qt Creator Manual}
\previouspage creator-qml-application.html \previouspage {Creating a Qt Quick Application}
\page creator-writing-program.html \page creator-writing-program.html
\nextpage creator-mobile-app-tutorial.html \nextpage {Creating a Mobile Application}
\title Creating a Qt Widget Based Application \title Creating a Qt Widget Based Application

View File

@@ -27,6 +27,6 @@ QtcProduct {
Export { Export {
Depends { name: "cpp" } Depends { name: "cpp" }
cpp.includePaths: [libIncludeBase] cpp.includePaths: [product.libIncludeBase]
} }
} }

View File

@@ -52,6 +52,6 @@ QtcProduct {
Export { Export {
Depends { name: "ExtensionSystem" } Depends { name: "ExtensionSystem" }
Depends { name: "cpp" } Depends { name: "cpp" }
cpp.includePaths: [pluginIncludeBase] cpp.includePaths: [product.pluginIncludeBase]
} }
} }

View File

@@ -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" installer.commands = python -u $$PWD/scripts/packageIfw.py -i \"$(IFW_PATH)\" -v $${QTCREATOR_VERSION} -a \"$${INSTALLER_ARCHIVE}\" "$$INSTALLER_NAME"
macx { 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\" 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 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 { win32 {

View File

@@ -91,7 +91,8 @@ def fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames):
for filename in filenames: for filename in filenames:
fpath = os.path.join(dirpath, filename) fpath = os.path.join(dirpath, filename)
relpath = os.path.relpath(install_dir+'/lib/qtcreator', dirpath) 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 print fpath, ':', command
try: try:
subprocess.check_call(command) subprocess.check_call(command)
@@ -215,20 +216,31 @@ def copy_translations(install_dir, qt_tr_dir):
print translation, '->', tr_dir print translation, '->', tr_dir
shutil.copy(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): def copy_libclang(install_dir, llvm_install_dir):
libsource = "" libsources = []
libtarget = "" libtarget = ""
if sys.platform.startswith("win"): 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') libtarget = os.path.join(install_dir, 'bin')
else: 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') libtarget = os.path.join(install_dir, 'lib', 'qtcreator')
resourcesource = os.path.join(llvm_install_dir, 'lib', 'clang') resourcesource = os.path.join(llvm_install_dir, 'lib', 'clang')
resourcetarget = os.path.join(install_dir, 'share', 'qtcreator', 'cplusplus', 'clang') resourcetarget = os.path.join(install_dir, 'share', 'qtcreator', 'cplusplus', 'clang')
print "copying libclang..." print "copying libclang..."
for libsource in libsources:
print libsource, '->', libtarget print libsource, '->', libtarget
shutil.copy(libsource, libtarget) copyPreservingLinks(libsource, libtarget)
print resourcesource, '->', resourcetarget print resourcesource, '->', resourcetarget
if (os.path.exists(resourcetarget)): if (os.path.exists(resourcetarget)):
shutil.rmtree(resourcetarget) shutil.rmtree(resourcetarget)

View File

@@ -57,7 +57,9 @@ fi
if [ $LLVM_INSTALL_DIR ]; then if [ $LLVM_INSTALL_DIR ]; then
if [ "$LLVM_INSTALL_DIR"/lib/libclang.dylib -nt "$1/Contents/PlugIns"/libclang.dylib ]; then if [ "$LLVM_INSTALL_DIR"/lib/libclang.dylib -nt "$1/Contents/PlugIns"/libclang.dylib ]; then
echo "- Copying libclang" 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 cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$1/Contents/Resources/cplusplus/" || exit 1
fi fi
_CLANG_CODEMODEL_LIB="$1/Contents/PlugIns/libClangCodeModel_debug.dylib" _CLANG_CODEMODEL_LIB="$1/Contents/PlugIns/libClangCodeModel_debug.dylib"
@@ -66,7 +68,8 @@ if [ $LLVM_INSTALL_DIR ]; then
fi fi
# this will just fail when run a second time on libClangCodeModel # 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 -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 fi
#### macdeployqt #### macdeployqt
@@ -93,7 +96,8 @@ if [ ! -d "$1/Contents/Frameworks/QtCore.framework" ]; then
"-executable=$1/Contents/Resources/ios/iostool" \ "-executable=$1/Contents/Resources/ios/iostool" \
"-executable=$1/Contents/Resources/ios/iossim" \ "-executable=$1/Contents/Resources/ios/iossim" \
"-executable=$1/Contents/Resources/ios/iossim_1_8_2" \ "-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" \
"-executable=$qbsapp-config" \ "-executable=$qbsapp-config" \
"-executable=$qbsapp-config-ui" \ "-executable=$qbsapp-config-ui" \
@@ -101,6 +105,6 @@ if [ ! -d "$1/Contents/Frameworks/QtCore.framework" ]; then
"-executable=$qbsapp-setup-android" \ "-executable=$qbsapp-setup-android" \
"-executable=$qbsapp-setup-qt" \ "-executable=$qbsapp-setup-qt" \
"-executable=$qbsapp-setup-toolchains" \ "-executable=$qbsapp-setup-toolchains" \
"$qmlpuppetArgument" "$qml2puppetArgument" || exit 1 "$qmlpuppetArgument" "$qml2puppetArgument" "$clangbackendArgument" || exit 1
fi fi

View File

@@ -30,16 +30,24 @@
#define QT_NO_META_MACROS #define QT_NO_META_MACROS
#if defined(QT_NO_KEYWORDS)
# define QT_NO_EMIT
#else
# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS
# define signals public __attribute__((annotate("qt_signal"))) # define signals public __attribute__((annotate("qt_signal")))
# define slots __attribute__((annotate("qt_slot"))) # define slots __attribute__((annotate("qt_slot")))
#define Q_SIGNALS signals # endif
#define Q_SLOTS slots #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_SIGNAL __attribute__((annotate("qt_signal")))
#define Q_SLOT __attribute__((annotate("qt_slot"))) #define Q_SLOT __attribute__((annotate("qt_slot")))
#define Q_PRIVATE_SLOT(d, signature) #define Q_PRIVATE_SLOT(d, signature)
#define Q_EMIT #define Q_EMIT
#ifndef QT_NO_EMIT
# define emit # define emit
#endif
#define Q_CLASSINFO(name, value) #define Q_CLASSINFO(name, value)
#define Q_PLUGIN_METADATA(x) #define Q_PLUGIN_METADATA(x)
#define Q_INTERFACES(x) #define Q_INTERFACES(x)
@@ -49,6 +57,8 @@
#define Q_OVERRIDE(text) #define Q_OVERRIDE(text)
#define Q_ENUMS(x) #define Q_ENUMS(x)
#define Q_FLAGS(x) #define Q_FLAGS(x)
#define Q_ENUM(x)
#define Q_FLAG(x)
#define Q_SCRIPTABLE #define Q_SCRIPTABLE
#define Q_INVOKABLE #define Q_INVOKABLE

View File

@@ -26,7 +26,7 @@ from dumper import *
# #
####################################################################### #######################################################################
def savePrint(output): def safePrint(output):
try: try:
print(output) print(output)
except: except:
@@ -47,7 +47,7 @@ def registerCommand(name, func):
def __init__(self): def __init__(self):
super(Command, self).__init__(name, gdb.COMMAND_OBSCURE) super(Command, self).__init__(name, gdb.COMMAND_OBSCURE)
def invoke(self, args, from_tty): def invoke(self, args, from_tty):
savePrint(func(args)) safePrint(func(args))
Command() Command()
@@ -130,7 +130,7 @@ class ScanStackCommand(gdb.Command):
def invoke(self, args, from_tty): def invoke(self, args, from_tty):
if len(args) == 0: if len(args) == 0:
args = 20 args = 20
savePrint(scanStack(gdb.parse_and_eval("$sp"), int(args))) safePrint(scanStack(gdb.parse_and_eval("$sp"), int(args)))
ScanStackCommand() ScanStackCommand()
@@ -438,7 +438,7 @@ class Dumper(DumperBase):
self.output.append(',partial="%d"' % isPartial) self.output.append(',partial="%d"' % isPartial)
print(''.join(self.output)) safePrint(''.join(self.output))
def enterSubItem(self, item): def enterSubItem(self, item):
if not item.iname: if not item.iname:
@@ -1619,7 +1619,7 @@ class Dumper(DumperBase):
frame = frame.older() frame = frame.older()
i += 1 i += 1
print(''.join(self.output)) safePrint(''.join(self.output))
def createResolvePendingBreakpointsHookBreakpoint(self, args): def createResolvePendingBreakpointsHookBreakpoint(self, args):
class Resolver(gdb.Breakpoint): class Resolver(gdb.Breakpoint):

View File

@@ -15,7 +15,8 @@
{ "key": "ProFileName", "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'pro')}" }, { "key": "ProFileName", "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'pro')}" },
{ "key": "MainCppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" }, { "key": "MainCppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" },
{ "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" }, { "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": "pages":
@@ -86,13 +87,7 @@
"typeId": "Kits", "typeId": "Kits",
"data": { "data": {
"projectFilePath": "%{ProFileName}", "projectFilePath": "%{ProFileName}",
"requiredFeatures": "requiredFeatures": [ "QtSupport.Wizards.FeatureQt", "%{QtQuickFeature}" ]
[
"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'}" }
]
} }
}, },
{ {

View File

@@ -17,7 +17,8 @@
{ "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" }, { "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" },
{ "key": "QtQuickControlsVersion", "value": "%{JS: %{QtVersion}.qtQuickControlsVersion}" }, { "key": "QtQuickControlsVersion", "value": "%{JS: %{QtVersion}.qtQuickControlsVersion}" },
{ "key": "QtQuickDialogsVersion", "value": "%{JS: %{QtVersion}.qtQuickDialogsVersion}" }, { "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": "pages":
@@ -46,7 +47,7 @@
"value": "value":
"{ "{
'qtQuickVersion': '2.5', 'qtQuickVersion': '2.5',
'qtQuickControlsVersion': '1.3', 'qtQuickControlsVersion': '1.4',
'qtQuickDialogsVersion': '1.2', 'qtQuickDialogsVersion': '1.2',
'qtQuickLayoutsVersion': '1.2' 'qtQuickLayoutsVersion': '1.2'
}", }",
@@ -57,7 +58,7 @@
"value": "value":
"{ "{
'qtQuickVersion': '2.4', 'qtQuickVersion': '2.4',
'qtQuickControlsVersion': '1.2', 'qtQuickControlsVersion': '1.3',
'qtQuickDialogsVersion': '1.2', 'qtQuickDialogsVersion': '1.2',
'qtQuickLayoutsVersion': '1.1' 'qtQuickLayoutsVersion': '1.1'
}", }",
@@ -103,12 +104,7 @@
"typeId": "Kits", "typeId": "Kits",
"data": { "data": {
"projectFilePath": "%{ProFileName}", "projectFilePath": "%{ProFileName}",
"requiredFeatures": "requiredFeatures": [ "QtSupport.Wizards.FeatureQt", "%{QtQuickFeature}" ]
[
"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' }" }
]
} }
}, },
{ {

View File

@@ -3348,7 +3348,7 @@ public:
DeclarationAST *declaration; DeclarationAST *declaration;
public: // annotations public: // annotations
Template *symbol; Scope *symbol;
public: public:
TemplateDeclarationAST() TemplateDeclarationAST()

View File

@@ -2367,11 +2367,15 @@ bool Bind::visit(ParameterDeclarationAST *ast)
bool Bind::visit(TemplateDeclarationAST *ast) bool Bind::visit(TemplateDeclarationAST *ast)
{ {
Template *templ = control()->newTemplate(ast->firstToken(), 0); Scope *scope = 0;
templ->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin()); if (ast->less_token)
templ->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd()); scope = control()->newTemplate(ast->firstToken(), 0);
ast->symbol = templ; else
Scope *previousScope = switchScope(templ); 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) { for (DeclarationListAST *it = ast->template_parameter_list; it; it = it->next) {
this->declaration(it->value); this->declaration(it->value);
@@ -2380,12 +2384,17 @@ bool Bind::visit(TemplateDeclarationAST *ast)
this->declaration(ast->declaration); this->declaration(ast->declaration);
(void) switchScope(previousScope); (void) switchScope(previousScope);
if (Symbol *decl = templ->declaration()) { Symbol *decl = 0;
templ->setSourceLocation(decl->sourceLocation(), translationUnit()); if (Template *templ = scope->asTemplate())
templ->setName(decl->name()); 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; return false;
} }

View File

@@ -112,6 +112,7 @@ class Function;
class Namespace; class Namespace;
class NamespaceAlias; class NamespaceAlias;
class Template; class Template;
class ExplicitInstantiation;
class BaseClass; class BaseClass;
class Block; class Block;
class Class; class Class;

View File

@@ -366,9 +366,16 @@ public:
Template *newTemplate(unsigned sourceLocation, const Name *name) Template *newTemplate(unsigned sourceLocation, const Name *name)
{ {
Template *ns = new Template(translationUnit, sourceLocation, name); Template *templ = new Template(translationUnit, sourceLocation, name);
symbols.push_back(ns); symbols.push_back(templ);
return ns; 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) 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) Template *Control::newTemplate(unsigned sourceLocation, const Name *name)
{ return d->newTemplate(sourceLocation, 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) NamespaceAlias *Control::newNamespaceAlias(unsigned sourceLocation, const Name *name)
{ return d->newNamespaceAlias(sourceLocation, name); } { return d->newNamespaceAlias(sourceLocation, name); }

View File

@@ -120,6 +120,9 @@ public:
/// Creates a new Template symbol. /// Creates a new Template symbol.
Template *newTemplate(unsigned sourceLocation, const Name *name = 0); 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. /// Creates a new Namespace symbol.
NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0); NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0);

View File

@@ -218,6 +218,17 @@ bool Matcher::match(const Template *type, const Template *otherType)
return true; 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) bool Matcher::match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType)
{ {
if (type == otherType) if (type == otherType)

View File

@@ -61,6 +61,7 @@ public:
virtual bool match(const Enum *type, const Enum *otherType); virtual bool match(const Enum *type, const Enum *otherType);
virtual bool match(const Namespace *type, const Namespace *otherType); virtual bool match(const Namespace *type, const Namespace *otherType);
virtual bool match(const Template *type, const Template *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 ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType);
virtual bool match(const Class *type, const Class *otherType); virtual bool match(const Class *type, const Class *otherType);
virtual bool match(const ObjCClass *type, const ObjCClass *otherType); virtual bool match(const ObjCClass *type, const ObjCClass *otherType);

View File

@@ -361,6 +361,9 @@ bool Symbol::isNamespace() const
bool Symbol::isTemplate() const bool Symbol::isTemplate() const
{ return asTemplate() != 0; } { return asTemplate() != 0; }
bool Symbol::isExplicitInstantiation() const
{ return asExplicitInstantiation() != 0; }
bool Symbol::isClass() const bool Symbol::isClass() const
{ return asClass() != 0; } { return asClass() != 0; }

View File

@@ -135,7 +135,7 @@ public:
/// Returns true if this Symbol is an Enum. /// Returns true if this Symbol is an Enum.
bool isEnum() const; bool isEnum() const;
/// Returns true if this Symbol is an Function. /// Returns true if this Symbol is a Function.
bool isFunction() const; bool isFunction() const;
/// Returns true if this Symbol is a Namespace. /// Returns true if this Symbol is a Namespace.
@@ -144,6 +144,9 @@ public:
/// Returns true if this Symbol is a Template. /// Returns true if this Symbol is a Template.
bool isTemplate() const; bool isTemplate() const;
/// Returns true if this Symbol is an ExplicitInstantiation.
bool isExplicitInstantiation() const;
/// Returns true if this Symbol is a Class. /// Returns true if this Symbol is a Class.
bool isClass() const; bool isClass() const;
@@ -203,6 +206,7 @@ public:
virtual const Function *asFunction() const { return 0; } virtual const Function *asFunction() const { return 0; }
virtual const Namespace *asNamespace() const { return 0; } virtual const Namespace *asNamespace() const { return 0; }
virtual const Template *asTemplate() 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 NamespaceAlias *asNamespaceAlias() const { return 0; }
virtual const Class *asClass() const { return 0; } virtual const Class *asClass() const { return 0; }
virtual const Block *asBlock() const { return 0; } virtual const Block *asBlock() const { return 0; }
@@ -229,6 +233,7 @@ public:
virtual Function *asFunction() { return 0; } virtual Function *asFunction() { return 0; }
virtual Namespace *asNamespace() { return 0; } virtual Namespace *asNamespace() { return 0; }
virtual Template *asTemplate() { return 0; } virtual Template *asTemplate() { return 0; }
virtual ExplicitInstantiation *asExplicitInstantiation() { return 0; }
virtual NamespaceAlias *asNamespaceAlias() { return 0; } virtual NamespaceAlias *asNamespaceAlias() { return 0; }
virtual Class *asClass() { return 0; } virtual Class *asClass() { return 0; }
virtual Block *asBlock() { return 0; } virtual Block *asBlock() { return 0; }

View File

@@ -51,6 +51,7 @@ public:
virtual bool visit(Function *) { return true; } virtual bool visit(Function *) { return true; }
virtual bool visit(Namespace *) { return true; } virtual bool visit(Namespace *) { return true; }
virtual bool visit(Template *) { return true; } virtual bool visit(Template *) { return true; }
virtual bool visit(ExplicitInstantiation *) { return true; }
virtual bool visit(Class *) { return true; } virtual bool visit(Class *) { return true; }
virtual bool visit(Block *) { return true; } virtual bool visit(Block *) { return true; }
virtual bool visit(ForwardClassDeclaration *) { return true; } virtual bool visit(ForwardClassDeclaration *) { return true; }

View File

@@ -481,10 +481,12 @@ void Enum::visitSymbol0(SymbolVisitor *visitor)
Template::Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name) Template::Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name) : Scope(translationUnit, sourceLocation, name)
, _isExplicitInstantiation(false)
{ } { }
Template::Template(Clone *clone, Subst *subst, Template *original) Template::Template(Clone *clone, Subst *subst, Template *original)
: Scope(clone, subst, original) : Scope(clone, subst, original)
, _isExplicitInstantiation(original->_isExplicitInstantiation)
{ } { }
Template::~Template() Template::~Template()
@@ -537,6 +539,56 @@ bool Template::match0(const Type *otherType, Matcher *matcher) const
return false; 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<ExplicitInstantiation *>(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) Namespace::Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name) : Scope(translationUnit, sourceLocation, name)
, _isInline(false) , _isInline(false)

View File

@@ -423,8 +423,41 @@ protected:
virtual void visitSymbol0(SymbolVisitor *visitor); virtual void visitSymbol0(SymbolVisitor *visitor);
virtual void accept0(TypeVisitor *visitor); virtual void accept0(TypeVisitor *visitor);
virtual bool match0(const Type *otherType, Matcher *matcher) const; 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 class CPLUSPLUS_EXPORT Namespace: public Scope, public Type
{ {

View File

@@ -125,6 +125,12 @@ void CloneType::visit(Template *type)
_type = templ; _type = templ;
} }
void CloneType::visit(ExplicitInstantiation *type)
{
ExplicitInstantiation *inst = _clone->symbol(type, _subst)->asExplicitInstantiation();
_type = inst;
}
void CloneType::visit(Class *type) void CloneType::visit(Class *type)
{ {
Class *klass = _clone->symbol(type, _subst)->asClass(); Class *klass = _clone->symbol(type, _subst)->asClass();
@@ -291,6 +297,14 @@ bool CloneSymbol::visit(Template *symbol)
return false; 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) bool CloneSymbol::visit(Class *symbol)
{ {
Class *klass = new Class(_clone, _subst, symbol); Class *klass = new Class(_clone, _subst, symbol);

View File

@@ -85,6 +85,7 @@ protected:
virtual void visit(Function *type); virtual void visit(Function *type);
virtual void visit(Namespace *type); virtual void visit(Namespace *type);
virtual void visit(Template *type); virtual void visit(Template *type);
virtual void visit(ExplicitInstantiation *type);
virtual void visit(Class *type); virtual void visit(Class *type);
virtual void visit(Enum *type); virtual void visit(Enum *type);
virtual void visit(ForwardClassDeclaration *type); virtual void visit(ForwardClassDeclaration *type);
@@ -152,6 +153,7 @@ protected:
virtual bool visit(Function *symbol); virtual bool visit(Function *symbol);
virtual bool visit(Namespace *symbol); virtual bool visit(Namespace *symbol);
virtual bool visit(Template *symbol); virtual bool visit(Template *symbol);
virtual bool visit(ExplicitInstantiation *symbol);
virtual bool visit(Class *symbol); virtual bool visit(Class *symbol);
virtual bool visit(Block *symbol); virtual bool visit(Block *symbol);
virtual bool visit(ForwardClassDeclaration *symbol); virtual bool visit(ForwardClassDeclaration *symbol);

View File

@@ -68,6 +68,9 @@ bool Type::isNamespaceType() const
bool Type::isTemplateType() const bool Type::isTemplateType() const
{ return asTemplateType() != 0; } { return asTemplateType() != 0; }
bool Type::isExplicitInstantiationType() const
{ return asExplicitInstantiationType() != 0; }
bool Type::isClassType() const bool Type::isClassType() const
{ return asClassType() != 0; } { return asClassType() != 0; }

View File

@@ -43,6 +43,7 @@ public:
bool isFunctionType() const; bool isFunctionType() const;
bool isNamespaceType() const; bool isNamespaceType() const;
bool isTemplateType() const; bool isTemplateType() const;
bool isExplicitInstantiationType() const;
bool isClassType() const; bool isClassType() const;
bool isEnumType() const; bool isEnumType() const;
bool isForwardClassDeclarationType() const; bool isForwardClassDeclarationType() const;
@@ -64,6 +65,7 @@ public:
virtual const Function *asFunctionType() const { return 0; } virtual const Function *asFunctionType() const { return 0; }
virtual const Namespace *asNamespaceType() const { return 0; } virtual const Namespace *asNamespaceType() const { return 0; }
virtual const Template *asTemplateType() 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 Class *asClassType() const { return 0; }
virtual const Enum *asEnumType() const { return 0; } virtual const Enum *asEnumType() const { return 0; }
virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; } virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; }
@@ -85,6 +87,7 @@ public:
virtual Function *asFunctionType() { return 0; } virtual Function *asFunctionType() { return 0; }
virtual Namespace *asNamespaceType() { return 0; } virtual Namespace *asNamespaceType() { return 0; }
virtual Template *asTemplateType() { return 0; } virtual Template *asTemplateType() { return 0; }
virtual ExplicitInstantiation *asExplicitInstantiationType() { return 0; }
virtual Class *asClassType() { return 0; } virtual Class *asClassType() { return 0; }
virtual Enum *asEnumType() { return 0; } virtual Enum *asEnumType() { return 0; }
virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; } virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; }

View File

@@ -51,6 +51,7 @@ public:
virtual void visit(Function *) {} virtual void visit(Function *) {}
virtual void visit(Namespace *) {} virtual void visit(Namespace *) {}
virtual void visit(Template *) {} virtual void visit(Template *) {}
virtual void visit(ExplicitInstantiation *) {}
virtual void visit(Class *) {} virtual void visit(Class *) {}
virtual void visit(Enum *) {} virtual void visit(Enum *) {}
virtual void visit(ForwardClassDeclaration *) {} virtual void visit(ForwardClassDeclaration *) {}

View File

@@ -35,8 +35,8 @@ SOURCES += $$PWD/ipcserverinterface.cpp \
$$PWD/translationunitdoesnotexistcommand.cpp \ $$PWD/translationunitdoesnotexistcommand.cpp \
$$PWD/codecompletionchunk.cpp \ $$PWD/codecompletionchunk.cpp \
$$PWD/projectpartcontainer.cpp \ $$PWD/projectpartcontainer.cpp \
$$PWD/projectpartsdonotexistcommand.cpp $$PWD/projectpartsdonotexistcommand.cpp \
$$PWD/lineprefixer.cpp
HEADERS += \ HEADERS += \
$$PWD/ipcserverinterface.h \ $$PWD/ipcserverinterface.h \
@@ -66,6 +66,7 @@ HEADERS += \
$$PWD/projectpartcontainer.h \ $$PWD/projectpartcontainer.h \
$$PWD/projectpartsdonotexistcommand.h \ $$PWD/projectpartsdonotexistcommand.h \
$$PWD/container_common.h \ $$PWD/container_common.h \
$$PWD/clangbackendipc_global.h $$PWD/clangbackendipc_global.h \
$$PWD/lineprefixer.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -6,7 +6,7 @@ QtcLibrary {
Depends { name: "Qt.network" } Depends { name: "Qt.network" }
Depends { name: "Sqlite" } Depends { name: "Sqlite" }
cpp.defines: base.concat("CLANGIPC_LIBRARY") cpp.defines: base.concat("CLANGBACKENDIPC_LIBRARY")
cpp.includePaths: base.concat(".") cpp.includePaths: base.concat(".")
Group { Group {

View File

@@ -54,7 +54,9 @@ QString connectionName()
ConnectionClient::ConnectionClient(IpcClientInterface *client) ConnectionClient::ConnectionClient(IpcClientInterface *client)
: serverProxy_(client, &localSocket), : serverProxy_(client, &localSocket),
isAliveTimerResetted(false) isAliveTimerResetted(false),
stdErrPrefixer("ClangBackEnd-StdErr: "),
stdOutPrefixer("ClangBackEnd: ")
{ {
processAliveTimer.setInterval(10000); processAliveTimer.setInterval(10000);
@@ -95,10 +97,17 @@ bool ConnectionClient::isConnected() const
return localSocket.state() == QLocalSocket::ConnectedState; return localSocket.state() == QLocalSocket::ConnectedState;
} }
void ConnectionClient::ensureCommandIsWritten()
{
while (localSocket.bytesToWrite() > 0)
localSocket.waitForBytesWritten();
}
void ConnectionClient::sendEndCommand() void ConnectionClient::sendEndCommand()
{ {
serverProxy_.end(); serverProxy_.end();
localSocket.flush(); localSocket.flush();
ensureCommandIsWritten();
} }
void ConnectionClient::resetProcessAliveTimer() void ConnectionClient::resetProcessAliveTimer()
@@ -148,8 +157,6 @@ void ConnectionClient::restartProcessIfTimerIsNotResettedAndSocketIsEmpty()
bool ConnectionClient::connectToLocalSocket() bool ConnectionClient::connectToLocalSocket()
{ {
QThread::msleep(30);
for (int counter = 0; counter < 1000; counter++) { for (int counter = 0; counter < 1000; counter++) {
localSocket.connectToServer(connectionName()); localSocket.connectToServer(connectionName());
bool isConnected = localSocket.waitForConnected(20); bool isConnected = localSocket.waitForConnected(20);
@@ -191,19 +198,20 @@ void ConnectionClient::killProcess()
} }
} }
void ConnectionClient::printLocalSocketError(QLocalSocket::LocalSocketError /*socketError*/) void ConnectionClient::printLocalSocketError(QLocalSocket::LocalSocketError socketError)
{ {
if (socketError != QLocalSocket::ServerNotFoundError)
qWarning() << "ClangCodeModel ConnectionClient LocalSocket Error:" << localSocket.errorString(); qWarning() << "ClangCodeModel ConnectionClient LocalSocket Error:" << localSocket.errorString();
} }
void ConnectionClient::printStandardOutput() void ConnectionClient::printStandardOutput()
{ {
qWarning() << "ClangBackEnd:" << process_->readAllStandardOutput(); QTextStream(stdout) << stdOutPrefixer.prefix(process_->readAllStandardOutput());
} }
void ConnectionClient::printStandardError() void ConnectionClient::printStandardError()
{ {
qWarning() << "ClangBackEnd Error:" << process_->readAllStandardError(); QTextStream(stderr) << stdErrPrefixer.prefix(process_->readAllStandardError());
} }
void ConnectionClient::finishProcess() void ConnectionClient::finishProcess()

View File

@@ -32,6 +32,7 @@
#define CLANGBACKEND_CONNECTIONCLIENT_H #define CLANGBACKEND_CONNECTIONCLIENT_H
#include "ipcserverproxy.h" #include "ipcserverproxy.h"
#include "lineprefixer.h"
#include <QLocalSocket> #include <QLocalSocket>
@@ -97,7 +98,7 @@ private:
void disconnectProcessFinished() const; void disconnectProcessFinished() const;
void connectStandardOutputAndError() const; void connectStandardOutputAndError() const;
void waitUntilSocketIsFlushed() const; void ensureCommandIsWritten();
private: private:
mutable std::unique_ptr<QProcess> process_; mutable std::unique_ptr<QProcess> process_;
@@ -106,6 +107,9 @@ private:
QTimer processAliveTimer; QTimer processAliveTimer;
QString processPath_; QString processPath_;
bool isAliveTimerResetted; bool isAliveTimerResetted;
LinePrefixer stdErrPrefixer;
LinePrefixer stdOutPrefixer;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -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

View File

@@ -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 <QString>
#include <QTextStream>
#include <utf8string.h>
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

View File

@@ -82,12 +82,19 @@ bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &se
return first.projectPartId_ < second.projectPartId_; 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) QDebug operator<<(QDebug debug, const ProjectPartContainer &container)
{ {
debug.nospace() << "ProjectPartContainer(" debug.nospace() << "ProjectPartContainer("
<< container.projectPartId() << container.projectPartId()
<< "," << ","
<< container.arguments() << quotedArguments(container.arguments())
<< ")"; << ")";
return debug; return debug;

View File

@@ -1021,7 +1021,7 @@ LookupScope *LookupScope::lookupType(const Name *name, Block *block)
LookupScope *LookupScope::findType(const Name *name) LookupScope *LookupScope::findType(const Name *name)
{ {
ProcessedSet processed; 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( LookupScope *Internal::LookupScopePrivate::findBlock_helper(
@@ -1830,6 +1830,12 @@ bool CreateBindings::visit(Template *templ)
return false; return false;
} }
bool CreateBindings::visit(ExplicitInstantiation *inst)
{
Q_UNUSED(inst);
return false;
}
bool CreateBindings::visit(Namespace *ns) bool CreateBindings::visit(Namespace *ns)
{ {
LookupScope *previous = enterLookupScopeBinding(ns); LookupScope *previous = enterLookupScopeBinding(ns);

View File

@@ -178,6 +178,7 @@ protected:
void process(Symbol *root); void process(Symbol *root);
virtual bool visit(Template *templ); virtual bool visit(Template *templ);
virtual bool visit(ExplicitInstantiation *inst);
virtual bool visit(Namespace *ns); virtual bool visit(Namespace *ns);
virtual bool visit(Class *klass); virtual bool visit(Class *klass);
virtual bool visit(ForwardClassDeclaration *klass); virtual bool visit(ForwardClassDeclaration *klass);

View File

@@ -154,6 +154,13 @@ QList<LookupItem> TypeResolver::typedefsFromScopeUpToFunctionScope(const Name *n
} }
} }
enclosingBlockScope = block->enclosingScope(); 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; return results;
} }

View File

@@ -1,3 +1,2 @@
QTC_LIB_NAME = Sqlite QTC_LIB_NAME = Sqlite
INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/3rdparty/sqlite
INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/sqlite INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/sqlite

View File

@@ -96,7 +96,7 @@ inline const char *botanEmsaAlgoName(const QByteArray &rfcAlgoName)
return "EMSA1(SHA-1)"; return "EMSA1(SHA-1)";
if (rfcAlgoName == SshCapabilities::PubKeyRsa) if (rfcAlgoName == SshCapabilities::PubKeyRsa)
return "EMSA3(SHA-1)"; return "EMSA3(SHA-1)";
if (rfcAlgoName == SshCapabilities::PubKeyEcdsa) if (rfcAlgoName == SshCapabilities::PubKeyEcdsa256)
return "EMSA1_BSI(SHA-256)"; return "EMSA1_BSI(SHA-256)";
throw SshClientException(SshInternalError, SSH_TR("Unexpected host key algorithm \"%1\"") throw SshClientException(SshInternalError, SSH_TR("Unexpected host key algorithm \"%1\"")
.arg(QString::fromLatin1(rfcAlgoName))); .arg(QString::fromLatin1(rfcAlgoName)));
@@ -118,11 +118,16 @@ inline const char *botanHMacAlgoName(const QByteArray &rfcAlgoName)
inline quint32 botanHMacKeyLen(const QByteArray &rfcAlgoName) inline quint32 botanHMacKeyLen(const QByteArray &rfcAlgoName)
{ {
Q_ASSERT(rfcAlgoName == SshCapabilities::HMacSha1
|| rfcAlgoName == SshCapabilities::HMacSha256);
if (rfcAlgoName == SshCapabilities::HMacSha1) if (rfcAlgoName == SshCapabilities::HMacSha1)
return 20; return 20;
if (rfcAlgoName == SshCapabilities::HMacSha256)
return 32; 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 } // namespace Internal

View File

@@ -65,9 +65,9 @@ const QList<QByteArray> SshCapabilities::KeyExchangeMethods = QList<QByteArray>(
const QByteArray SshCapabilities::PubKeyDss("ssh-dss"); const QByteArray SshCapabilities::PubKeyDss("ssh-dss");
const QByteArray SshCapabilities::PubKeyRsa("ssh-rsa"); const QByteArray SshCapabilities::PubKeyRsa("ssh-rsa");
const QByteArray SshCapabilities::PubKeyEcdsa("ecdsa-sha2-nistp256"); const QByteArray SshCapabilities::PubKeyEcdsa256("ecdsa-sha2-nistp256");
const QList<QByteArray> SshCapabilities::PublicKeyAlgorithms = QList<QByteArray>() const QList<QByteArray> SshCapabilities::PublicKeyAlgorithms = QList<QByteArray>()
<< SshCapabilities::PubKeyEcdsa << SshCapabilities::PubKeyEcdsa256
<< SshCapabilities::PubKeyRsa << SshCapabilities::PubKeyRsa
<< SshCapabilities::PubKeyDss; << SshCapabilities::PubKeyDss;
@@ -130,5 +130,13 @@ QByteArray SshCapabilities::findBestMatch(const QList<QByteArray> &myCapabilitie
return commonCapabilities(myCapabilities, serverCapabilities).first(); 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 Internal
} // namespace QSsh } // namespace QSsh

View File

@@ -50,7 +50,7 @@ public:
static const QByteArray PubKeyDss; static const QByteArray PubKeyDss;
static const QByteArray PubKeyRsa; static const QByteArray PubKeyRsa;
static const QByteArray PubKeyEcdsa; static const QByteArray PubKeyEcdsa256;
static const QList<QByteArray> PublicKeyAlgorithms; static const QList<QByteArray> PublicKeyAlgorithms;
static const QByteArray CryptAlgo3DesCbc; static const QByteArray CryptAlgo3DesCbc;
@@ -76,6 +76,8 @@ public:
const QList<QByteArray> &serverCapabilities); const QList<QByteArray> &serverCapabilities);
static QByteArray findBestMatch(const QList<QByteArray> &myCapabilities, static QByteArray findBestMatch(const QList<QByteArray> &myCapabilities,
const QList<QByteArray> &serverCapabilities); const QList<QByteArray> &serverCapabilities);
static int ecdsaIntegerWidthInBytes(const QByteArray &ecdsaAlgo);
}; };
} // namespace Internal } // namespace Internal

View File

@@ -30,6 +30,7 @@
#include "sshincomingpacket_p.h" #include "sshincomingpacket_p.h"
#include "ssh_global.h"
#include "sshbotanconversions_p.h" #include "sshbotanconversions_p.h"
#include "sshcapabilities_p.h" #include "sshcapabilities_p.h"
@@ -169,7 +170,37 @@ SshKeyExchangeInit SshIncomingPacket::extractKeyExchangeInitData() const
return exchangeData; 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(isComplete());
Q_ASSERT(type() == SSH_MSG_KEXDH_REPLY); Q_ASSERT(type() == SSH_MSG_KEXDH_REPLY);
@@ -179,41 +210,32 @@ SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray
quint32 topLevelOffset = TypeOffset + 1; quint32 topLevelOffset = TypeOffset + 1;
replyData.k_s = SshPacketParser::asString(m_data, &topLevelOffset); replyData.k_s = SshPacketParser::asString(m_data, &topLevelOffset);
quint32 k_sOffset = 0; quint32 k_sOffset = 0;
if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != pubKeyAlgo) if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != hostKeyAlgo)
throw SshPacketParseException(); throw SshPacketParseException();
getHostKeySpecificReplyData(replyData, hostKeyAlgo, replyData.k_s.mid(k_sOffset));
if (pubKeyAlgo == SshCapabilities::PubKeyDss || pubKeyAlgo == SshCapabilities::PubKeyRsa) { if (kexAlgo == SshCapabilities::DiffieHellmanGroup1Sha1) {
// 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);
}
replyData.f = SshPacketParser::asBigInt(m_data, &topLevelOffset); replyData.f = SshPacketParser::asBigInt(m_data, &topLevelOffset);
} else { } else {
Q_ASSERT(pubKeyAlgo == SshCapabilities::PubKeyEcdsa); QSSH_ASSERT_AND_RETURN_VALUE(kexAlgo.startsWith(SshCapabilities::EcdhKexNamePrefix),
if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != pubKeyAlgo.mid(11)) // Without "ecdsa-sha2-" prefix. SshKeyExchangeReply());
throw SshPacketParseException();
replyData.q = SshPacketParser::asString(replyData.k_s, &k_sOffset);
replyData.q_s = SshPacketParser::asString(m_data, &topLevelOffset); replyData.q_s = SshPacketParser::asString(m_data, &topLevelOffset);
} }
const QByteArray fullSignature = SshPacketParser::asString(m_data, &topLevelOffset); const QByteArray fullSignature = SshPacketParser::asString(m_data, &topLevelOffset);
quint32 sigOffset = 0; quint32 sigOffset = 0;
if (SshPacketParser::asString(fullSignature, &sigOffset) != pubKeyAlgo) if (SshPacketParser::asString(fullSignature, &sigOffset) != hostKeyAlgo)
throw SshPacketParseException(); throw SshPacketParseException();
replyData.signatureBlob = SshPacketParser::asString(fullSignature, &sigOffset); replyData.signatureBlob = SshPacketParser::asString(fullSignature, &sigOffset);
if (pubKeyAlgo == SshCapabilities::PubKeyEcdsa) { if (hostKeyAlgo == SshCapabilities::PubKeyEcdsa256) {
// Botan's PK_Verifier wants the signature in this format. // Botan's PK_Verifier wants the signature in this format.
quint32 blobOffset = 0; quint32 blobOffset = 0;
const Botan::BigInt r = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset); const Botan::BigInt r = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset);
const Botan::BigInt s = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset); const Botan::BigInt s = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset);
replyData.signatureBlob = convertByteArray(Botan::BigInt::encode(r)); const int width = SshCapabilities::ecdsaIntegerWidthInBytes(hostKeyAlgo);
replyData.signatureBlob += convertByteArray(Botan::BigInt::encode(s)); 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)); replyData.k_s.prepend(m_data.mid(TypeOffset + 1, 4));
return replyData; return replyData;

View File

@@ -62,10 +62,10 @@ struct SshKeyExchangeInit
struct SshKeyExchangeReply struct SshKeyExchangeReply
{ {
QByteArray k_s; QByteArray k_s;
QList<Botan::BigInt> parameters; // DSS: p, q, g, y. RSA: e, n. QList<Botan::BigInt> hostKeyParameters; // DSS: p, q, g, y. RSA: e, n.
QByteArray q; // For ECDSA host keys only.
Botan::BigInt f; // For DH only. Botan::BigInt f; // For DH only.
QByteArray q_s; // For ECDH only. QByteArray q_s; // For ECDH only.
QByteArray q; // For ECDH only.
QByteArray signatureBlob; QByteArray signatureBlob;
}; };
@@ -164,7 +164,8 @@ public:
void reset(); void reset();
SshKeyExchangeInit extractKeyExchangeInitData() const; SshKeyExchangeInit extractKeyExchangeInitData() const;
SshKeyExchangeReply extractKeyExchangeReply(const QByteArray &pubKeyAlgo) const; SshKeyExchangeReply extractKeyExchangeReply(const QByteArray &kexAlgo,
const QByteArray &hostKeyAlgo) const;
SshDisconnect extractDisconnect() const; SshDisconnect extractDisconnect() const;
SshUserAuthBanner extractUserAuthBanner() const; SshUserAuthBanner extractUserAuthBanner() const;
SshUserAuthInfoRequestPacket extractUserAuthInfoRequest() const; SshUserAuthInfoRequestPacket extractUserAuthInfoRequest() const;

View File

@@ -30,6 +30,7 @@
#include "sshkeyexchange_p.h" #include "sshkeyexchange_p.h"
#include "ssh_global.h"
#include "sshbotanconversions_p.h" #include "sshbotanconversions_p.h"
#include "sshcapabilities_p.h" #include "sshcapabilities_p.h"
#include "sshsendfacility_p.h" #include "sshsendfacility_p.h"
@@ -115,28 +116,8 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit)
m_kexAlgoName = SshCapabilities::findBestMatch(SshCapabilities::KeyExchangeMethods, m_kexAlgoName = SshCapabilities::findBestMatch(SshCapabilities::KeyExchangeMethods,
kexInitParams.keyAlgorithms.names); kexInitParams.keyAlgorithms.names);
const QList<QByteArray> &commonHostKeyAlgos m_serverHostKeyAlgo = SshCapabilities::findBestMatch(SshCapabilities::PublicKeyAlgorithms,
= SshCapabilities::commonCapabilities(SshCapabilities::PublicKeyAlgorithms,
kexInitParams.serverHostKeyAlgorithms.names); 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)));
}
determineHashingAlgorithm(kexInitParams, true); determineHashingAlgorithm(kexInitParams, true);
determineHashingAlgorithm(kexInitParams, false); determineHashingAlgorithm(kexInitParams, false);
@@ -152,7 +133,7 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit)
kexInitParams.compressionAlgorithmsServerToClient.names); kexInitParams.compressionAlgorithmsServerToClient.names);
AutoSeeded_RNG rng; AutoSeeded_RNG rng;
if (ecdh) { if (m_kexAlgoName.startsWith(SshCapabilities::EcdhKexNamePrefix)) {
m_ecdhKey.reset(new ECDH_PrivateKey(rng, EC_Group(botanKeyExchangeAlgoName(m_kexAlgoName)))); m_ecdhKey.reset(new ECDH_PrivateKey(rng, EC_Group(botanKeyExchangeAlgoName(m_kexAlgoName))));
m_sendFacility.sendKeyEcdhInitPacket(convertByteArray(m_ecdhKey->public_value())); m_sendFacility.sendKeyEcdhInitPacket(convertByteArray(m_ecdhKey->public_value()));
} else { } else {
@@ -169,7 +150,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
{ {
const SshKeyExchangeReply &reply 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())) { if (m_dhKey && (reply.f <= 0 || reply.f >= m_dhKey->group_p())) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
"Server sent invalid f."); "Server sent invalid f.");
@@ -187,6 +168,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
DH_KA_Operation dhOp(*m_dhKey); DH_KA_Operation dhOp(*m_dhKey);
SecureVector<byte> encodedF = BigInt::encode(reply.f); SecureVector<byte> encodedF = BigInt::encode(reply.f);
encodedK = dhOp.agree(encodedF, encodedF.size()); encodedK = dhOp.agree(encodedF, encodedF.size());
m_dhKey.reset(nullptr);
} else { } else {
Q_ASSERT(m_ecdhKey); Q_ASSERT(m_ecdhKey);
concatenatedData // Q_C. concatenatedData // Q_C.
@@ -194,7 +176,9 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
concatenatedData += AbstractSshPacket::encodeString(reply.q_s); concatenatedData += AbstractSshPacket::encodeString(reply.q_s);
ECDH_KA_Operation ecdhOp(*m_ecdhKey); ECDH_KA_Operation ecdhOp(*m_ecdhKey);
encodedK = ecdhOp.agree(convertByteArray(reply.q_s), reply.q_s.count()); encodedK = ecdhOp.agree(convertByteArray(reply.q_s), reply.q_s.count());
m_ecdhKey.reset(nullptr);
} }
const BigInt k = BigInt::decode(encodedK); const BigInt k = BigInt::decode(encodedK);
m_k = AbstractSshPacket::encodeMpInt(k); // Roundtrip, as Botan encodes BigInts somewhat differently. m_k = AbstractSshPacket::encodeMpInt(k); // Roundtrip, as Botan encodes BigInts somewhat differently.
concatenatedData += m_k; concatenatedData += m_k;
@@ -219,22 +203,22 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
QScopedPointer<Public_Key> sigKey; QScopedPointer<Public_Key> sigKey;
if (m_serverHostKeyAlgo == SshCapabilities::PubKeyDss) { if (m_serverHostKeyAlgo == SshCapabilities::PubKeyDss) {
const DL_Group group(reply.parameters.at(0), reply.parameters.at(1), const DL_Group group(reply.hostKeyParameters.at(0), reply.hostKeyParameters.at(1),
reply.parameters.at(2)); reply.hostKeyParameters.at(2));
DSA_PublicKey * const dsaKey DSA_PublicKey * const dsaKey
= new DSA_PublicKey(group, reply.parameters.at(3)); = new DSA_PublicKey(group, reply.hostKeyParameters.at(3));
sigKey.reset(dsaKey); sigKey.reset(dsaKey);
} else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyRsa) { } else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyRsa) {
RSA_PublicKey * const rsaKey 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); 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 { } 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); const byte * const botanH = convertByteArray(m_h);
@@ -248,8 +232,6 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
checkHostKey(reply.k_s); checkHostKey(reply.k_s);
m_sendFacility.sendNewKeysPacket(); m_sendFacility.sendNewKeysPacket();
m_dhKey.reset(nullptr);
m_ecdhKey.reset(nullptr);
} }
QByteArray SshKeyExchange::hashAlgoForKexAlgo() const QByteArray SshKeyExchange::hashAlgoForKexAlgo() const

View File

@@ -159,7 +159,10 @@ QString ShellCommand::displayName() const
if (!d->m_jobs.isEmpty()) { if (!d->m_jobs.isEmpty()) {
const Internal::ShellCommandPrivate::Job &job = d->m_jobs.at(0); const Internal::ShellCommandPrivate::Job &job = d->m_jobs.at(0);
QString result = job.binary.toFileInfo().baseName(); QString result = job.binary.toFileInfo().baseName();
if (!result.isEmpty())
result[0] = result.at(0).toTitleCase(); result[0] = result.at(0).toTitleCase();
else
result = tr("UNKNOWN");
if (!job.arguments.isEmpty()) if (!job.arguments.isEmpty())
result += QLatin1Char(' ') + job.arguments.at(0); result += QLatin1Char(' ') + job.arguments.at(0);

View File

@@ -622,6 +622,8 @@ TreeItem::TreeItem(const QStringList &displays, int flags)
TreeItem::~TreeItem() TreeItem::~TreeItem()
{ {
QTC_CHECK(m_parent == 0);
QTC_CHECK(m_model == 0);
removeChildren(); removeChildren();
delete m_displays; delete m_displays;
} }
@@ -851,6 +853,10 @@ TreeModel::TreeModel(TreeItem *root, QObject *parent)
TreeModel::~TreeModel() 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; delete m_root;
} }
@@ -966,7 +972,13 @@ int TreeModel::topLevelItemCount() const
void TreeModel::setRootItem(TreeItem *item) void TreeModel::setRootItem(TreeItem *item)
{ {
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; delete m_root;
}
m_root = item; m_root = item;
item->setModel(this); item->setModel(this);
emit layoutChanged(); emit layoutChanged();
@@ -1049,6 +1061,7 @@ TreeItem *TreeModel::takeItem(TreeItem *item)
QModelIndex idx = indexForItem(parent); QModelIndex idx = indexForItem(parent);
beginRemoveRows(idx, pos, pos); beginRemoveRows(idx, pos, pos);
item->m_parent = 0; item->m_parent = 0;
item->m_model = 0;
parent->m_children.removeAt(pos); parent->m_children.removeAt(pos);
endRemoveRows(); endRemoveRows();
return item; return item;

View File

@@ -155,7 +155,7 @@ public:
void handleToolFinished(); void handleToolFinished();
void saveToolSettings(Id toolId); void saveToolSettings(Id toolId);
void loadToolSettings(Id toolId); void loadToolSettings(Id toolId);
void startTool(); void startCurrentTool();
void selectToolboxAction(const QString &item); void selectToolboxAction(const QString &item);
void modeChanged(IMode *mode); void modeChanged(IMode *mode);
void resetLayout(); void resetLayout();
@@ -173,10 +173,11 @@ public:
ActionContainer *m_menu; ActionContainer *m_menu;
QComboBox *m_toolBox; QComboBox *m_toolBox;
QStackedWidget *m_controlsStackWidget; QStackedWidget *m_controlsStackWidget;
StatusLabel *m_statusLabel; QStackedWidget *m_statusLabelsStackWidget;
typedef QMap<Id, FancyMainWindowSettings> MainWindowSettingsMap; typedef QMap<Id, FancyMainWindowSettings> MainWindowSettingsMap;
QHash<Id, QList<QDockWidget *> > m_toolWidgets; QHash<Id, QList<QDockWidget *> > m_toolWidgets;
QHash<Id, QWidget *> m_controlsWidgetFromTool; QHash<Id, QWidget *> m_controlsWidgetFromTool;
QHash<Id, StatusLabel *> m_statusLabelsPerTool;
MainWindowSettingsMap m_defaultSettings; MainWindowSettingsMap m_defaultSettings;
// list of dock widgets to prevent memory leak // list of dock widgets to prevent memory leak
@@ -198,7 +199,7 @@ AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager *qq):
m_menu(0), m_menu(0),
m_toolBox(new QComboBox), m_toolBox(new QComboBox),
m_controlsStackWidget(new QStackedWidget), m_controlsStackWidget(new QStackedWidget),
m_statusLabel(new StatusLabel) m_statusLabelsStackWidget(new QStackedWidget)
{ {
m_toolBox->setObjectName(QLatin1String("AnalyzerManagerToolBox")); m_toolBox->setObjectName(QLatin1String("AnalyzerManagerToolBox"));
connect(m_toolBox, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated), connect(m_toolBox, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated),
@@ -241,7 +242,8 @@ void AnalyzerManagerPrivate::setupActions()
m_startAction = new QAction(tr("Start"), m_menu); m_startAction = new QAction(tr("Start"), m_menu);
m_startAction->setIcon(QIcon(QLatin1String(ANALYZER_CONTROL_START_ICON))); m_startAction->setIcon(QIcon(QLatin1String(ANALYZER_CONTROL_START_ICON)));
ActionManager::registerAction(m_startAction, "Analyzer.Start"); 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 = new QAction(tr("Stop"), m_menu);
m_stopAction->setEnabled(false); m_stopAction->setEnabled(false);
@@ -351,7 +353,7 @@ void AnalyzerManagerPrivate::createModeMainWindow()
analyzeToolBarLayout->addWidget(new StyledSeparator); analyzeToolBarLayout->addWidget(new StyledSeparator);
analyzeToolBarLayout->addWidget(m_toolBox); analyzeToolBarLayout->addWidget(m_toolBox);
analyzeToolBarLayout->addWidget(m_controlsStackWidget); analyzeToolBarLayout->addWidget(m_controlsStackWidget);
analyzeToolBarLayout->addWidget(m_statusLabel); analyzeToolBarLayout->addWidget(m_statusLabelsStackWidget);
analyzeToolBarLayout->addStretch(); analyzeToolBarLayout->addStretch();
auto dock = new QDockWidget(tr("Analyzer Toolbar")); auto dock = new QDockWidget(tr("Analyzer Toolbar"));
@@ -420,7 +422,7 @@ bool AnalyzerManagerPrivate::showPromptDialog(const QString &title, const QStrin
return messageBox.clickedStandardButton() == QDialogButtonBox::Yes; return messageBox.clickedStandardButton() == QDialogButtonBox::Yes;
} }
void AnalyzerManagerPrivate::startTool() void AnalyzerManagerPrivate::startCurrentTool()
{ {
QTC_ASSERT(m_currentAction, return); QTC_ASSERT(m_currentAction, return);
m_currentAction->startTool(); m_currentAction->startTool();
@@ -492,6 +494,9 @@ void AnalyzerManagerPrivate::selectAction(AnalyzerAction *action)
QTC_CHECK(!m_controlsWidgetFromTool.contains(toolId)); QTC_CHECK(!m_controlsWidgetFromTool.contains(toolId));
m_controlsWidgetFromTool[toolId] = widget; m_controlsWidgetFromTool[toolId] = widget;
m_controlsStackWidget->addWidget(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)) foreach (QDockWidget *widget, m_toolWidgets.value(toolId))
activateDock(Qt::DockWidgetArea(widget->property(INITIAL_DOCK_AREA).toInt()), widget); 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)); QTC_CHECK(m_controlsWidgetFromTool.contains(toolId));
m_controlsStackWidget->setCurrentWidget(m_controlsWidgetFromTool.value(toolId)); m_controlsStackWidget->setCurrentWidget(m_controlsWidgetFromTool.value(toolId));
m_statusLabelsStackWidget->setCurrentWidget(m_statusLabelsPerTool.value(toolId));
m_toolBox->setCurrentIndex(toolboxIndex); m_toolBox->setCurrentIndex(toolboxIndex);
updateRunActions(); updateRunActions();
@@ -539,9 +545,8 @@ void AnalyzerManagerPrivate::addAction(AnalyzerAction *action)
rebuildToolBox(); rebuildToolBox();
connect(action, &QAction::triggered, this, [this, action] { connect(action, &QAction::triggered, this, [this, action] {
AnalyzerManager::showMode();
selectAction(action); selectAction(action);
startTool(); action->startTool();
}); });
} }
@@ -647,16 +652,15 @@ QDockWidget *AnalyzerManager::createDockWidget(Core::Id toolId,
return dockWidget; return dockWidget;
} }
void AnalyzerManager::selectTool(Id actionId) void AnalyzerManager::selectAction(Id actionId, bool alsoRunIt)
{ {
foreach (AnalyzerAction *action, d->m_actions) foreach (AnalyzerAction *action, d->m_actions) {
if (action->actionId() == actionId) if (action->actionId() == actionId) {
d->selectAction(action); d->selectAction(action);
if (alsoRunIt)
action->startTool();
}
} }
void AnalyzerManager::startTool()
{
d->startTool();
} }
FancyMainWindow *AnalyzerManager::mainWindow() FancyMainWindow *AnalyzerManager::mainWindow()
@@ -670,14 +674,16 @@ void AnalyzerManagerPrivate::resetLayout()
m_mainWindow->restoreSettings(m_defaultSettings.value(m_currentAction->toolId())); 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() void AnalyzerManager::showMode()

Some files were not shown because too many files have changed in this diff Show More