Merge remote-tracking branch 'origin/4.6'

Conflicts:
	src/plugins/coreplugin/locator/locator.cpp
	src/plugins/imageviewer/imageviewerplugin.cpp
	src/plugins/remotelinux/remotelinuxplugin.cpp
	src/tools/clangbackend/source/tokeninfo.cpp
	tests/unit/unittest/data/highlightingmarks.cpp

Change-Id: I74cc3ba3a2836cb9d0e65d3380d8c4f88d720c67
This commit is contained in:
Eike Ziller
2018-02-07 11:58:23 +01:00
119 changed files with 1204 additions and 589 deletions

View File

@@ -505,10 +505,10 @@ index c788abb881..ed4773b132 100644
+clang_PrintingPolicy_setProperty +clang_PrintingPolicy_setProperty
+clang_PrintingPolicy_dispose +clang_PrintingPolicy_dispose
diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
index f2a96d6be6..a9f5ee1da4 100644 index f2a96d6be6..342fbd5279 100644
--- a/tools/clang/unittests/libclang/LibclangTest.cpp --- a/tools/clang/unittests/libclang/LibclangTest.cpp
+++ b/tools/clang/unittests/libclang/LibclangTest.cpp +++ b/tools/clang/unittests/libclang/LibclangTest.cpp
@@ -572,3 +572,33 @@ TEST_F(LibclangReparseTest, clang_parseTranslationUnit2FullArgv) { @@ -572,3 +572,35 @@ TEST_F(LibclangReparseTest, clang_parseTranslationUnit2FullArgv) {
EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU)); EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
DisplayDiagnostics(); DisplayDiagnostics();
} }
@@ -536,6 +536,8 @@ index f2a96d6be6..a9f5ee1da4 100644
+ for (unsigned Value = 0; Value < 2; ++Value) { + for (unsigned Value = 0; Value < 2; ++Value) {
+ for (int I = 0; I < CXPrintingPolicy_LastProperty; ++I) { + for (int I = 0; I < CXPrintingPolicy_LastProperty; ++I) {
+ auto Property = static_cast<enum CXPrintingPolicyProperty>(I); + auto Property = static_cast<enum CXPrintingPolicyProperty>(I);
+ if (Property == CXPrintingPolicy_ConstantsAsWritten || Property == CXPrintingPolicy_SuppressImplicitBase)
+ continue; // These are not yet in clang 5.0.
+ +
+ clang_PrintingPolicy_setProperty(Policy, Property, Value); + clang_PrintingPolicy_setProperty(Policy, Property, Value);
+ EXPECT_EQ(Value, clang_PrintingPolicy_getProperty(Policy, Property)); + EXPECT_EQ(Value, clang_PrintingPolicy_getProperty(Policy, Property));

View File

@@ -96,12 +96,10 @@
\li \uicontrol Copyright is a one-line, short copyright string. \li \uicontrol Copyright is a one-line, short copyright string.
\li \uicontrol License is a multi-line license text (but \li \uicontrol License is a license text.
shouldn't be pages over pages long, since the interface
doesn't allow nice reading of long texts).
\li \uicontrol{Description} is a relatively short, but possibly \li \uicontrol{Description} is a short description of what the
multi-line description of what the plugin does. plugin does.
\li \uicontrol URL is a website where the user can find more \li \uicontrol URL is a website where the user can find more
information about the plugin and/or organization providing information about the plugin and/or organization providing

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -31,7 +31,7 @@
/*! /*!
\contentspage {Qt Creator Manual} \contentspage {Qt Creator Manual}
\previouspage creator-clang-static-analyzer.html \previouspage creator-heob.html
\page creator-cpu-usage-analyzer.html \page creator-cpu-usage-analyzer.html
\nextpage creator-autotest.html \nextpage creator-autotest.html

View File

@@ -71,6 +71,11 @@
Objective-C programs by using the experimental plugin that Objective-C programs by using the experimental plugin that
integrates the Clang Static Analyzer source code analysis tool. integrates the Clang Static Analyzer source code analysis tool.
\li \l{Detecting Memory Leaks with Heob}
You can use the Heob heap observer on Windows to detect buffer
overruns and memory leaks.
\li \l{Analyzing CPU Usage}{CPU Usage Analyzer} \li \l{Analyzing CPU Usage}{CPU Usage Analyzer}
You can analyze the CPU usage of embedded applications and Linux You can analyze the CPU usage of embedded applications and Linux

View File

@@ -33,7 +33,7 @@
\contentspage {Qt Creator Manual} \contentspage {Qt Creator Manual}
\previouspage creator-running-valgrind-remotely.html \previouspage creator-running-valgrind-remotely.html
\page creator-clang-static-analyzer.html \page creator-clang-static-analyzer.html
\nextpage creator-cpu-usage-analyzer.html \nextpage creator-heob.html
\title Using Clang Static Analyzer \title Using Clang Static Analyzer

View File

@@ -0,0 +1,197 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
**
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** 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. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
**
****************************************************************************/
// **********************************************************************
// NOTE: the sections are not ordered by their logical order to avoid
// reshuffling the file each time the index order changes (i.e., often).
// Run the fixnavi.pl script to adjust the links to the index order.
// **********************************************************************
/*!
\contentspage {Qt Creator Manual}
\previouspage creator-clang-static-analyzer.html
\page creator-heob.html
\nextpage creator-cpu-usage-analyzer.html
\title Detecting Memory Leaks with Heob
\QC integrates the \l{https://github.com/ssbssa/heob}{Heob} heap observer
for detecting buffer overruns and memory leaks. You must download and
install Heob to run it from \QC.
To run Heob on the currently open project:
\list 1
\li Select \uicontrol Analyze > \uicontrol Heob.
\li In the \uicontrol {Heob path} field, enter the path to the Heob
executable.
\li Specify additional settings for running the checks. For more
information about the available options, see
\l{Specifying Heob Settings}.
\li Select \uicontrol OK to run Heob.
\endlist
\QC runs the application, and then it runs Heob in a console window.
\image qtcreator-heob.png
Heob raises an access violation on buffer overruns and provides stack traces
of the offending instruction and buffer allocation. The results are
displayed when Heob exits normally.
\image qtcreator-heob-output.png
\section1 Specifying Heob Settings
To specify settings for Heob, select \uicontrol Analyze > \uicontrol Heob.
\image qtcreator-heob-settings.png
In the \uicontrol {Extra arguments} field, enter additional arguments for
running Heob. To list the available arguments in the Heob console, enter
\c -H in this field and press \key Enter.
For example, use the \c -oleaks.html option to record leak data in an HTML
file. Together with this option, you can use the \c -g2 option to group the
leaks visually in the file and the \c -L1024 option to record leak contents
up to 1024 bytes in the file. For example, \c {-oleaks.html -g2 -L1024}
Select \uicontrol Save to save the current settings as default.
The following sections describe the available options in more detail.
\section2 Recording Results
The results of the checks are displayed in the \uicontrol Memcheck view and
recorded in a file. You can specify the file name in the
\uicontrol {XML output file} field. Heob creates the file in the project
directory.
You can use the process identifier (PID) as a variable in the file name.
For example, \c leaks-%p.xml. This injects Heob into the child processes,
as well.
Other variables you can use are \c %P for the parent PID and \c %n for the
application name.
If you use variables, \QC cannot open the file automatically, but you can
open it from the project directory.
\section2 Handling Exceptions
In the \uicontrol {Handle exceptions} list, select \uicontrol Off to use the
standard exception handler and have the debugger automatically attached if
the application crashes. This works only if you register \QC is as a
post-mortem debugger by selecting \uicontrol Tools > \uicontrol Options >
\uicontrol Debugger > \uicontrol General >
\uicontrol {Use Qt Creator for post-mortem debugging}.
Select \uicontrol On to use the Heob exception handler that checks the
reason and location of the crash and detects whether it occurred because of
buffer overrun.
Select \uicontrol Only to disable all Heob functions, except installing the
exception handler. If the application crashes, only a stack trace of the
crash is displayed. Therefore, this option is mostly useful when using Heob
on the console or running it for child processes, as well.
\section2 Raising Exceptions on Errors
Select the \uicontrol {Raise breakpoint exception on error} check
box to display errors when the application runs.
If the option is disabled, errors such as \e {double free}, \e {free of
invalid pointer}, and \e {not enough memory} just write all collected data
into the results file and you will only see them at the end of the
application run.
If the option is enabled, the application stops at the error location.
This is mostly useful when used with the \uicontrol {Run with debugger}
option, which runs Heob under the debugger.
\section2 Protecting Pages
In the \uicontrol {Page protection} list, select \uicontrol Off to use
standard memory allocation functions and enable only memory leak detection.
Select \uicontrol After to place a protected page at the end of each
allocated block and throw an exception if it is accessed. Select
\uicontrol Before to place a protected page before each allocated block.
These options consume memory and slow down the checks, and are therefore
recommended only for 64-bit or short-running programs.
Select \uicontrol {Freed memory protection} to protect all allocation pages
when freed, so that their address space can never be used again. This is
useful for \e use-after-free and \e double-free detection. However, the
available memory address space can run out fast for 32-bit programs.
\section2 Handling Leak Data
In the \uicontrol {Leak details} list, determine how to handle the
collected leak data when the process exits. Selecting \uicontrol None means
that no leak data is collected. If you activate leak type detection, Heob
might need more time to collect the data when the process exits.
Select \uicontrol Simple to write all memory that was not freed into the
results file.
Select \uicontrol {Detect Leak Types} to parse all static and global memory
blocks for references to the leaks. The reachable blocks are marked
\e reachable and recursively checked for other references. If references are
found, the blocks are marked \e {indirectly reachable}. The remaining blocks
are checked for references to each other and marked either
\e {indirectly lost} or \e {jointly lost} (if the blocks reference each
other). The blocks that have no references at all are marked \e lost.
Select \uicontrol {Detect Leak Types (Show Reachable)} to also record the
the reachable blocks in the results file.
Select \uicontrol {Fuzzy Detect Leak Types} to mark memory blocks
\e reachable or \e {indirectly lost} if they contain references to any
address. This option is useful when used with some custom allocators (such
as \c av_malloc() in \c ffmpeg) that keep only an address somewhere inside
the allocation block and do not refer directly to the start of an allocated
block. Select \uicontrol {Detect Leak Types (Show Reachable)} to also
record the reachable blocks in the results file.
In the \uicontrol {Minimum leak size} list, select the size of
leaks to detect in bytes.
In the \uicontrol {Control leak recording} list, select \uicontrol Off to
record all leaks. You cannot change leak recording while it is running.
To start Heob without starting leak recording, select
\uicontrol {On (Start Disabled)}. In the Heob console, turn recording
\uicontrol on or \uicontrol off, \uicontrol clear all results, or
select \uicontrol show to record all current leaks into the results file.
Open the file to see its contents before the process exits.
To start leak recording when Heob starts and still have the option to
control the recording, select \uicontrol {On (Start Enabled)}.
*/

View File

@@ -67,7 +67,7 @@
\list \list
\li \l{Detecting Memory Leaks} \li \l{Detecting Memory Leaks with Memcheck}
\li \l{Profiling Function Execution} \li \l{Profiling Function Execution}

View File

@@ -35,7 +35,7 @@
\page creator-analyzer.html \page creator-analyzer.html
\nextpage creator-cache-profiler.html \nextpage creator-cache-profiler.html
\title Detecting Memory Leaks \title Detecting Memory Leaks with Memcheck
You can use the Memcheck tool included in the Valgrind tool suite to detect You can use the Memcheck tool included in the Valgrind tool suite to detect
problems that are related to memory management in applications. You can use problems that are related to memory management in applications. You can use
@@ -43,7 +43,9 @@
application is interrupted and you can debug it. application is interrupted and you can debug it.
\note You can install and run Memcheck locally on Linux. You can run \note You can install and run Memcheck locally on Linux. You can run
it on a remote host or device from any development machine. it on a remote host or device from any development machine. On Windows,
you can use the \l{Detecting Memory Leaks with Heob}{Heob} heap observer to
receive similar results.
After you download and install Valgrind tools, you can use Memcheck from After you download and install Valgrind tools, you can use Memcheck from
\QC. \QC.

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -65,7 +65,7 @@
\li To view the base classes and data members of the TextFinder class, \li To view the base classes and data members of the TextFinder class,
go to the \uicontrol {Locals and Expressions} view. go to the \uicontrol Locals view.
\image qtcreator-watcher.png \image qtcreator-watcher.png

View File

@@ -170,67 +170,68 @@
\section1 Installing Native Debuggers \section1 Installing Native Debuggers
Check the table below for the supported versions and other important The following sections provide information about installing native
information about installing native debuggers. debuggers.
\table \section2 GDB
\header
\li Native Debugger
\li Notes
\row
\li GDB
\li On Windows, use the Python-enabled GDB versions that is bundled
with the Qt package or comes with recent versions of MinGW. On
most Linux distributions the GDB builds shipped with the system
are sufficient. You can also build your own. Follow the
instructions in \l{http://wiki.qt.io/QtCreator_Build_Gdb}
{Building GDB}. Builds of GDB shipped with Xcode on \macos are no
longer supported.
\row On Windows, use the Python-enabled GDB versions that is bundled
\li Debugging tools for Windows with the Qt package or comes with recent versions of MinGW. On
\li To use the CDB debugger, you must install the most Linux distributions, the GDB builds shipped with the system
\e{Debugging tools for Windows}. You can download them from are sufficient.
\l{https://developer.microsoft.com/windows/downloads/windows-10-sdk}
{Download and Install Debugging Tools for Windows} as part of the Windows SDK.
\note Visual Studio does not include the Debugging tools needed, You can also build your own GDB, as instructed in
and therefore, you must install them separately. \l{http://wiki.qt.io/QtCreator_Build_Gdb}{Building GDB}.
The pre-built \QSDK for Windows makes use of the library if it Builds of GDB shipped with Xcode on \macos are no longer supported.
is present on the system. When manually building \QC using
the Microsoft Visual C++ Compiler, the build process checks for
the required files in
\c{"%ProgramFiles%\Debugging Tools for Windows"}.
It is highly recommended that you add the Symbol Server provided \section2 Debugging Tools for Windows
by Microsoft to the symbol search path of the debugger. The
Symbol Server provides you with debugging informaton for the
operating system libraries for debugging Windows applications.
For more information, see
\l{Setting CDB Paths on Windows}.
\row To use the CDB debugger, you must install the
\li Debugging tools for \macos \e{Debugging tools for Windows}. You can download them from
\li The Qt binary distribution contains both debug and release \l{https://developer.microsoft.com/windows/downloads/windows-10-sdk}
variants of the libraries. But you have to explicitly tell the {Download and Install Debugging Tools for Windows} as part of the Windows
runtime linker that you want to use the debug libraries even if SDK.
your application is compiled as debug, as release is the default
library.
If you use a qmake based project in \QC, you can set a flag in \note Visual Studio does not include the Debugging tools needed,
your \l{glossary-run-config}{run configuration}, in and therefore, you must install them separately.
\uicontrol Projects mode. In the run configuration, select
\uicontrol{Use debug version of frameworks}.
For more detailed information about debugging on \macos, In addition, you must select \uicontrol {Qt Creator CDB Debugger Support}
see: \l{http://developer.apple.com/library/mac/#technotes/tn2124/_index.html#//apple_ref/doc/uid/DTS10003391} (in \uicontrol Qt > \uicontrol Tools > \uicontrol {\QC}) when you install
{Mac OS X Debugging Magic}. Qt or the stand-alone \QC.
\row When manually building \QC using
\li LLDB the Microsoft Visual C++ Compiler, the build process checks for
\li We recommend using the LLDB version that is delivered with Xcode 5. the required files in
\endtable \c{"%ProgramFiles%\Debugging Tools for Windows"}.
It is highly recommended that you add the Symbol Server provided
by Microsoft to the symbol search path of the debugger. The
Symbol Server provides you with debugging informaton for the
operating system libraries for debugging Windows applications.
For more information, see
\l{Setting CDB Paths on Windows}.
\section2 Debugging Tools for \macos
The Qt binary distribution contains both debug and release
variants of the libraries. But you have to explicitly tell the
runtime linker that you want to use the debug libraries even if
your application is compiled as debug, as release is the default
library.
If you use a qmake based project in \QC, you can set a flag in
your \l{glossary-run-config}{run configuration}, in
\uicontrol Projects mode. In the run configuration, select
\uicontrol{Use debug version of frameworks}.
For more detailed information about debugging on \macos,
see: \l{http://developer.apple.com/library/mac/#technotes/tn2124/_index.html#//apple_ref/doc/uid/DTS10003391}
{Mac OS X Debugging Magic}.
\section2 LLDB
We recommend using the LLDB version that is delivered with the latest Xcode.
\section1 Mapping Source Paths \section1 Mapping Source Paths

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -679,11 +679,10 @@
\section1 Local Variables and Function Parameters \section1 Local Variables and Function Parameters
The Locals view consists of two parts: the \uicontrol Locals pane at the top The Locals view consists of the \uicontrol Locals pane and the
and the \uicontrol {Return Value} pane at the bottom. The \uicontrol {Return Value} pane (hidden when empty).
\uicontrol {Return Value} is only visible if it is not empty.
\image qtcreator-locals-expressions.png "Locals view" \image qtcreator-locals.png "Locals view"
Whenever a program stops under the control of the debugger, it retrieves Whenever a program stops under the control of the debugger, it retrieves
information about the topmost stack frame and displays it in the information about the topmost stack frame and displays it in the
@@ -694,7 +693,7 @@
pane displays the value returned by the function. pane displays the value returned by the function.
\section1 Evaluating Expresssion \section1 Evaluating Expressions
To compute values of arithmetic expressions or function calls, use To compute values of arithmetic expressions or function calls, use
expression evaluators in the \uicontrol Expressions view. To insert a new expression evaluators in the \uicontrol Expressions view. To insert a new
@@ -703,6 +702,8 @@
\uicontrol {Add New Expression Evaluator} from the context menu, or drag and \uicontrol {Add New Expression Evaluator} from the context menu, or drag and
drop an expression from the code editor. drop an expression from the code editor.
\image qtcreator-debugger-expressions.png
\note Expression evaluators are powerful, but slow down debugger operation \note Expression evaluators are powerful, but slow down debugger operation
significantly. It is advisable to not use them excessively, and to remove significantly. It is advisable to not use them excessively, and to remove
unneeded expression evaluators as soon as possible. unneeded expression evaluators as soon as possible.
@@ -1070,7 +1071,7 @@
\li \c d of type \c Dumper, an object containing the current settings and \li \c d of type \c Dumper, an object containing the current settings and
providing facilities to build up an object representing a part of providing facilities to build up an object representing a part of
the \uicontrol {Locals and Expressions} view. the \uicontrol Locals and \uicontrol Expressions views.
\li \c value of type \c Value, wrapping either a \li \c value of type \c Value, wrapping either a
\l{https://sourceware.org/gdb/onlinedocs/gdb/Values-From-Inferior.html} \l{https://sourceware.org/gdb/onlinedocs/gdb/Values-From-Inferior.html}
@@ -1082,7 +1083,7 @@
The \c{qdump__*} function has to feed the Dumper object with certain The \c{qdump__*} function has to feed the Dumper object with certain
information that is used to build up the object and its children's display information that is used to build up the object and its children's display
in the \uicontrol {Locals and Expressions} view. in the \uicontrol Locals and \uicontrol Expressions views.
Example: Example:
@@ -1099,6 +1100,16 @@
avoid direct access to the \c gdb.* and \c lldb.* namespaces and use the avoid direct access to the \c gdb.* and \c lldb.* namespaces and use the
functions of the \c Dumper class instead. functions of the \c Dumper class instead.
To get to the base instance of the object in the debugging helper, use the
\c value.base() function or the following example code:
\code
def qdump__A(d, value):
t = value.members(True)[0].type
dptr, base_v = value.split('p{%s}' % t.name)
d.putItem(base_v)
\endcode
Debugging helpers can be set up to be called whenever a type name matches Debugging helpers can be set up to be called whenever a type name matches
a regular expression. To do so, the debugging helper's function name must a regular expression. To do so, the debugging helper's function name must
begin with \c{qdump__} (with two underscore characters). In addition, begin with \c{qdump__} (with two underscore characters). In addition,
@@ -1122,8 +1133,9 @@
A debugging helper creates a description of the displayed data item A debugging helper creates a description of the displayed data item
in a format that is similar to GDB/MI and JSON. in a format that is similar to GDB/MI and JSON.
For each line in the \uicontrol {Locals and Expressions} view, a string like For each line in the \uicontrol Locals and \uicontrol Expressions views, a
the following needs to be created and channeled to the debugger plugin. string like the following needs to be created and channeled to the debugger
plugin.
\code \code
{ iname='some internal name', # optional { iname='some internal name', # optional
@@ -1575,18 +1587,18 @@
\section1 Pointer Variable Members Are Not Displayed Directly \section1 Pointer Variable Members Are Not Displayed Directly
When you use the \uicontrol {Locals and Expressions} view to inspect a When you use the \uicontrol Locals and \uicontrol Expressions views to inspect a
pointer variable and expand the variable tree item, another tree item level pointer variable and expand the variable tree item, another tree item level
is displayed. To directly display the members of the pointer variable, is displayed. To directly display the members of the pointer variable,
select \uicontrol {Dereference Pointers Automatically} in the context select \uicontrol {Dereference Pointers Automatically} in the context
menu in the \uicontrol {Locals and Expressions} view. menu in the \uicontrol Locals and \uicontrol Expressions views.
\section1 Structure Members Are Not Sorted According to Structure Layout \section1 Structure Members Are Not Sorted According to Structure Layout
By default, structure members are displayed in alphabetic order. To inspect By default, structure members are displayed in alphabetic order. To inspect
the real layout in memory, deselect the real layout in memory, deselect
\uicontrol {Sort Members of Classes and Structs Alphabetically} in the \uicontrol {Sort Members of Classes and Structs Alphabetically} in the
context menu in the \uicontrol {Locals and Expressions} view. context menu in the \uicontrol Locals and \uicontrol Expressions views.
\section1 Built-in Debugger Is Slow During Startup and Runtime \section1 Built-in Debugger Is Slow During Startup and Runtime

View File

@@ -218,14 +218,18 @@
test list for the currently active test frameworks when you edit tests. test list for the currently active test frameworks when you edit tests.
To refresh the view, select \uicontrol {Rescan Tests} in the context menu. To refresh the view, select \uicontrol {Rescan Tests} in the context menu.
You can add filters to specify the directories within the current project To group related test cases for an active test framework, select
to scan for tests. Select \uicontrol Tools > \uicontrol Options > \uicontrol Tools > \uicontrol Options > \uicontrol {Testing} >
\uicontrol {Testing} > \uicontrol General > \uicontrol Add, and \uicontrol General, and then select the \uicontrol Group check box next to
specify paths to the directories to scan for tests. Wildcards are not the framework name in the \uicontrol {Active Test Frameworks} list.
supported in the filter expressions.
\image qtcreator-autotests-options.png \image qtcreator-autotests-options.png
You can add filters to specify the directories within the current project
to scan for tests. Select the \uicontrol {Global Filters} check box, and
the select \uicontrol Add to specify paths to the directories to scan for
tests. Wildcards are not supported in the filter expressions.
To show or hide init and cleanup or data functions in the \uicontrol Tests To show or hide init and cleanup or data functions in the \uicontrol Tests
view, select \inlineimage filtericon.png view, select \inlineimage filtericon.png
(\uicontrol {Filter Test Tree}), and then select \uicontrol {Show Init and (\uicontrol {Filter Test Tree}), and then select \uicontrol {Show Init and

View File

@@ -177,11 +177,12 @@
\li \l{Profiling QML Applications} \li \l{Profiling QML Applications}
\li \l{Using Valgrind Code Analysis Tools} \li \l{Using Valgrind Code Analysis Tools}
\list \list
\li \l{Detecting Memory Leaks} \li \l{Detecting Memory Leaks with Memcheck}
\li \l{Profiling Function Execution} \li \l{Profiling Function Execution}
\li \l{Running Valgrind Tools on External Applications} \li \l{Running Valgrind Tools on External Applications}
\endlist \endlist
\li \l{Using Clang Static Analyzer} \li \l{Using Clang Static Analyzer}
\li \l{Detecting Memory Leaks with Heob}
\li \l{Analyzing CPU Usage} \li \l{Analyzing CPU Usage}
\endlist \endlist
\li \l{Running Autotests} \li \l{Running Autotests}

View File

@@ -299,6 +299,13 @@
\uicontrol Git > \uicontrol {Remote Repository} > \uicontrol Git > \uicontrol {Remote Repository} >
\uicontrol {Push to Gerrit}. \uicontrol {Push to Gerrit}.
\image qtcreator-gerrit-push.png
Select the \uicontrol {Draft/private} check box to push changes that are
only visible to you and the reviewers. If you are using Gerrit 2.15 or
later, you can select the \uicontrol {Work-in-progress} check box to push
changes that do not generate email notifications.
To view the same information about each change as in the Gerrit To view the same information about each change as in the Gerrit
web interface, select \uicontrol Tools > \uicontrol Git > web interface, select \uicontrol Tools > \uicontrol Git >
\uicontrol {Remote Repository} > \uicontrol Gerrit. \uicontrol {Remote Repository} > \uicontrol Gerrit.

View File

@@ -16,6 +16,7 @@ Module {
: ["$ORIGIN/..", "$ORIGIN/../" + qtc.ide_library_path] : ["$ORIGIN/..", "$ORIGIN/../" + qtc.ide_library_path]
property string resourcesInstallDir: qtc.ide_data_path + "/qbs" property string resourcesInstallDir: qtc.ide_data_path + "/qbs"
property string pluginsInstallDir: qtc.ide_plugin_path + "/qbs/plugins" property string pluginsInstallDir: qtc.ide_plugin_path + "/qbs/plugins"
property string qmlTypeDescriptionsInstallDir: qtc.ide_data_path + "/qml-type-descriptions"
property string appInstallDir: qtc.ide_bin_path property string appInstallDir: qtc.ide_bin_path
property string libexecInstallDir: qtc.ide_libexec_path property string libexecInstallDir: qtc.ide_libexec_path
property bool installHtml: false property bool installHtml: false

View File

@@ -258,6 +258,14 @@ def qdump__ProjectExplorer__FolderNode(d, value):
d.putStringValue(value["m_displayName"]) d.putStringValue(value["m_displayName"])
d.putPlainChildren(value) d.putPlainChildren(value)
def qdump__ProjectExplorer__ToolChain(d, value):
d.putStringValue(value["d"]["m_displayName"])
d.putPlainChildren(value)
def qdump__ProjectExplorer__Kit(d, value):
d.putStringValue(value["d"]["m_unexpandedDisplayName"])
d.putPlainChildren(value)
def qdump__ProjectExplorer__ProjectNode(d, value): def qdump__ProjectExplorer__ProjectNode(d, value):
qdump__ProjectExplorer__FolderNode(d, value) qdump__ProjectExplorer__FolderNode(d, value)

View File

@@ -1,14 +1,32 @@
{ {
"name": "qbs", "name": "qbs",
"searchPaths": [ "searchPaths": [
"$(QBS_IMPORT_PATH)"], "$(QBS_IMPORT_PATH)"
],
"installPaths": [ "installPaths": [
"$(QBS_IMPORT_PATH)"], "$(QBS_IMPORT_PATH)"
],
"implicitImports": [ "implicitImports": [
"__javascriptQt5__"], "__javascriptQt5__"
],
"supportedImports": [ "supportedImports": [
"qbs.base 1.0", "qbs",
"qbs 1.0", "qbs.BinaryFile",
"qbs.fileinfo 1.0", "qbs.BundleTools",
"qbs.probe 1.0"] "qbs.DarwinTools",
"qbs.Environment",
"qbs.File",
"qbs.FileInfo",
"qbs.ModUtils",
"qbs.PathTools",
"qbs.Probes",
"qbs.Process",
"qbs.PropertyList",
"qbs.TemporaryDir",
"qbs.TextFile",
"qbs.UnixUtils",
"qbs.Utilities",
"qbs.WindowsUtils",
"qbs.Xml"
]
} }

View File

@@ -60,6 +60,7 @@ Module {
Property { name: "fileTags"; type: "string"; isList: true } Property { name: "fileTags"; type: "string"; isList: true }
Property { name: "fileTagsFilter"; type: "string"; isList: true } Property { name: "fileTagsFilter"; type: "string"; isList: true }
Property { name: "files"; type: "string"; isList: true } Property { name: "files"; type: "string"; isList: true }
Property { name: "filesAreTargets"; type: "bool" }
Property { name: "name"; type: "string" } Property { name: "name"; type: "string" }
Property { name: "overrideTags"; type: "bool" } Property { name: "overrideTags"; type: "bool" }
Property { name: "prefix"; type: "string" } Property { name: "prefix"; type: "string" }
@@ -72,6 +73,7 @@ Module {
Property { name: "condition"; type: "bool" } Property { name: "condition"; type: "bool" }
Property { name: "name"; type: "string" } Property { name: "name"; type: "string" }
Property { name: "present"; type: "bool" } Property { name: "present"; type: "bool" }
Property { name: "priority"; type: "int" }
Property { name: "setupBuildEnvironment"; type: "QVariant" } Property { name: "setupBuildEnvironment"; type: "QVariant" }
Property { name: "setupRunEnvironment"; type: "QVariant" } Property { name: "setupRunEnvironment"; type: "QVariant" }
Property { name: "validate"; type: "bool" } Property { name: "validate"; type: "bool" }
@@ -187,6 +189,7 @@ Module {
name: "SubProject" name: "SubProject"
exports: [ "qbs/SubProject 1.0" ] exports: [ "qbs/SubProject 1.0" ]
prototype: "QQuickItem" prototype: "QQuickItem"
Property { name: "condition"; type: "bool" }
Property { name: "filePath"; type: "string" } Property { name: "filePath"; type: "string" }
Property { name: "inheritProperties"; type: "bool" } Property { name: "inheritProperties"; type: "bool" }
} }
@@ -201,3 +204,4 @@ Module {
Property { name: "prepare"; type: "QVariant" } Property { name: "prepare"; type: "QVariant" }
} }
} }

View File

@@ -70,4 +70,7 @@ Module {
] ]
Property { name: "filter"; type: "string" } Property { name: "filter"; type: "string" }
} }
Component {
name: "Environment"
}
} }

View File

@@ -157,7 +157,7 @@ Item {
} }
Controls.MenuItem { Controls.MenuItem {
text: qsTr("Insert keyframe") text: qsTr("Insert Keyframe")
visible: hasActiveTimeline visible: hasActiveTimeline
onTriggered: insertKeyframe(backendValue.name) onTriggered: insertKeyframe(backendValue.name)
} }

View File

@@ -237,11 +237,11 @@ Section {
} }
CheckBox { CheckBox {
text: qsTr("Prefer Shaping") text: qsTr("Prefer shaping")
Layout.fillWidth: true Layout.fillWidth: true
backendValue: (backendValues.font_preferShaping === undefined) ? dummyBackendValue : backendValues.font_preferShaping backendValue: (backendValues.font_preferShaping === undefined) ? dummyBackendValue : backendValues.font_preferShaping
tooltip: qsTr("Sometimes, a font will apply complex rules to a set of characters in order to display them correctly.\n" + tooltip: qsTr("Sometimes, a font will apply complex rules to a set of characters in order to display them correctly.\n" +
"In some writing systems, such as Brahmic scripts, this is required in order for the text to be legible, but in e.g." + "In some writing systems, such as Brahmic scripts, this is required in order for the text to be legible, whereas in" +
"Latin script,\n it is merely a cosmetic feature. Setting the preferShaping property to false will disable all such features\nwhen they are not required, which will improve performance in most cases.") "Latin script,\n it is merely a cosmetic feature. Setting the preferShaping property to false will disable all such features\nwhen they are not required, which will improve performance in most cases.")
} }
} }

View File

@@ -131,7 +131,7 @@ Section {
Label { Label {
text: qsTr("Line Height") text: qsTr("Line height")
tooltip: qsTr("Sets the line height for the text.") tooltip: qsTr("Sets the line height for the text.")
} }

View File

@@ -13,7 +13,19 @@ CONFIG += qt warn_on depend_includepath testcase
TEMPLATE = app TEMPLATE = app
SOURCES += %{TestCaseFileWithCppSuffix} SOURCES += %{TestCaseFileWithCppSuffix}
@else @endif
@if "%{TestFrameWork}" == "QtQuickTest"
CONFIG += warn_on qmltestcase
TEMPLATE = app
DISTFILES += \\
%{TestCaseFileWithQmlSuffix}
SOURCES += \\
%{MainCppName}
@endif
@if "%{TestFrameWork}" == "GTest"
include(gtest_dependency.pri) include(gtest_dependency.pri)
TEMPLATE = app TEMPLATE = app

View File

@@ -17,6 +17,7 @@ CppApplication {
] ]
@else @else
consoleApplication: true consoleApplication: true
@endif
@if "%{TestFrameWork}" == "GTest" @if "%{TestFrameWork}" == "GTest"
property string googletestDir: { property string googletestDir: {
@@ -28,7 +29,6 @@ CppApplication {
return Environment.getEnv("GOOGLETEST_DIR") return Environment.getEnv("GOOGLETEST_DIR")
} }
} }
@endif
@if "%{GTestCXX11}" == "true" @if "%{GTestCXX11}" == "true"
cpp.cxxLanguageVersion: "c++11" cpp.cxxLanguageVersion: "c++11"
@@ -52,4 +52,24 @@ CppApplication {
].concat(googleCommon.getGTestAll(googletestDir)) ].concat(googleCommon.getGTestAll(googletestDir))
.concat(googleCommon.getGMockAll(googletestDir)) .concat(googleCommon.getGMockAll(googletestDir))
@endif @endif
@if "%{TestFrameWork}" == "QtQuickTest"
Depends { name: "cpp" }
Depends { name: "Qt.core" }
Depends {
condition: Qt.core.versionMajor > 4
name: "Qt.qmltest"
}
Group {
name: "main application"
files: [ "%{MainCppName}" ]
}
Group {
name: "qml test files"
files: "%{TestCaseFileWithQmlSuffix}"
}
cpp.defines: base.concat("QUICK_TEST_SOURCE_DIR=\\"" + path + "\\"")
@endif
} }

View File

@@ -13,6 +13,7 @@ find_package(Qt5Gui REQUIRED)
SET(CMAKE_AUTOMOC ON) SET(CMAKE_AUTOMOC ON)
SET(CMAKE_INCLUDE_CURRENT_DIR ON) SET(CMAKE_INCLUDE_CURRENT_DIR ON)
SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
ENABLE_TESTING() ENABLE_TESTING()
add_executable(${PROJECT_NAME} %{TestCaseFileWithCppSuffix}) add_executable(${PROJECT_NAME} %{TestCaseFileWithCppSuffix})
@@ -24,7 +25,26 @@ target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Gui Qt5::Test)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Test) target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Test)
@endif @endif
@else @endif
@if "%{TestFrameWork}" == "QtQuickTest"
find_package(Qt5QuickTest REQUIRED)
SET(CMAKE_AUTOMOC ON)
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
ENABLE_TESTING()
# no need to copy around qml test files for shadow builds - just set the respective define
add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
add_executable(${PROJECT_NAME} %{MainCppName})
add_test(${PROJECT_NAME} COMMAND ${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::QuickTest)
@endif
@if "%{TestFrameWork}" == "GTest"
@if "%{GTestCXX11}" == "true" @if "%{GTestCXX11}" == "true"
add_definitions(-DGTEST_LANGUAGE_CXX11) add_definitions(-DGTEST_LANGUAGE_CXX11)

View File

@@ -1,3 +1,8 @@
@if "%{TestFrameWork}" == "QtQuickTest"
#include <QtQuickTest/quicktest.h>
QUICK_TEST_MAIN(example)
@else
%{Cpp:LicenseTemplate}\ %{Cpp:LicenseTemplate}\
#include "%{TestCaseFileWithHeaderSuffix}" #include "%{TestCaseFileWithHeaderSuffix}"
@@ -8,3 +13,4 @@ int main(int argc, char *argv[])
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
@endif

View File

@@ -0,0 +1,19 @@
import QtQuick 2.0
import QtTest 1.0
TestCase {
name: "%{TestCaseName}"
@if "%{GenerateInitAndCleanup}" == "true"
function initTestCase() {
}
function cleanupTestCase() {
}
@endif
function test_case1() {
compare(1 + 1, 2, "sanity check");
verify(true);
}
}

View File

@@ -39,6 +39,10 @@
{ {
"key": "TestCaseFileWithCppSuffix", "key": "TestCaseFileWithCppSuffix",
"value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++src') }" "value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++src') }"
},
{
"key": "TestCaseFileWithQmlSuffix",
"value": "%{JS: 'tst_%{TestCaseName}.qml'.toLowerCase() }"
} }
], ],
@@ -73,9 +77,14 @@
"value": "QtTest" "value": "QtTest"
}, },
{ {
"trKey": "Googletest", "trKey": "Google Test",
"value": "GTest" "value": "GTest"
},
{
"trKey": "Qt Quick Test",
"value": "QtQuickTest"
} }
] ]
} }
}, },
@@ -107,7 +116,7 @@
{ {
"name": "GenerateInitAndCleanup", "name": "GenerateInitAndCleanup",
"trDisplayName": "Generate initialization and cleanup code", "trDisplayName": "Generate initialization and cleanup code",
"visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}", "visible": "%{JS: [ 'QtTest', 'QtQuickTest' ].indexOf('%{TestFrameWork}') >= 0 }",
"type": "CheckBox", "type": "CheckBox",
"data": { "data": {
"checked": false "checked": false
@@ -174,7 +183,7 @@
"enabled": "%{IsTopLevelProject}", "enabled": "%{IsTopLevelProject}",
"data": { "data": {
"projectFilePath": "%{ProjectFilePath}", "projectFilePath": "%{ProjectFilePath}",
"requiredFeatures": [ "%{JS: ('%{BuildSystem}' == 'cmake' && '%{TestFrameWork}' == 'QtTest') ? 'QtSupport.Wizards.FeatureQt.5' : 'QtSupport.Wizards.FeatureQt' }" ] "requiredFeatures": [ "%{JS: (('%{BuildSystem}' === 'cmake' && '%{TestFrameWork}' === 'QtTest') || '%{TestFrameWork}' === 'QtQuickTest') ? 'QtSupport.Wizards.FeatureQt.5' : 'QtSupport.Wizards.FeatureQt' }" ]
} }
}, },
{ {
@@ -237,7 +246,13 @@
{ {
"source": "files/tst_main.cpp", "source": "files/tst_main.cpp",
"target": "%{MainCppName}", "target": "%{MainCppName}",
"condition": "%{JS: '%{TestFrameWork}' == 'GTest'}", "condition": "%{JS: ['GTest', 'QtQuickTest'].indexOf('%{TestFrameWork}') >= 0}",
"openInEditor": true
},
{
"source": "files/tst_qml.tmpl",
"target": "%{TestCaseFileWithQmlSuffix}",
"condition": "%{JS: '%{TestFrameWork}' === 'QtQuickTest'}",
"openInEditor": true "openInEditor": true
}, },
{ {

View File

@@ -8,7 +8,7 @@
"trDisplayCategory": "Modeling", "trDisplayCategory": "Modeling",
"iconText": "scxml", "iconText": "scxml",
"platformIndependent": true, "platformIndependent": true,
"enabled": "%{JS: [ %{Plugins} ].indexOf('QtSupport') >= 0}", "enabled": "%{JS: [ %{Plugins} ].indexOf('ScxmlEditor') >= 0}",
"options": "options":
[ [

View File

@@ -7,7 +7,7 @@
"trDisplayName": "Plain C Application", "trDisplayName": "Plain C Application",
"trDisplayCategory": "Non-Qt Project", "trDisplayCategory": "Non-Qt Project",
"icon": "../../global/consoleapplication.png", "icon": "../../global/consoleapplication.png",
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 || [ %{Plugins} ].indexOf('QbsProjectManager') >= 0 || [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0}", "enabled": "%{JS: [ %{Plugins} ].indexOf('CppEditor') >= 0 && ([ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 || [ %{Plugins} ].indexOf('QbsProjectManager') >= 0 || [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0)}",
"options": "options":
[ [

View File

@@ -7,7 +7,7 @@
"trDisplayName": "Plain C++ Application", "trDisplayName": "Plain C++ Application",
"trDisplayCategory": "Non-Qt Project", "trDisplayCategory": "Non-Qt Project",
"icon": "../../global/consoleapplication.png", "icon": "../../global/consoleapplication.png",
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 || [ %{Plugins} ].indexOf('QbsProjectManager') >= 0 || [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0}", "enabled": "%{JS: [ %{Plugins} ].indexOf('CppEditor') >= 0 && ([ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 || [ %{Plugins} ].indexOf('QbsProjectManager') >= 0 || [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0)}",
"options": "options":
[ [

View File

@@ -20,25 +20,9 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
const QUrl mainQml(QStringLiteral("qrc:/main.qml")); if (engine.rootObjects().isEmpty())
return -1;
// Catch the objectCreated signal, so that we can determine if the root component was loaded
// successfully. If not, then the object created from it will be null. The root component may
// get loaded asynchronously.
const QMetaObject::Connection connection = QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated,
&app, [&](QObject *object, const QUrl &url) {
if (url != mainQml)
return;
if (!object)
app.exit(-1);
else
QObject::disconnect(connection);
}, Qt::QueuedConnection);
engine.load(mainQml);
return app.exec(); return app.exec();
} }

View File

@@ -27,6 +27,10 @@ Product {
"themes/**/*", "themes/**/*",
"welcomescreen/**/*" "welcomescreen/**/*"
] ]
excludeFiles: [
"qml-type-descriptions/qbs-bundle.json",
"qml-type-descriptions/qbs.qmltypes",
]
} }
Group { Group {

View File

@@ -158,8 +158,8 @@ static inline int askMsgSendFailed()
{ {
return QMessageBox::question(0, QApplication::translate("Application","Could not send message"), return QMessageBox::question(0, QApplication::translate("Application","Could not send message"),
QCoreApplication::translate("Application", "Unable to send command line arguments " QCoreApplication::translate("Application", "Unable to send command line arguments "
"to the already running instance. It appears to be not " "to the already running instance. It does not appear to "
"responding. Do you want to start a new instance of " "be responding. Do you want to start a new instance of "
"%1?").arg(Core::Constants::IDE_DISPLAY_NAME), "%1?").arg(Core::Constants::IDE_DISPLAY_NAME),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Retry, QMessageBox::Yes | QMessageBox::No | QMessageBox::Retry,
QMessageBox::Retry); QMessageBox::Retry);

View File

@@ -85,7 +85,7 @@ void ProcessCreator::checkIfProcessPathExists() const
{ {
if (!QFileInfo::exists(m_processPath)) { if (!QFileInfo::exists(m_processPath)) {
const QString messageTemplate = QCoreApplication::translate("ProcessCreator", const QString messageTemplate = QCoreApplication::translate("ProcessCreator",
"Executable does not exists: %1"); "Executable does not exist: %1");
throwProcessException(messageTemplate.arg(m_processPath)); throwProcessException(messageTemplate.arg(m_processPath));
} }
} }
@@ -101,7 +101,7 @@ void ProcessCreator::dispatchProcessError(QProcess *process) const
switch (process->error()) { switch (process->error()) {
case QProcess::UnknownError: { case QProcess::UnknownError: {
const QString message = QCoreApplication::translate("ProcessCreator", const QString message = QCoreApplication::translate("ProcessCreator",
"Unknown error happend."); "Unknown error occurred.");
throwProcessException(message); throwProcessException(message);
}; };
case QProcess::Crashed: { case QProcess::Crashed: {
@@ -116,7 +116,7 @@ void ProcessCreator::dispatchProcessError(QProcess *process) const
}; };
case QProcess::Timedout: { case QProcess::Timedout: {
const QString message = QCoreApplication::translate("ProcessCreator", const QString message = QCoreApplication::translate("ProcessCreator",
"Process timeouted."); "Process timed out.");
throwProcessException(message); throwProcessException(message);
}; };
case QProcess::WriteError: { case QProcess::WriteError: {

View File

@@ -515,6 +515,7 @@ bool DiagramSceneModel::exportSvg(const QString &fileName, bool selectedElements
return true; return true;
#else // QT_NO_SVG #else // QT_NO_SVG
Q_UNUSED(fileName); Q_UNUSED(fileName);
Q_UNUSED(selectedElements);
return false; return false;
#endif // QT_NO_SVG #endif // QT_NO_SVG
} }

View File

@@ -217,7 +217,7 @@ void QmlDebugConnectionManager::destroyConnection()
void QmlDebugConnectionManager::qmlDebugConnectionOpened() void QmlDebugConnectionManager::qmlDebugConnectionOpened()
{ {
logState(tr("Debug connection opened")); logState(tr("Debug connection opened."));
QTC_ASSERT(m_connection, return); QTC_ASSERT(m_connection, return);
QTC_ASSERT(m_connection->isConnected(), return); QTC_ASSERT(m_connection->isConnected(), return);
stopConnectionTimer(); stopConnectionTimer();
@@ -226,7 +226,7 @@ void QmlDebugConnectionManager::qmlDebugConnectionOpened()
void QmlDebugConnectionManager::qmlDebugConnectionClosed() void QmlDebugConnectionManager::qmlDebugConnectionClosed()
{ {
logState(tr("Debug connection closed")); logState(tr("Debug connection closed."));
QTC_ASSERT(m_connection, return); QTC_ASSERT(m_connection, return);
QTC_ASSERT(!m_connection->isConnected(), return); QTC_ASSERT(!m_connection->isConnected(), return);
destroyConnection(); destroyConnection();
@@ -235,7 +235,7 @@ void QmlDebugConnectionManager::qmlDebugConnectionClosed()
void QmlDebugConnectionManager::qmlDebugConnectionFailed() void QmlDebugConnectionManager::qmlDebugConnectionFailed()
{ {
logState(tr("Debug connection failed")); logState(tr("Debug connection failed."));
QTC_ASSERT(m_connection, return); QTC_ASSERT(m_connection, return);
QTC_ASSERT(!m_connection->isConnected(), /**/); QTC_ASSERT(!m_connection->isConnected(), /**/);

View File

@@ -68,7 +68,6 @@ ScrollView {
// switch to non-interactive ourselves, though. // switch to non-interactive ourselves, though.
property bool stayInteractive: true property bool stayInteractive: true
onStayInteractiveChanged: flick.interactive = stayInteractive onStayInteractiveChanged: flick.interactive = stayInteractive
onWidthChanged: scroll()
Flickable { Flickable {
id: flick id: flick
@@ -89,6 +88,15 @@ ScrollView {
recursionGuard = false; recursionGuard = false;
} }
// Logically we should bind to scroller.width above as we use scroller.width in scroll().
// However, this width changes before scroller.width when the window is resized and if we
// don't explicitly set contentX here, for some reason an automatic change in contentX is
// triggered after this width has changed, but before scroller.width changes. This would be
// indistinguishabe from a manual flick by the user and thus changes the range position. We
// don't want to change the range position on resizing the window. Therefore we bind to this
// width.
onWidthChanged: scroll()
// Update the zoom control on scrolling. // Update the zoom control on scrolling.
onContentXChanged: guarded(function() { onContentXChanged: guarded(function() {
var newStartTime = contentX * zoomer.rangeDuration / scroller.width var newStartTime = contentX * zoomer.rangeDuration / scroller.width

View File

@@ -66,7 +66,8 @@ static bool isQmake(const QString &path)
QFileInfo fi(path); QFileInfo fi(path);
if (BuildableHelperLibrary::isQtChooser(fi)) if (BuildableHelperLibrary::isQtChooser(fi))
fi.setFile(BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget())); fi.setFile(BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget()));
if (!fi.exists() || fi.isDir())
return false;
return !BuildableHelperLibrary::qtVersionForQMake(fi.absoluteFilePath()).isEmpty(); return !BuildableHelperLibrary::qtVersionForQMake(fi.absoluteFilePath()).isEmpty();
} }
@@ -154,7 +155,7 @@ QStringList BuildableHelperLibrary::possibleQMakeCommands()
// On Unix some distributions renamed qmake with a postfix to avoid clashes // On Unix some distributions renamed qmake with a postfix to avoid clashes
// On OS X, Qt 4 binary packages also has renamed qmake. There are also symbolic links that are // On OS X, Qt 4 binary packages also has renamed qmake. There are also symbolic links that are
// named "qmake", but the file dialog always checks against resolved links (native Cocoa issue) // named "qmake", but the file dialog always checks against resolved links (native Cocoa issue)
return QStringList(QLatin1String("qmake*")); return QStringList(HostOsInfo::withExecutableSuffix("qmake*"));
} }
// Copy helper source files to a target directory, replacing older files. // Copy helper source files to a target directory, replacing older files.

View File

@@ -80,7 +80,7 @@
<item> <item>
<widget class="QCheckBox" name="removeVCCheckBox"> <widget class="QCheckBox" name="removeVCCheckBox">
<property name="text"> <property name="text">
<string>&amp;Remove from Version Control</string> <string>&amp;Remove from version control</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@@ -640,7 +640,7 @@ QVariant SettingsAccessor::retrieveSharedSettings() const
QString SettingsAccessor::differentEnvironmentMsg(const QString &projectName) QString SettingsAccessor::differentEnvironmentMsg(const QString &projectName)
{ {
return QApplication::translate("Utils::EnvironmentIdAccessor", return QApplication::translate("Utils::EnvironmentIdAccessor",
"Settings File for \"%1\" from a different Environment?") "Settings File for \"%1\" from a Different Environment?")
.arg(projectName); .arg(projectName);
} }

View File

@@ -26,10 +26,10 @@
#include "winutils.h" #include "winutils.h"
#include "qtcassert.h" #include "qtcassert.h"
// Enable WinAPI Windows XP and later // Enable WinAPI Windows Vista and later
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#undef _WIN32_WINNT #undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 #define _WIN32_WINNT 0x0600 // Needed for QueryFullProcessImageName
#include <windows.h> #include <windows.h>
#endif #endif
@@ -168,6 +168,23 @@ QTCREATOR_UTILS_EXPORT bool is64BitWindowsBinary(const QString &binaryIn)
#endif #endif
} }
QTCREATOR_UTILS_EXPORT QString imageName(quint32 processId)
{
QString result;
#ifdef Q_OS_WIN
HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
if (handle == NULL)
return result;
wchar_t path[MAX_PATH];
DWORD pathLen = MAX_PATH;
if (QueryFullProcessImageName(handle, 0, path, &pathLen))
result = QString::fromUtf16(reinterpret_cast<const ushort*>(path));
CloseHandle(handle);
#endif
return result;
}
WindowsCrashDialogBlocker::WindowsCrashDialogBlocker() WindowsCrashDialogBlocker::WindowsCrashDialogBlocker()
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
: silenceErrorMode(SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS), : silenceErrorMode(SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS),

View File

@@ -44,6 +44,9 @@ QTCREATOR_UTILS_EXPORT bool is64BitWindowsSystem();
// Check for a 64bit binary. // Check for a 64bit binary.
QTCREATOR_UTILS_EXPORT bool is64BitWindowsBinary(const QString &binary); QTCREATOR_UTILS_EXPORT bool is64BitWindowsBinary(const QString &binary);
// Get the path to the executable for a given PID.
QTCREATOR_UTILS_EXPORT QString imageName(quint32 processId);
// //
// RAII class to temporarily prevent windows crash messages from popping up using the // RAII class to temporarily prevent windows crash messages from popping up using the
// application-global (!) error mode. // application-global (!) error mode.

View File

@@ -558,9 +558,8 @@ ClangCompletionAssistProcessor::extractLineColumn(int position)
int line = -1, column = -1; int line = -1, column = -1;
::Utils::Text::convertPosition(m_interface->textDocument(), position, &line, &column); ::Utils::Text::convertPosition(m_interface->textDocument(), position, &line, &column);
const QTextBlock block = m_interface->textDocument()->findBlock(position);
const QString stringOnTheLeft = block.text().left(column); column = Utils::clangColumn(m_interface->textDocument()->findBlock(position), column);
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
return {line, column}; return {line, column};
} }

View File

@@ -64,6 +64,9 @@ int positionInText(QTextDocument *textDocument,
{ {
auto textBlock = textDocument->findBlockByNumber( auto textBlock = textDocument->findBlockByNumber(
static_cast<int>(sourceLocationContainer.line()) - 1); static_cast<int>(sourceLocationContainer.line()) - 1);
// 'sourceLocationContainer' already has the CppEditor column converted from
// the utf8 byte offset from the beginning of the line provided by clang.
// - 1 is required for 0-based columns.
const int column = static_cast<int>(sourceLocationContainer.column()) - 1; const int column = static_cast<int>(sourceLocationContainer.column()) - 1;
return textBlock.position() + column; return textBlock.position() + column;
} }

View File

@@ -356,9 +356,7 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams &param
if (!isCursorOnIdentifier(params.textCursor)) if (!isCursorOnIdentifier(params.textCursor))
return defaultCursorInfoFuture(); return defaultCursorInfoFuture();
const QTextBlock block = params.textCursor.document()->findBlockByNumber(line - 1); column = Utils::clangColumn(params.textCursor.document()->findBlockByNumber(line - 1), column);
const QString stringOnTheLeft = block.text().left(column);
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
const CppTools::SemanticInfo::LocalUseMap localUses const CppTools::SemanticInfo::LocalUseMap localUses
= CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column); = CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column);

View File

@@ -43,6 +43,7 @@
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QStringList> #include <QStringList>
#include <QTextBlock>
using namespace ClangCodeModel; using namespace ClangCodeModel;
using namespace ClangCodeModel::Internal; using namespace ClangCodeModel::Internal;
@@ -190,5 +191,15 @@ void setLastSentDocumentRevision(const QString &filePath, uint revision)
document->sendTracker().setLastSentRevision(int(revision)); document->sendTracker().setLastSentRevision(int(revision));
} }
int clangColumn(const QTextBlock &line, int cppEditorColumn)
{
// (1) cppEditorColumn is the actual column shown by CppEditor.
// (2) The return value is the column in Clang which is the utf8 byte offset from the beginning
// of the line.
// Here we convert column from (1) to (2).
// '+ 1' is for 1-based columns
return line.text().left(cppEditorColumn).toUtf8().size() + 1;
}
} // namespace Utils } // namespace Utils
} // namespace Clang } // namespace Clang

View File

@@ -27,6 +27,10 @@
#include <cpptools/projectpart.h> #include <cpptools/projectpart.h>
QT_BEGIN_NAMESPACE
class QTextBlock;
QT_END_NAMESPACE
namespace CppTools { namespace CppTools {
class CppEditorDocumentHandle; class CppEditorDocumentHandle;
} }
@@ -46,6 +50,7 @@ CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath);
CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath); CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath);
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart); bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
QString projectPartIdForFile(const QString &filePath); QString projectPartIdForFile(const QString &filePath);
int clangColumn(const QTextBlock &lineText, int cppEditorColumn);
} // namespace Utils } // namespace Utils
} // namespace Clang } // namespace Clang

View File

@@ -61,6 +61,7 @@
#include <utils/checkablemessagebox.h> #include <utils/checkablemessagebox.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/temporarydirectory.h> #include <utils/temporarydirectory.h>
#include <utils/qtcprocess.h>
#include <QAction> #include <QAction>
#include <QLoggingCategory> #include <QLoggingCategory>
@@ -71,6 +72,40 @@ using namespace Utils;
static Q_LOGGING_CATEGORY(LOG, "qtc.clangstaticanalyzer.runcontrol") static Q_LOGGING_CATEGORY(LOG, "qtc.clangstaticanalyzer.runcontrol")
static QStringList splitArgs(QString &argsString)
{
QStringList result;
Utils::QtcProcess::ArgIterator it(&argsString);
while (it.next())
result.append(it.value());
return result;
}
template<size_t Size>
static QStringList extraOptions(const char(&environment)[Size])
{
if (!qEnvironmentVariableIsSet(environment))
return QStringList();
QString arguments = QString::fromLocal8Bit(qgetenv(environment));
return splitArgs(arguments);
}
static QStringList extraClangStaticAnalyzerPrependOptions() {
constexpr char csaPrependOptions[] = "QTC_CLANG_CSA_CMD_PREPEND";
static const QStringList options = extraOptions(csaPrependOptions);
if (!options.isEmpty())
qWarning() << "ClangStaticAnalyzer options are prepended with " << options.toVector();
return options;
}
static QStringList extraClangStaticAnalyzerAppendOptions() {
constexpr char csaAppendOptions[] = "QTC_CLANG_CSA_CMD_APPEND";
static const QStringList options = extraOptions(csaAppendOptions);
if (!options.isEmpty())
qWarning() << "ClangStaticAnalyzer options are appended with " << options.toVector();
return options;
}
namespace ClangStaticAnalyzer { namespace ClangStaticAnalyzer {
namespace Internal { namespace Internal {
@@ -303,7 +338,9 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage(); const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
CompilerOptionsBuilder optionsBuilder(*projectPart, clangVersion, CompilerOptionsBuilder optionsBuilder(*projectPart, clangVersion,
clangResourceDirectory); clangResourceDirectory);
const QStringList arguments = optionsBuilder.build(file.kind, pchUsage); QStringList arguments = extraClangStaticAnalyzerPrependOptions();
arguments.append(optionsBuilder.build(file.kind, pchUsage));
arguments.append(extraClangStaticAnalyzerAppendOptions());
unitsToAnalyze << AnalyzeUnit(file.path, arguments); unitsToAnalyze << AnalyzeUnit(file.path, arguments);
} }
} }

View File

@@ -77,6 +77,9 @@ const char CUT[] = "QtCreator.Cut";
const char SELECTALL[] = "QtCreator.SelectAll"; const char SELECTALL[] = "QtCreator.SelectAll";
const char GOTO[] = "QtCreator.Goto"; const char GOTO[] = "QtCreator.Goto";
const char ZOOM_IN[] = "QtCreator.ZoomIn";
const char ZOOM_OUT[] = "QtCreator.ZoomOut";
const char ZOOM_RESET[] = "QtCreator.ZoomReset";
const char NEW[] = "QtCreator.New"; const char NEW[] = "QtCreator.New";
const char OPEN[] = "QtCreator.Open"; const char OPEN[] = "QtCreator.Open";
@@ -145,6 +148,7 @@ const char G_FILE_NEW[] = "QtCreator.Group.File.New";
const char G_FILE_OPEN[] = "QtCreator.Group.File.Open"; const char G_FILE_OPEN[] = "QtCreator.Group.File.Open";
const char G_FILE_PROJECT[] = "QtCreator.Group.File.Project"; const char G_FILE_PROJECT[] = "QtCreator.Group.File.Project";
const char G_FILE_SAVE[] = "QtCreator.Group.File.Save"; const char G_FILE_SAVE[] = "QtCreator.Group.File.Save";
const char G_FILE_EXPORT[] = "QtCreator.Group.File.Export";
const char G_FILE_CLOSE[] = "QtCreator.Group.File.Close"; const char G_FILE_CLOSE[] = "QtCreator.Group.File.Close";
const char G_FILE_PRINT[] = "QtCreator.Group.File.Print"; const char G_FILE_PRINT[] = "QtCreator.Group.File.Print";
const char G_FILE_OTHER[] = "QtCreator.Group.File.Other"; const char G_FILE_OTHER[] = "QtCreator.Group.File.Other";

View File

@@ -17,11 +17,18 @@ Project {
condition: qbs.targetOS.contains("windows") condition: qbs.targetOS.contains("windows")
} }
Depends { name: "Qt.script"; required: false }
Depends { name: "Utils" } Depends { name: "Utils" }
Depends { name: "Aggregation" } Depends { name: "Aggregation" }
Depends { name: "app_version_header" } Depends { name: "app_version_header" }
Properties {
condition: Qt.script.present
cpp.defines: base.concat("WITH_JAVASCRIPTFILTER")
}
cpp.dynamicLibraries: { cpp.dynamicLibraries: {
if (qbs.targetOS.contains("windows")) if (qbs.targetOS.contains("windows"))
return ["ole32", "user32"] return ["ole32", "user32"]
@@ -341,8 +348,6 @@ Project {
"filesystemfilter.ui", "filesystemfilter.ui",
"ilocatorfilter.cpp", "ilocatorfilter.cpp",
"ilocatorfilter.h", "ilocatorfilter.h",
"javascriptfilter.cpp",
"javascriptfilter.h",
"locatorconstants.h", "locatorconstants.h",
"locatorfiltersfilter.cpp", "locatorfiltersfilter.cpp",
"locatorfiltersfilter.h", "locatorfiltersfilter.h",
@@ -362,6 +367,16 @@ Project {
] ]
} }
Group {
name: "Locator Javascript Filter"
condition: Qt.script.present
prefix: "locator/"
files: [
"javascriptfilter.cpp",
"javascriptfilter.h",
]
}
Group { Group {
name: "Locator_mac" name: "Locator_mac"
condition: qbs.targetOS.contains("macos") condition: qbs.targetOS.contains("macos")

View File

@@ -50,6 +50,8 @@ namespace {
const int ICON_SIZE = 48; const int ICON_SIZE = 48;
const char LAST_CATEGORY_KEY[] = "Core/NewDialog/LastCategory"; const char LAST_CATEGORY_KEY[] = "Core/NewDialog/LastCategory";
const char LAST_PLATFORM_KEY[] = "Core/NewDialog/LastPlatform"; const char LAST_PLATFORM_KEY[] = "Core/NewDialog/LastPlatform";
const char ALLOW_ALL_TEMPLATES[] = "Core/NewDialog/AllowAllTemplates";
const char SHOW_PLATOFORM_FILTER[] = "Core/NewDialog/ShowPlatformFilter";
class WizardFactoryContainer class WizardFactoryContainer
{ {
@@ -79,13 +81,28 @@ public:
invalidateFilter(); invalidateFilter();
} }
void manualReset()
{
beginResetModel();
endResetModel();
}
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
{ {
if (!sourceParent.isValid()) if (!sourceParent.isValid())
return true; return true;
if (!sourceParent.parent().isValid()) { // category
const QModelIndex sourceCategoryIndex = sourceModel()->index(sourceRow, 0, sourceParent);
for (int i = 0; i < sourceModel()->rowCount(sourceCategoryIndex); ++i)
if (filterAcceptsRow(i, sourceCategoryIndex))
return true;
return false;
}
QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
Core::IWizardFactory *wizard = factoryOfItem(qobject_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(sourceIndex)); Core::IWizardFactory *wizard =
factoryOfItem(qobject_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(sourceIndex));
if (wizard) if (wizard)
return wizard->isAvailable(m_platform); return wizard->isAvailable(m_platform);
@@ -95,51 +112,6 @@ private:
Core::Id m_platform; Core::Id m_platform;
}; };
class TwoLevelProxyModel : public QAbstractProxyModel
{
// Q_OBJECT
public:
TwoLevelProxyModel(QObject *parent = nullptr): QAbstractProxyModel(parent) {}
QModelIndex index(int row, int column, const QModelIndex &parent) const override
{
QModelIndex ourModelIndex = sourceModel()->index(row, column, mapToSource(parent));
return createIndex(row, column, ourModelIndex.internalPointer());
}
QModelIndex parent(const QModelIndex &index) const override
{
return mapFromSource(mapToSource(index).parent());
}
int rowCount(const QModelIndex &index) const override
{
if (index.isValid() && index.parent().isValid() && !index.parent().parent().isValid())
return 0;
else
return sourceModel()->rowCount(mapToSource(index));
}
int columnCount(const QModelIndex &index) const override
{
return sourceModel()->columnCount(mapToSource(index));
}
QModelIndex mapFromSource (const QModelIndex &index) const override
{
if (!index.isValid())
return QModelIndex();
return createIndex(index.row(), index.column(), index.internalPointer());
}
QModelIndex mapToSource (const QModelIndex &index) const override
{
if (!index.isValid())
return QModelIndex();
return static_cast<TwoLevelProxyModel*>(sourceModel())->createIndex(index.row(), index.column(), index.internalPointer());
}
};
#define ROW_HEIGHT 24 #define ROW_HEIGHT 24
class FancyTopLevelDelegate : public QItemDelegate class FancyTopLevelDelegate : public QItemDelegate
@@ -209,12 +181,11 @@ NewDialog::NewDialog(QWidget *parent) :
m_okButton->setText(tr("Choose...")); m_okButton->setText(tr("Choose..."));
m_model = new QStandardItemModel(this); m_model = new QStandardItemModel(this);
m_twoLevelProxyModel = new TwoLevelProxyModel(this);
m_twoLevelProxyModel->setSourceModel(m_model);
m_filterProxyModel = new PlatformFilterProxyModel(this); m_filterProxyModel = new PlatformFilterProxyModel(this);
m_filterProxyModel->setSourceModel(m_model); m_filterProxyModel->setSourceModel(m_model);
m_ui->templateCategoryView->setModel(m_twoLevelProxyModel); m_ui->templateCategoryView->setModel(m_filterProxyModel);
m_ui->templateCategoryView->setEditTriggers(QAbstractItemView::NoEditTriggers); m_ui->templateCategoryView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_ui->templateCategoryView->setItemDelegate(new FancyTopLevelDelegate); m_ui->templateCategoryView->setItemDelegate(new FancyTopLevelDelegate);
@@ -269,7 +240,10 @@ void NewDialog::setWizardFactories(QList<IWizardFactory *> factories,
m_dummyIcon = QIcon(":/utils/images/wizardicon-file.png"); m_dummyIcon = QIcon(":/utils/images/wizardicon-file.png");
QSet<Id> availablePlatforms = IWizardFactory::allAvailablePlatforms(); QSet<Id> availablePlatforms = IWizardFactory::allAvailablePlatforms();
m_ui->comboBox->addItem(tr("All Templates"), Id().toSetting());
const bool allowAllTemplates = ICore::settings()->value(ALLOW_ALL_TEMPLATES, true).toBool();
if (allowAllTemplates)
m_ui->comboBox->addItem(tr("All Templates"), Id().toSetting());
foreach (Id platform, availablePlatforms) { foreach (Id platform, availablePlatforms) {
const QString displayNameForPlatform = IWizardFactory::displayNameForPlatform(platform); const QString displayNameForPlatform = IWizardFactory::displayNameForPlatform(platform);
@@ -279,6 +253,10 @@ void NewDialog::setWizardFactories(QList<IWizardFactory *> factories,
m_ui->comboBox->setCurrentIndex(0); // "All templates" m_ui->comboBox->setCurrentIndex(0); // "All templates"
m_ui->comboBox->setEnabled(!availablePlatforms.isEmpty()); m_ui->comboBox->setEnabled(!availablePlatforms.isEmpty());
const bool showPlatformFilter = ICore::settings()->value(SHOW_PLATOFORM_FILTER, true).toBool();
if (!showPlatformFilter)
m_ui->comboBox->hide();
foreach (IWizardFactory *factory, factories) { foreach (IWizardFactory *factory, factories) {
QStandardItem *kindItem; QStandardItem *kindItem;
switch (factory->kind()) { switch (factory->kind()) {
@@ -309,21 +287,23 @@ void NewDialog::showDialog()
m_ui->comboBox->setCurrentIndex(index); m_ui->comboBox->setCurrentIndex(index);
} }
static_cast<PlatformFilterProxyModel*>(m_filterProxyModel)->manualReset();
if (!lastCategory.isEmpty()) if (!lastCategory.isEmpty())
foreach (QStandardItem* item, m_categoryItems) { foreach (QStandardItem* item, m_categoryItems) {
if (item->data(Qt::UserRole) == lastCategory) if (item->data(Qt::UserRole) == lastCategory)
idx = m_twoLevelProxyModel->mapToSource(m_model->indexFromItem(item)); idx = m_filterProxyModel->mapFromSource(m_model->indexFromItem(item));
} }
if (!idx.isValid()) if (!idx.isValid())
idx = m_twoLevelProxyModel->index(0,0, m_twoLevelProxyModel->index(0,0)); idx = m_filterProxyModel->index(0,0, m_filterProxyModel->index(0,0));
m_ui->templateCategoryView->setCurrentIndex(idx); m_ui->templateCategoryView->setCurrentIndex(idx);
// We need to set ensure that the category has default focus // We need to set ensure that the category has default focus
m_ui->templateCategoryView->setFocus(Qt::NoFocusReason); m_ui->templateCategoryView->setFocus(Qt::NoFocusReason);
for (int row = 0; row < m_twoLevelProxyModel->rowCount(); ++row) for (int row = 0; row < m_filterProxyModel->rowCount(); ++row)
m_ui->templateCategoryView->setExpanded(m_twoLevelProxyModel->index(row, 0), true); m_ui->templateCategoryView->setExpanded(m_filterProxyModel->index(row, 0), true);
// Ensure that item description is visible on first show // Ensure that item description is visible on first show
currentItemChanged(m_ui->templatesView->rootIndex().child(0,0)); currentItemChanged(m_ui->templatesView->rootIndex().child(0,0));
@@ -426,7 +406,7 @@ void NewDialog::addItem(QStandardItem *topLevelCategoryItem, IWizardFactory *fac
void NewDialog::currentCategoryChanged(const QModelIndex &index) void NewDialog::currentCategoryChanged(const QModelIndex &index)
{ {
if (index.parent() != m_model->invisibleRootItem()->index()) { if (index.parent() != m_model->invisibleRootItem()->index()) {
QModelIndex sourceIndex = m_twoLevelProxyModel->mapToSource(index); QModelIndex sourceIndex = m_filterProxyModel->mapToSource(index);
sourceIndex = m_filterProxyModel->mapFromSource(sourceIndex); sourceIndex = m_filterProxyModel->mapFromSource(sourceIndex);
m_ui->templatesView->setRootIndex(sourceIndex); m_ui->templatesView->setRootIndex(sourceIndex);
// Focus the first item by default // Focus the first item by default
@@ -472,8 +452,9 @@ void NewDialog::currentItemChanged(const QModelIndex &index)
void NewDialog::saveState() void NewDialog::saveState()
{ {
QModelIndex idx = m_ui->templateCategoryView->currentIndex(); const QModelIndex filterIdx = m_ui->templateCategoryView->currentIndex();
QStandardItem *currentItem = m_model->itemFromIndex(m_twoLevelProxyModel->mapToSource(idx)); const QModelIndex idx = m_filterProxyModel->mapToSource(filterIdx);
QStandardItem *currentItem = m_model->itemFromIndex(idx);
if (currentItem) if (currentItem)
ICore::settings()->setValue(QLatin1String(LAST_CATEGORY_KEY), ICore::settings()->setValue(QLatin1String(LAST_CATEGORY_KEY),
currentItem->data(Qt::UserRole)); currentItem->data(Qt::UserRole));

View File

@@ -81,7 +81,6 @@ private:
Ui::NewDialog *m_ui; Ui::NewDialog *m_ui;
QStandardItemModel *m_model; QStandardItemModel *m_model;
QAbstractProxyModel *m_twoLevelProxyModel;
QSortFilterProxyModel *m_filterProxyModel; QSortFilterProxyModel *m_filterProxyModel;
QPushButton *m_okButton; QPushButton *m_okButton;
QIcon m_dummyIcon; QIcon m_dummyIcon;

View File

@@ -27,14 +27,15 @@
#include <QClipboard> #include <QClipboard>
#include <QGuiApplication> #include <QGuiApplication>
#include <QJSEngine> #include <QScriptEngine>
namespace Core { namespace Core {
namespace Internal { namespace Internal {
enum JavaScriptAction enum JavaScriptAction
{ {
ResetEngine = QVariant::UserType + 1 ResetEngine = QVariant::UserType + 1,
AbortEngine
}; };
JavaScriptFilter::JavaScriptFilter() JavaScriptFilter::JavaScriptFilter()
@@ -43,6 +44,13 @@ JavaScriptFilter::JavaScriptFilter()
setDisplayName(tr("Evaluate JavaScript")); setDisplayName(tr("Evaluate JavaScript"));
setIncludedByDefault(false); setIncludedByDefault(false);
setShortcutString("="); setShortcutString("=");
m_abortTimer.setSingleShot(true);
m_abortTimer.setInterval(1000);
connect(&m_abortTimer, &QTimer::timeout, this, [this] {
m_aborted = true;
if (m_engine && m_engine->isEvaluating())
m_engine->abortEvaluation();
});
} }
JavaScriptFilter::~JavaScriptFilter() JavaScriptFilter::~JavaScriptFilter()
@@ -55,6 +63,8 @@ void JavaScriptFilter::prepareSearch(const QString &entry)
if (!m_engine) if (!m_engine)
setupEngine(); setupEngine();
m_aborted = false;
m_abortTimer.start();
} }
QList<LocatorFilterEntry> JavaScriptFilter::matchesFor( QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
@@ -67,11 +77,15 @@ QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
entries.append({this, tr("Reset Engine"), QVariant(ResetEngine, nullptr)}); entries.append({this, tr("Reset Engine"), QVariant(ResetEngine, nullptr)});
} else { } else {
const QString result = m_engine->evaluate(entry).toString(); const QString result = m_engine->evaluate(entry).toString();
const QString expression = entry + " = " + result; if (m_aborted) {
const QString message = entry + " = " + tr("Engine aborted after timeout.");
entries.append({this, expression, QVariant()}); entries.append({this, message, QVariant(AbortEngine, nullptr)});
entries.append({this, tr("Copy to clipboard: %1").arg(result), result}); } else {
entries.append({this, tr("Copy to clipboard: %1").arg(expression), expression}); const QString expression = entry + " = " + result;
entries.append({this, expression, QVariant()});
entries.append({this, tr("Copy to clipboard: %1").arg(result), result});
entries.append({this, tr("Copy to clipboard: %1").arg(expression), expression});
}
} }
return entries; return entries;
@@ -104,7 +118,7 @@ void JavaScriptFilter::refresh(QFutureInterface<void> &future)
void JavaScriptFilter::setupEngine() void JavaScriptFilter::setupEngine()
{ {
m_engine.reset(new QJSEngine); m_engine.reset(new QScriptEngine);
m_engine->evaluate( m_engine->evaluate(
"function abs(x) { return Math.abs(x); }\n" "function abs(x) { return Math.abs(x); }\n"
"function acos(x) { return Math.acos(x); }\n" "function acos(x) { return Math.acos(x); }\n"

View File

@@ -27,10 +27,12 @@
#include <coreplugin/locator/ilocatorfilter.h> #include <coreplugin/locator/ilocatorfilter.h>
#include <QTimer>
#include <memory> #include <memory>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QJSEngine; class QScriptEngine;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Core { namespace Core {
@@ -53,7 +55,9 @@ public:
private: private:
void setupEngine(); void setupEngine();
mutable std::unique_ptr<QJSEngine> m_engine; mutable std::unique_ptr<QScriptEngine> m_engine;
QTimer m_abortTimer;
bool m_aborted = false;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -75,7 +75,9 @@ class LocatorData
public: public:
LocatorManager m_locatorManager; LocatorManager m_locatorManager;
#ifdef WITH_JAVASCRIPTFILTER
JavaScriptFilter m_javaScriptFilter; JavaScriptFilter m_javaScriptFilter;
#endif
OpenDocumentsFilter m_openDocumentsFilter; OpenDocumentsFilter m_openDocumentsFilter;
FileSystemFilter m_fileSystemFilter; FileSystemFilter m_fileSystemFilter;
ExecuteFilter m_executeFilter; ExecuteFilter m_executeFilter;
@@ -124,7 +126,6 @@ void Locator::initialize()
auto locatorWidget = LocatorManager::createLocatorInputWidget(ICore::mainWindow()); auto locatorWidget = LocatorManager::createLocatorInputWidget(ICore::mainWindow());
StatusBarManager::addStatusBarWidget(locatorWidget, StatusBarManager::First, StatusBarManager::addStatusBarWidget(locatorWidget, StatusBarManager::First,
Context("LocatorWidget")); Context("LocatorWidget"));
connect(ICore::instance(), &ICore::saveSettingsRequested, this, &Locator::saveSettings); connect(ICore::instance(), &ICore::saveSettingsRequested, this, &Locator::saveSettings);
} }

View File

@@ -15,8 +15,7 @@ HEADERS += \
$$PWD/executefilter.h \ $$PWD/executefilter.h \
$$PWD/locatorsearchutils.h \ $$PWD/locatorsearchutils.h \
$$PWD/locatorsettingspage.h \ $$PWD/locatorsettingspage.h \
$$PWD/externaltoolsfilter.h \ $$PWD/externaltoolsfilter.h
$$PWD/javascriptfilter.h
SOURCES += \ SOURCES += \
$$PWD/locator.cpp \ $$PWD/locator.cpp \
@@ -33,7 +32,18 @@ SOURCES += \
$$PWD/locatorsearchutils.cpp \ $$PWD/locatorsearchutils.cpp \
$$PWD/locatorsettingspage.cpp \ $$PWD/locatorsettingspage.cpp \
$$PWD/externaltoolsfilter.cpp \ $$PWD/externaltoolsfilter.cpp \
$$PWD/javascriptfilter.cpp
qtHaveModule(script) {
QT *= script
DEFINES += WITH_JAVASCRIPTFILTER
HEADERS += \
$$PWD/javascriptfilter.h
SOURCES += \
$$PWD/javascriptfilter.cpp
}
FORMS += \ FORMS += \
$$PWD/filesystemfilter.ui \ $$PWD/filesystemfilter.ui \

View File

@@ -411,6 +411,7 @@ void MainWindow::registerDefaultContainers()
filemenu->appendGroup(Constants::G_FILE_OPEN); filemenu->appendGroup(Constants::G_FILE_OPEN);
filemenu->appendGroup(Constants::G_FILE_PROJECT); filemenu->appendGroup(Constants::G_FILE_PROJECT);
filemenu->appendGroup(Constants::G_FILE_SAVE); filemenu->appendGroup(Constants::G_FILE_SAVE);
filemenu->appendGroup(Constants::G_FILE_EXPORT);
filemenu->appendGroup(Constants::G_FILE_CLOSE); filemenu->appendGroup(Constants::G_FILE_CLOSE);
filemenu->appendGroup(Constants::G_FILE_PRINT); filemenu->appendGroup(Constants::G_FILE_PRINT);
filemenu->appendGroup(Constants::G_FILE_OTHER); filemenu->appendGroup(Constants::G_FILE_OTHER);
@@ -465,6 +466,7 @@ void MainWindow::registerDefaultActions()
// File menu separators // File menu separators
mfile->addSeparator(Constants::G_FILE_SAVE); mfile->addSeparator(Constants::G_FILE_SAVE);
mfile->addSeparator(Constants::G_FILE_EXPORT);
mfile->addSeparator(Constants::G_FILE_PRINT); mfile->addSeparator(Constants::G_FILE_PRINT);
mfile->addSeparator(Constants::G_FILE_CLOSE); mfile->addSeparator(Constants::G_FILE_CLOSE);
mfile->addSeparator(Constants::G_FILE_OTHER); mfile->addSeparator(Constants::G_FILE_OTHER);
@@ -620,6 +622,30 @@ void MainWindow::registerDefaultActions()
medit->addAction(cmd, Constants::G_EDIT_OTHER); medit->addAction(cmd, Constants::G_EDIT_OTHER);
tmpaction->setEnabled(false); tmpaction->setEnabled(false);
// Zoom In Action
icon = QIcon::hasThemeIcon("zoom-in") ? QIcon::fromTheme("zoom-in")
: Utils::Icons::ZOOMIN_TOOLBAR.icon();
tmpaction = new QAction(icon, tr("Zoom In"), this);
cmd = ActionManager::registerAction(tmpaction, Constants::ZOOM_IN);
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl++")));
tmpaction->setEnabled(false);
// Zoom Out Action
icon = QIcon::hasThemeIcon("zoom-out") ? QIcon::fromTheme("zoom-out")
: Utils::Icons::ZOOMOUT_TOOLBAR.icon();
tmpaction = new QAction(icon, tr("Zoom Out"), this);
cmd = ActionManager::registerAction(tmpaction, Constants::ZOOM_OUT);
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+-")));
tmpaction->setEnabled(false);
// Zoom Reset Action
icon = QIcon::hasThemeIcon("zoom-original") ? QIcon::fromTheme("zoom-original")
: Utils::Icons::EYE_OPEN_TOOLBAR.icon();
tmpaction = new QAction(icon, tr("Original Size"), this);
cmd = ActionManager::registerAction(tmpaction, Constants::ZOOM_RESET);
cmd->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? tr("Meta+0") : tr("Ctrl+0")));
tmpaction->setEnabled(false);
// Options Action // Options Action
mtools->appendGroup(Constants::G_TOOLS_OPTIONS); mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
mtools->addSeparator(Constants::G_TOOLS_OPTIONS); mtools->addSeparator(Constants::G_TOOLS_OPTIONS);

View File

@@ -31,7 +31,6 @@
#include <utils/link.h> #include <utils/link.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/smallstring.h>
#include <clangsupport/sourcelocationscontainer.h> #include <clangsupport/sourcelocationscontainer.h>
#include <clangsupport/refactoringclientinterface.h> #include <clangsupport/refactoringclientinterface.h>

View File

@@ -438,7 +438,7 @@ void extractGdbVersion(const QString &msg,
const QChar dot(QLatin1Char('.')); const QChar dot(QLatin1Char('.'));
const bool ignoreParenthesisContent = msg.contains(QLatin1String("rubenvb")) const bool ignoreParenthesisContent = msg.contains(QLatin1String("rubenvb"))
|| msg.contains(QLatin1String("openSUSE")); || msg.contains(QLatin1String("SUSE"));
const QChar parOpen(QLatin1Char('(')); const QChar parOpen(QLatin1Char('('));
const QChar parClose(QLatin1Char(')')); const QChar parClose(QLatin1Char(')'));

View File

@@ -226,22 +226,22 @@ void GerritPushDialog::onRemoteChanged(bool force)
m_currentSupportsWip = supportsWip; m_currentSupportsWip = supportsWip;
m_ui->wipCheckBox->setEnabled(supportsWip); m_ui->wipCheckBox->setEnabled(supportsWip);
if (supportsWip) { if (supportsWip) {
m_ui->wipCheckBox->setToolTip(tr("Checked - Mark change as WIP\n" m_ui->wipCheckBox->setToolTip(tr("Checked - Mark change as WIP.\n"
"Unchecked - Mark change as ready\n" "Unchecked - Mark change as ready for review.\n"
"Partially checked - Do not change current state")); "Partially checked - Do not change current state."));
m_ui->draftCheckBox->setTristate(true); m_ui->draftCheckBox->setTristate(true);
if (m_ui->draftCheckBox->checkState() != Qt::Checked) if (m_ui->draftCheckBox->checkState() != Qt::Checked)
m_ui->draftCheckBox->setCheckState(Qt::PartiallyChecked); m_ui->draftCheckBox->setCheckState(Qt::PartiallyChecked);
m_ui->draftCheckBox->setToolTip(tr("Checked - Mark change as private\n" m_ui->draftCheckBox->setToolTip(tr("Checked - Mark change as private.\n"
"Unchecked - Unmark change as private\n" "Unchecked - Remove mark.\n"
"Partially checked - Do not change current state")); "Partially checked - Do not change current state."));
} else { } else {
m_ui->wipCheckBox->setToolTip(tr("Supported on Gerrit 2.15 and up")); m_ui->wipCheckBox->setToolTip(tr("Supported on Gerrit 2.15 and later."));
m_ui->draftCheckBox->setTristate(false); m_ui->draftCheckBox->setTristate(false);
if (m_ui->draftCheckBox->checkState() != Qt::Checked) if (m_ui->draftCheckBox->checkState() != Qt::Checked)
m_ui->draftCheckBox->setCheckState(Qt::Unchecked); m_ui->draftCheckBox->setCheckState(Qt::Unchecked);
m_ui->draftCheckBox->setToolTip(tr("Checked - Mark change as draft\n" m_ui->draftCheckBox->setToolTip(tr("Checked - The change is a draft.\n"
"Unchecked - Unmark change as draft")); "Unchecked - The change is not a draft."));
} }
} }

View File

@@ -82,14 +82,14 @@ Unchecked - Unmark change as private
Semi-checked - Do not change current state</string> Semi-checked - Do not change current state</string>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Draft/Private</string> <string>&amp;Draft/private</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="wipCheckBox"> <widget class="QCheckBox" name="wipCheckBox">
<property name="text"> <property name="text">
<string>&amp;Work-In-Progress</string> <string>&amp;Work-in-progress</string>
</property> </property>
<property name="tristate"> <property name="tristate">
<bool>true</bool> <bool>true</bool>

View File

@@ -33,10 +33,12 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <QAction>
#include <QMap> #include <QMap>
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>
@@ -107,14 +109,14 @@ void ImageViewer::ctor()
{QLatin1String(":/utils/images/desktopdevicesmall.png"), Utils::Theme::IconsBaseColor}}); {QLatin1String(":/utils/images/desktopdevicesmall.png"), Utils::Theme::IconsBaseColor}});
d->ui_toolbar.toolButtonBackground->setIcon(backgroundIcon.icon()); d->ui_toolbar.toolButtonBackground->setIcon(backgroundIcon.icon());
d->ui_toolbar.toolButtonOutline->setIcon(Utils::Icons::BOUNDING_RECT.icon()); d->ui_toolbar.toolButtonOutline->setIcon(Utils::Icons::BOUNDING_RECT.icon());
d->ui_toolbar.toolButtonZoomIn->setIcon(Utils::Icons::ZOOMIN_TOOLBAR.icon()); d->ui_toolbar.toolButtonZoomIn->setIcon(
d->ui_toolbar.toolButtonZoomOut->setIcon(Utils::Icons::ZOOMOUT_TOOLBAR.icon()); Core::ActionManager::command(Core::Constants::ZOOM_IN)->action()->icon());
d->ui_toolbar.toolButtonZoomOut->setIcon(
Core::ActionManager::command(Core::Constants::ZOOM_OUT)->action()->icon());
d->ui_toolbar.toolButtonOriginalSize->setIcon(
Core::ActionManager::command(Core::Constants::ZOOM_RESET)->action()->icon());
d->ui_toolbar.toolButtonFitToScreen->setIcon(Utils::Icons::FITTOVIEW_TOOLBAR.icon()); d->ui_toolbar.toolButtonFitToScreen->setIcon(Utils::Icons::FITTOVIEW_TOOLBAR.icon());
d->ui_toolbar.toolButtonOriginalSize->setIcon(Utils::Icons::EYE_OPEN_TOOLBAR.icon());
// icons update - try to use system theme // icons update - try to use system theme
updateButtonIconByTheme(d->ui_toolbar.toolButtonZoomIn, QLatin1String("zoom-in"));
updateButtonIconByTheme(d->ui_toolbar.toolButtonZoomOut, QLatin1String("zoom-out"));
updateButtonIconByTheme(d->ui_toolbar.toolButtonOriginalSize, QLatin1String("zoom-original"));
updateButtonIconByTheme(d->ui_toolbar.toolButtonFitToScreen, QLatin1String("zoom-fit-best")); updateButtonIconByTheme(d->ui_toolbar.toolButtonFitToScreen, QLatin1String("zoom-fit-best"));
// a display - something is on the background // a display - something is on the background
updateButtonIconByTheme(d->ui_toolbar.toolButtonBackground, QLatin1String("video-display")); updateButtonIconByTheme(d->ui_toolbar.toolButtonBackground, QLatin1String("video-display"));
@@ -123,9 +125,9 @@ void ImageViewer::ctor()
updateButtonIconByTheme(d->ui_toolbar.toolButtonOutline, QLatin1String("emblem-photos")); updateButtonIconByTheme(d->ui_toolbar.toolButtonOutline, QLatin1String("emblem-photos"));
d->ui_toolbar.toolButtonExportImage->setCommandId(Constants::ACTION_EXPORT_IMAGE); d->ui_toolbar.toolButtonExportImage->setCommandId(Constants::ACTION_EXPORT_IMAGE);
d->ui_toolbar.toolButtonZoomIn->setCommandId(Constants::ACTION_ZOOM_IN); d->ui_toolbar.toolButtonZoomIn->setCommandId(Core::Constants::ZOOM_IN);
d->ui_toolbar.toolButtonZoomOut->setCommandId(Constants::ACTION_ZOOM_OUT); d->ui_toolbar.toolButtonZoomOut->setCommandId(Core::Constants::ZOOM_OUT);
d->ui_toolbar.toolButtonOriginalSize->setCommandId(Constants::ACTION_ORIGINAL_SIZE); d->ui_toolbar.toolButtonOriginalSize->setCommandId(Core::Constants::ZOOM_RESET);
d->ui_toolbar.toolButtonFitToScreen->setCommandId(Constants::ACTION_FIT_TO_SCREEN); d->ui_toolbar.toolButtonFitToScreen->setCommandId(Constants::ACTION_FIT_TO_SCREEN);
d->ui_toolbar.toolButtonBackground->setCommandId(Constants::ACTION_BACKGROUND); d->ui_toolbar.toolButtonBackground->setCommandId(Constants::ACTION_BACKGROUND);
d->ui_toolbar.toolButtonOutline->setCommandId(Constants::ACTION_OUTLINE); d->ui_toolbar.toolButtonOutline->setCommandId(Constants::ACTION_OUTLINE);

View File

@@ -33,9 +33,6 @@ const char IMAGEVIEWER_ID[] = "Editors.ImageViewer";
const char IMAGEVIEWER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "Image Viewer"); const char IMAGEVIEWER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "Image Viewer");
const char ACTION_EXPORT_IMAGE[] = "ImageViewer.ExportImage"; const char ACTION_EXPORT_IMAGE[] = "ImageViewer.ExportImage";
const char ACTION_ZOOM_IN[] = "ImageViewer.ZoomIn";
const char ACTION_ZOOM_OUT[] = "ImageViewer.ZoomOut";
const char ACTION_ORIGINAL_SIZE[] = "ImageViewer.OriginalSize";
const char ACTION_FIT_TO_SCREEN[] = "ImageViewer.FitToScreen"; const char ACTION_FIT_TO_SCREEN[] = "ImageViewer.FitToScreen";
const char ACTION_BACKGROUND[] = "ImageViewer.Background"; const char ACTION_BACKGROUND[] = "ImageViewer.Background";
const char ACTION_OUTLINE[] = "ImageViewer.Outline"; const char ACTION_OUTLINE[] = "ImageViewer.Outline";

View File

@@ -36,6 +36,7 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/id.h> #include <coreplugin/id.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
@@ -62,22 +63,19 @@ static inline ImageViewer *currentImageViewer()
void ImageViewerPlugin::extensionsInitialized() void ImageViewerPlugin::extensionsInitialized()
{ {
QAction *a = registerNewAction(Constants::ACTION_ZOOM_IN, tr("Zoom In"), QAction *a = registerNewAction(Core::Constants::ZOOM_IN);
QKeySequence(tr("Ctrl++")));
connect(a, &QAction::triggered, this, []() { connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer()) if (ImageViewer *iv = currentImageViewer())
iv->zoomIn(); iv->zoomIn();
}); });
a = registerNewAction(Constants::ACTION_ZOOM_OUT, tr("Zoom Out"), a = registerNewAction(Core::Constants::ZOOM_OUT);
QKeySequence(tr("Ctrl+-")));
connect(a, &QAction::triggered, this, []() { connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer()) if (ImageViewer *iv = currentImageViewer())
iv->zoomOut(); iv->zoomOut();
}); });
a = registerNewAction(Constants::ACTION_ORIGINAL_SIZE, tr("Original Size"), a = registerNewAction(Core::Constants::ZOOM_RESET);
QKeySequence(Core::useMacShortcuts ? tr("Meta+0") : tr("Ctrl+0")));
connect(a, &QAction::triggered, this, []() { connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer()) if (ImageViewer *iv = currentImageViewer())
iv->resetToOriginalSize(); iv->resetToOriginalSize();
@@ -125,7 +123,8 @@ QAction *ImageViewerPlugin::registerNewAction(Core::Id id,
Core::Context context(Constants::IMAGEVIEWER_ID); Core::Context context(Constants::IMAGEVIEWER_ID);
QAction *action = new QAction(title, this); QAction *action = new QAction(title, this);
Core::Command *command = Core::ActionManager::registerAction(action, id, context); Core::Command *command = Core::ActionManager::registerAction(action, id, context);
command->setDefaultKeySequence(key); if (!key.isEmpty())
command->setDefaultKeySequence(key);
return action; return action;
} }

View File

@@ -28,12 +28,12 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
#include <QKeySequence>
#include <QPointer> #include <QPointer>
#include <QtPlugin> #include <QtPlugin>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QAction; class QAction;
class QKeySequence;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Core { class Id; } namespace Core { class Id; }
@@ -55,7 +55,8 @@ public:
void extensionsInitialized(); void extensionsInitialized();
private: private:
QAction *registerNewAction(Core::Id id, const QString &title, const QKeySequence &key); QAction *registerNewAction(Core::Id id, const QString &title = QString(),
const QKeySequence &key = QKeySequence());
QPointer<ImageViewerFactory> m_factory; QPointer<ImageViewerFactory> m_factory;
}; };

View File

@@ -58,9 +58,6 @@ public:
QAction *synchronizeBrowserAction = nullptr; QAction *synchronizeBrowserAction = nullptr;
QAction *exportDiagramAction = nullptr; QAction *exportDiagramAction = nullptr;
QAction *exportSelectedElementsAction = nullptr; QAction *exportSelectedElementsAction = nullptr;
QAction *zoomInAction = nullptr;
QAction *zoomOutAction = nullptr;
QAction *resetZoomAction = nullptr;
}; };
ActionHandler::ActionHandler(const Core::Context &context, QObject *parent) ActionHandler::ActionHandler(const Core::Context &context, QObject *parent)
@@ -135,92 +132,63 @@ QAction *ActionHandler::exportSelectedElementsAction() const
return d->exportSelectedElementsAction; return d->exportSelectedElementsAction;
} }
QAction *ActionHandler::zoomInAction() const
{
return d->zoomInAction;
}
QAction *ActionHandler::zoomOutAction() const
{
return d->zoomOutAction;
}
QAction *ActionHandler::resetZoom() const
{
return d->resetZoomAction;
}
void ActionHandler::createActions() void ActionHandler::createActions()
{ {
Core::ActionContainer *medit = Core::ActionManager::actionContainer(Core::Constants::M_EDIT); Core::ActionContainer *medit = Core::ActionManager::actionContainer(Core::Constants::M_EDIT);
Core::ActionContainer *mfile = Core::ActionManager::actionContainer(Core::Constants::M_FILE);
d->undoAction = registerCommand(Core::Constants::UNDO, [this]() { undo(); }, d->context)->action(); d->undoAction = registerCommand(Core::Constants::UNDO, &ModelEditor::undo, d->context)->action();
d->redoAction = registerCommand(Core::Constants::REDO, [this]() { redo(); }, d->context)->action(); d->redoAction = registerCommand(Core::Constants::REDO, &ModelEditor::redo, d->context)->action();
d->cutAction = registerCommand(Core::Constants::CUT, [this]() { cut(); }, d->context)->action(); d->cutAction = registerCommand(Core::Constants::CUT, &ModelEditor::cut, d->context)->action();
d->copyAction = registerCommand(Core::Constants::COPY, [this]() { copy(); }, d->context)->action(); d->copyAction = registerCommand(Core::Constants::COPY, &ModelEditor::copy, d->context)->action();
d->pasteAction = registerCommand(Core::Constants::PASTE, [this]() { paste(); }, d->context)->action(); d->pasteAction = registerCommand(Core::Constants::PASTE, &ModelEditor::paste, d->context)->action();
Core::Command *removeCommand = registerCommand( Core::Command *removeCommand = registerCommand(
Constants::REMOVE_SELECTED_ELEMENTS, [this]() { removeSelectedElements(); }, d->context, true, Constants::REMOVE_SELECTED_ELEMENTS, &ModelEditor::removeSelectedElements, d->context,
tr("&Remove"), QKeySequence::Delete); tr("&Remove"), QKeySequence::Delete);
medit->addAction(removeCommand, Core::Constants::G_EDIT_COPYPASTE); medit->addAction(removeCommand, Core::Constants::G_EDIT_COPYPASTE);
d->removeAction = removeCommand->action(); d->removeAction = removeCommand->action();
Core::Command *deleteCommand = registerCommand( Core::Command *deleteCommand = registerCommand(
Constants::DELETE_SELECTED_ELEMENTS, [this]() { deleteSelectedElements(); }, d->context, true, Constants::DELETE_SELECTED_ELEMENTS, &ModelEditor::deleteSelectedElements, d->context,
tr("&Delete"), QKeySequence("Ctrl+D")); tr("&Delete"), QKeySequence("Ctrl+D"));
medit->addAction(deleteCommand, Core::Constants::G_EDIT_COPYPASTE); medit->addAction(deleteCommand, Core::Constants::G_EDIT_COPYPASTE);
d->deleteAction = deleteCommand->action(); d->deleteAction = deleteCommand->action();
d->selectAllAction = registerCommand(Core::Constants::SELECTALL, [this]() { selectAll(); }, d->context)->action(); d->selectAllAction = registerCommand(Core::Constants::SELECTALL, &ModelEditor::selectAll, d->context)->action();
Core::ActionContainer *menuModelEditor = Core::ActionManager::createMenu(Constants::MENU_ID);
menuModelEditor->menu()->setTitle(tr("Model Editor"));
Core::ActionContainer *menuTools = Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);
menuTools->addMenu(menuModelEditor);
Core::Command *exportDiagramCommand = registerCommand( Core::Command *exportDiagramCommand = registerCommand(
Constants::EXPORT_DIAGRAM, [this]() { exportDiagram(); }, d->context, true, Constants::EXPORT_DIAGRAM, &ModelEditor::exportDiagram, d->context,
tr("Export Diagram...")); tr("Export Diagram..."));
menuModelEditor->addAction(exportDiagramCommand); exportDiagramCommand->setAttribute(Core::Command::CA_Hide);
mfile->addAction(exportDiagramCommand, Core::Constants::G_FILE_EXPORT);
d->exportDiagramAction = exportDiagramCommand->action(); d->exportDiagramAction = exportDiagramCommand->action();
Core::Command *exportSelectedElementsCommand = registerCommand( Core::Command *exportSelectedElementsCommand = registerCommand(
Constants::EXPORT_SELECTED_ELEMENTS, [this]() { exportSelectedElements(); }, d->context, true, Constants::EXPORT_SELECTED_ELEMENTS, &ModelEditor::exportSelectedElements, d->context,
tr("Export Selected Elements...")); tr("Export Selected Elements..."));
menuModelEditor->addAction(exportSelectedElementsCommand); exportSelectedElementsCommand->setAttribute(Core::Command::CA_Hide);
mfile->addAction(exportSelectedElementsCommand, Core::Constants::G_FILE_EXPORT);
d->exportSelectedElementsAction = exportSelectedElementsCommand->action(); d->exportSelectedElementsAction = exportSelectedElementsCommand->action();
menuModelEditor->addSeparator(d->context); registerCommand(Core::Constants::ZOOM_IN, &ModelEditor::zoomIn, d->context);
registerCommand(Core::Constants::ZOOM_OUT, &ModelEditor::zoomOut, d->context);
Core::Command *zoomInCommand = registerCommand( registerCommand(Core::Constants::ZOOM_RESET, &ModelEditor::resetZoom, d->context);
Constants::ZOOM_IN, [this]() { zoomIn(); }, d->context, true,
tr("Zoom In"), QKeySequence("Ctrl++"));
menuModelEditor->addAction(zoomInCommand);
d->zoomInAction = zoomInCommand->action();
Core::Command *zoomOutCommand = registerCommand(
Constants::ZOOM_OUT, [this]() { zoomOut(); }, d->context, true,
tr("Zoom Out"), QKeySequence("Ctrl+-"));
menuModelEditor->addAction(zoomOutCommand);
d->zoomOutAction = zoomOutCommand->action();
Core::Command *resetZoomCommand = registerCommand(
Constants::RESET_ZOOM, [this]() { resetZoom(); }, d->context, true,
tr("Reset Zoom"), QKeySequence("Ctrl+0"));
menuModelEditor->addAction(resetZoomCommand);
d->zoomOutAction = resetZoomCommand->action();
d->openParentDiagramAction = registerCommand( d->openParentDiagramAction = registerCommand(
Constants::OPEN_PARENT_DIAGRAM, [this]() { openParentDiagram(); }, Core::Context(), true, Constants::OPEN_PARENT_DIAGRAM, &ModelEditor::openParentDiagram, Core::Context(),
tr("Open Parent Diagram"), QKeySequence("Ctrl+Shift+P"))->action(); tr("Open Parent Diagram"), QKeySequence("Ctrl+Shift+P"),
d->openParentDiagramAction->setIcon(QIcon(":/modeleditor/up.png")); QIcon(":/modeleditor/up.png"))->action();
registerCommand(Constants::ACTION_ADD_PACKAGE, nullptr, Core::Context(), true, tr("Add Package")); registerCommand(Constants::ACTION_ADD_PACKAGE, nullptr, Core::Context(), tr("Add Package"),
registerCommand(Constants::ACTION_ADD_COMPONENT, nullptr, Core::Context(), true, tr("Add Component")); QKeySequence(), QIcon(":/modelinglib/48x48/package.png"));
registerCommand(Constants::ACTION_ADD_CLASS, nullptr, Core::Context(), true, tr("Add Class")); registerCommand(Constants::ACTION_ADD_COMPONENT, nullptr, Core::Context(), tr("Add Component"),
registerCommand(Constants::ACTION_ADD_CANVAS_DIAGRAM, nullptr, Core::Context(), true, tr("Add Canvas Diagram")); QKeySequence(), QIcon(":/modelinglib/48x48/component.png"));
registerCommand(Constants::ACTION_ADD_CLASS, nullptr, Core::Context(), tr("Add Class"),
QKeySequence(), QIcon(":/modelinglib/48x48/class.png"));
registerCommand(Constants::ACTION_ADD_CANVAS_DIAGRAM, nullptr, Core::Context(), tr("Add Canvas Diagram"),
QKeySequence(), QIcon(":/modelinglib/48x48/canvas-diagram.png"));
d->synchronizeBrowserAction = registerCommand( d->synchronizeBrowserAction = registerCommand(
Constants::ACTION_SYNC_BROWSER, nullptr, Core::Context(), true, Constants::ACTION_SYNC_BROWSER, nullptr, Core::Context(),
tr("Synchronize Browser and Diagram") + "<br><i><small>" tr("Synchronize Browser and Diagram") + "<br><i><small>"
+ tr("Press && Hold for options") + "</small></i>")->action(); + tr("Press && Hold for options") + "</small></i>", QKeySequence(),
d->synchronizeBrowserAction->setIcon(Utils::Icons::LINK.icon()); Utils::Icons::LINK.icon())->action();
d->synchronizeBrowserAction->setCheckable(true); d->synchronizeBrowserAction->setCheckable(true);
auto editPropertiesAction = new QAction(tr("Edit Element Properties"), Core::ICore::mainWindow()); auto editPropertiesAction = new QAction(tr("Edit Element Properties"), Core::ICore::mainWindow());
@@ -236,69 +204,6 @@ void ActionHandler::createActions()
connect(editItemAction, &QAction::triggered, this, &ActionHandler::onEditItem); connect(editItemAction, &QAction::triggered, this, &ActionHandler::onEditItem);
} }
void ActionHandler::undo()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->undo();
}
void ActionHandler::redo()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->redo();
}
void ActionHandler::cut()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->cut();
}
void ActionHandler::copy()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->copy();
}
void ActionHandler::paste()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->paste();
}
void ActionHandler::removeSelectedElements()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->removeSelectedElements();
}
void ActionHandler::deleteSelectedElements()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->deleteSelectedElements();
}
void ActionHandler::selectAll()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->selectAll();
}
void ActionHandler::openParentDiagram()
{
auto editor = dynamic_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->openParentDiagram();
}
void ActionHandler::onEditProperties() void ActionHandler::onEditProperties()
{ {
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor()); auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
@@ -313,51 +218,27 @@ void ActionHandler::onEditItem()
editor->editSelectedItem(); editor->editSelectedItem();
} }
void ActionHandler::exportDiagram() std::function<void()> invokeOnCurrentModelEditor(void (ModelEditor::*function)())
{ {
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor()); return [function] {
if (editor) auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
editor->exportDiagram(false); if (editor)
(editor->*function)();
};
} }
void ActionHandler::exportSelectedElements() Core::Command *ActionHandler::registerCommand(const Core::Id &id, void (ModelEditor::*function)(),
{ const Core::Context &context, const QString &title,
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor()); const QKeySequence &keySequence, const QIcon &icon)
if (editor)
editor->exportDiagram(true);
}
void ActionHandler::zoomIn()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->zoomIn();
}
void ActionHandler::zoomOut()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->zoomOut();
}
void ActionHandler::resetZoom()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->resetZoom();
}
Core::Command *ActionHandler::registerCommand(const Core::Id &id, const std::function<void()> &slot,
const Core::Context &context, bool scriptable, const QString &title,
const QKeySequence &keySequence)
{ {
auto action = new QAction(title, this); auto action = new QAction(title, this);
Core::Command *command = Core::ActionManager::registerAction(action, id, context, scriptable); if (!icon.isNull())
action->setIcon(icon);
Core::Command *command = Core::ActionManager::registerAction(action, id, context, /*scriptable=*/true);
if (!keySequence.isEmpty()) if (!keySequence.isEmpty())
command->setDefaultKeySequence(keySequence); command->setDefaultKeySequence(keySequence);
if (slot) if (function)
connect(action, &QAction::triggered, this, slot); connect(action, &QAction::triggered, this, invokeOnCurrentModelEditor(function));
return command; return command;
} }

View File

@@ -25,10 +25,11 @@
#pragma once #pragma once
#include <QObject>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <QIcon>
#include <QObject>
#include <functional> #include <functional>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -43,6 +44,8 @@ class Command;
namespace ModelEditor { namespace ModelEditor {
namespace Internal { namespace Internal {
class ModelEditor;
class ActionHandler : class ActionHandler :
public QObject public QObject
{ {
@@ -73,27 +76,13 @@ public:
void createActions(); void createActions();
private: private:
void undo();
void redo();
void cut();
void copy();
void paste();
void removeSelectedElements();
void deleteSelectedElements();
void selectAll();
void openParentDiagram();
void onEditProperties(); void onEditProperties();
void onEditItem(); void onEditItem();
void exportDiagram();
void exportSelectedElements();
void zoomIn();
void zoomOut();
void resetZoom();
Core::Command *registerCommand(const Core::Id &id, const std::function<void()> &slot, Core::Command *registerCommand(const Core::Id &id, void (ModelEditor::*function)(),
const Core::Context &context, const Core::Context &context, const QString &title = QString(),
bool scriptable = true, const QString &title = QString(), const QKeySequence &keySequence = QKeySequence(),
const QKeySequence &keySequence = QKeySequence()); const QIcon &icon = QIcon());
private: private:
ActionHandlerPrivate *d; ActionHandlerPrivate *d;

View File

@@ -69,6 +69,8 @@
#include "qmt/tasks/diagramscenecontroller.h" #include "qmt/tasks/diagramscenecontroller.h"
#include "qmt/tasks/finddiagramvisitor.h" #include "qmt/tasks/finddiagramvisitor.h"
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/minisplitter.h> #include <coreplugin/minisplitter.h>
@@ -323,22 +325,27 @@ void ModelEditor::init(QWidget *parent)
toolbarLayout->addWidget(d->diagramSelector, 1); toolbarLayout->addWidget(d->diagramSelector, 1);
toolbarLayout->addStretch(1); toolbarLayout->addStretch(1);
toolbarLayout->addWidget( toolbarLayout->addWidget(createToolbarCommandButton(Core::Constants::ZOOM_RESET,
createToolbarCommandButton(Constants::ACTION_ADD_PACKAGE, [this]() { onAddPackage(); }, [this]() { resetZoom(); },
QIcon(":/modelinglib/48x48/package.png"), d->toolbar));
tr("Add Package"), d->toolbar)); toolbarLayout->addWidget(createToolbarCommandButton(Core::Constants::ZOOM_IN,
toolbarLayout->addWidget( [this]() { zoomIn(); },
createToolbarCommandButton(Constants::ACTION_ADD_COMPONENT, [this]() { onAddComponent(); }, d->toolbar));
QIcon(":/modelinglib/48x48/component.png"), toolbarLayout->addWidget(createToolbarCommandButton(Core::Constants::ZOOM_OUT,
tr("Add Component"), d->toolbar)); [this]() { zoomOut(); },
toolbarLayout->addWidget( d->toolbar));
createToolbarCommandButton(Constants::ACTION_ADD_CLASS, [this]() { onAddClass(); }, toolbarLayout->addWidget(createToolbarCommandButton(Constants::ACTION_ADD_PACKAGE,
QIcon(":/modelinglib/48x48/class.png"), [this]() { onAddPackage(); },
tr("Add Class"), d->toolbar)); d->toolbar));
toolbarLayout->addWidget( toolbarLayout->addWidget(createToolbarCommandButton(Constants::ACTION_ADD_COMPONENT,
createToolbarCommandButton(Constants::ACTION_ADD_CANVAS_DIAGRAM, [this]() { onAddCanvasDiagram(); }, [this]() { onAddComponent(); },
QIcon(":/modelinglib/48x48/canvas-diagram.png"), d->toolbar));
tr("Add Canvas Diagram"), d->toolbar)); toolbarLayout->addWidget(createToolbarCommandButton(Constants::ACTION_ADD_CLASS,
[this]() { onAddClass(); },
d->toolbar));
toolbarLayout->addWidget(createToolbarCommandButton(Constants::ACTION_ADD_CANVAS_DIAGRAM,
[this]() { onAddCanvasDiagram(); },
d->toolbar));
toolbarLayout->addSpacing(20); toolbarLayout->addSpacing(20);
auto syncToggleButton = new Core::CommandButton(Constants::ACTION_SYNC_BROWSER, d->toolbar); auto syncToggleButton = new Core::CommandButton(Constants::ACTION_SYNC_BROWSER, d->toolbar);
@@ -569,7 +576,17 @@ void ModelEditor::editSelectedItem()
onEditSelectedElement(); onEditSelectedElement();
} }
void ModelEditor::exportDiagram(bool selectedElements) void ModelEditor::exportDiagram()
{
exportToImage(/*selectedElements=*/false);
}
void ModelEditor::exportSelectedElements()
{
exportToImage(/*selectedElements=*/true);
}
void ModelEditor::exportToImage(bool selectedElements)
{ {
qmt::MDiagram *diagram = currentDiagram(); qmt::MDiagram *diagram = currentDiagram();
if (diagram) { if (diagram) {
@@ -797,18 +814,18 @@ void ModelEditor::expandModelTreeToDepth(int depth)
d->modelTreeView->expandToDepth(depth); d->modelTreeView->expandToDepth(depth);
} }
QToolButton *ModelEditor::createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot, QToolButton *ModelEditor::createToolbarCommandButton(const Core::Id &id,
const QIcon &icon, const QString &toolTipBase, const std::function<void()> &slot,
QWidget *parent) QWidget *parent)
{ {
auto button = new Core::CommandButton(id, parent); Core::Command *command = Core::ActionManager::command(id);
auto action = new QAction(button); QTC_CHECK(command);
action->setIcon(icon); const QString text = command ? command->description() : QString();
action->setToolTip(toolTipBase); auto action = new QAction(text, this);
button->setDefaultAction(action); action->setIcon(command ? command->action()->icon() : QIcon());
//button->setIcon(icon); auto button = Core::Command::toolButtonWithAppendedShortcut(action, command);
//button->setToolTipBase(toolTipBase); button->setParent(parent);
connect(button, &Core::CommandButton::clicked, this, slot); connect(button, &QToolButton::clicked, this, slot);
return button; return button;
} }

View File

@@ -87,7 +87,8 @@ public:
void openParentDiagram(); void openParentDiagram();
void editProperties(); void editProperties();
void editSelectedItem(); void editSelectedItem();
void exportDiagram(bool selectedElements); void exportDiagram();
void exportSelectedElements();
void zoomIn(); void zoomIn();
void zoomOut(); void zoomOut();
void resetZoom(); void resetZoom();
@@ -103,9 +104,9 @@ private:
void showProperties(qmt::MDiagram *diagram, const QList<qmt::DElement *> &diagramElements); void showProperties(qmt::MDiagram *diagram, const QList<qmt::DElement *> &diagramElements);
void clearProperties(); void clearProperties();
void expandModelTreeToDepth(int depth); void expandModelTreeToDepth(int depth);
QToolButton *createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot, QToolButton *createToolbarCommandButton(const Core::Id &id,
const QIcon &icon, const std::function<void()> &slot,
const QString &toolTipBase, QWidget *parent); QWidget *parent);
bool updateButtonIconByTheme(QAbstractButton *button, const QString &name); bool updateButtonIconByTheme(QAbstractButton *button, const QString &name);
void showZoomIndicator(); void showZoomIndicator();
@@ -158,6 +159,8 @@ private:
void synchronizeDiagramWithBrowser(); void synchronizeDiagramWithBrowser();
void synchronizeBrowserWithDiagram(const qmt::MDiagram *diagram); void synchronizeBrowserWithDiagram(const qmt::MDiagram *diagram);
void exportToImage(bool selectedElements);
private: private:
ModelEditorPrivate *d; ModelEditorPrivate *d;
}; };

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include <QtGlobal>
namespace ModelEditor { namespace ModelEditor {
namespace Constants { namespace Constants {
@@ -37,9 +39,6 @@ const char OPEN_PARENT_DIAGRAM[] = "ModelEditor.OpenParentDiagram";
const char MENU_ID[] = "ModelEditor.Menu"; const char MENU_ID[] = "ModelEditor.Menu";
const char EXPORT_DIAGRAM[] = "ModelEditor.ExportDiagram"; const char EXPORT_DIAGRAM[] = "ModelEditor.ExportDiagram";
const char EXPORT_SELECTED_ELEMENTS[] = "ModelEditor.ExportSelectedElements"; const char EXPORT_SELECTED_ELEMENTS[] = "ModelEditor.ExportSelectedElements";
const char ZOOM_IN[] = "ModelEditor.ZoomIn";
const char ZOOM_OUT[] = "ModelEditor.ZoomOut";
const char RESET_ZOOM[] = "ModelEditor.ResetZoom";
const char ACTION_ADD_PACKAGE[] = "ModelEditor.Action.AddPackage"; const char ACTION_ADD_PACKAGE[] = "ModelEditor.Action.AddPackage";
const char ACTION_ADD_COMPONENT[] = "ModelEditor.Action.AddComponent"; const char ACTION_ADD_COMPONENT[] = "ModelEditor.Action.AddComponent";
const char ACTION_ADD_CLASS[] = "ModelEditor.Action.AddClass"; const char ACTION_ADD_CLASS[] = "ModelEditor.Action.AddClass";

View File

@@ -54,40 +54,6 @@ namespace Internal {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Resolve QueryFullProcessImageNameW out of kernel32.dll due
// to incomplete MinGW import libs and it not being present
// on Windows XP.
static BOOL queryFullProcessImageName(HANDLE h, DWORD flags, LPWSTR buffer, DWORD *size)
{
// Resolve required symbols from the kernel32.dll
typedef BOOL (WINAPI *QueryFullProcessImageNameWProtoType)
(HANDLE, DWORD, LPWSTR, PDWORD);
static QueryFullProcessImageNameWProtoType queryFullProcessImageNameW = 0;
if (!queryFullProcessImageNameW) {
QLibrary kernel32Lib(QLatin1String("kernel32.dll"), 0);
if (kernel32Lib.isLoaded() || kernel32Lib.load())
queryFullProcessImageNameW = (QueryFullProcessImageNameWProtoType)kernel32Lib.resolve("QueryFullProcessImageNameW");
}
if (!queryFullProcessImageNameW)
return FALSE;
// Read out process
return (*queryFullProcessImageNameW)(h, flags, buffer, size);
}
static QString imageName(DWORD processId)
{
QString rc;
HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION , FALSE, processId);
if (handle == INVALID_HANDLE_VALUE)
return rc;
WCHAR buffer[MAX_PATH];
DWORD bufSize = MAX_PATH;
if (queryFullProcessImageName(handle, 0, buffer, &bufSize))
rc = QString::fromUtf16(reinterpret_cast<const ushort*>(buffer));
CloseHandle(handle);
return rc;
}
LocalProcessList::LocalProcessList(const IDevice::ConstPtr &device, QObject *parent) LocalProcessList::LocalProcessList(const IDevice::ConstPtr &device, QObject *parent)
: DeviceProcessList(device, parent) : DeviceProcessList(device, parent)
, m_myPid(GetCurrentProcessId()) , m_myPid(GetCurrentProcessId())
@@ -108,7 +74,7 @@ QList<DeviceProcessItem> LocalProcessList::getLocalProcesses()
DeviceProcessItem p; DeviceProcessItem p;
p.pid = pe.th32ProcessID; p.pid = pe.th32ProcessID;
// Image has the absolute path, but can fail. // Image has the absolute path, but can fail.
const QString image = imageName(pe.th32ProcessID); const QString image = Utils::imageName(pe.th32ProcessID);
p.exe = p.cmdLine = image.isEmpty() ? p.exe = p.cmdLine = image.isEmpty() ?
QString::fromWCharArray(pe.szExeFile) : QString::fromWCharArray(pe.szExeFile) :
image; image;

View File

@@ -1,8 +1,10 @@
import qbs 1.0 import qbs 1.0
import qbs.File
import qbs.FileInfo import qbs.FileInfo
QtcPlugin { QtcPlugin {
name: "QbsProjectManager" name: "QbsProjectManager"
type: base.concat(["qmltype-update"])
property var externalQbsIncludes: project.useExternalQbs property var externalQbsIncludes: project.useExternalQbs
? [project.qbs_install_dir + "/include/qbs"] : [] ? [project.qbs_install_dir + "/include/qbs"] : []
@@ -116,5 +118,42 @@ QtcPlugin {
"qbsrunconfiguration.cpp", "qbsrunconfiguration.cpp",
"qbsrunconfiguration.h", "qbsrunconfiguration.h",
] ]
// QML typeinfo stuff
property bool updateQmlTypeInfo: useInternalQbsProducts
Group {
condition: !updateQmlTypeInfo
name: "qbs qml type info"
qbs.install: true
qbs.installDir: FileInfo.joinPaths(qtc.ide_data_path, "qtcreator",
"qml-type-descriptions")
prefix: FileInfo.joinPaths(project.ide_source_tree, "share", "qtcreator",
"qml-type-descriptions") + '/'
files: [
"qbs-bundle.json",
"qbs.qmltypes",
]
}
Depends { name: "qbs resources" }
Rule {
condition: updateQmlTypeInfo
inputsFromDependencies: ["qbs qml type descriptions", "qbs qml type bundle"]
Artifact {
filePath: "dummy." + input.fileName
fileTags: ["qmltype-update"]
}
prepare: {
var cmd = new JavaScriptCommand();
cmd.description = "Updating " + input.fileName + " in Qt Creator repository";
cmd.sourceCode = function() {
var targetFilePath = FileInfo.joinPaths(project.ide_source_tree, "share",
"qtcreator", "qml-type-descriptions",
input.fileName);
File.copy(input.filePath, targetFilePath);
}
return cmd;
}
}
} }

View File

@@ -51,7 +51,11 @@ static const char ANDROID_RC_ID_PREFIX[] = "Qt4ProjectManager.AndroidRunConfigur
QmakeAndroidRunConfiguration::QmakeAndroidRunConfiguration(Target *target) QmakeAndroidRunConfiguration::QmakeAndroidRunConfiguration(Target *target)
: AndroidRunConfiguration(target, ANDROID_RC_ID_PREFIX) : AndroidRunConfiguration(target, ANDROID_RC_ID_PREFIX)
{} {
connect(target->project(), &Project::parsingFinished, this, [this]() {
updateDisplayName();
});
}
QString QmakeAndroidRunConfiguration::extraId() const QString QmakeAndroidRunConfiguration::extraId() const
{ {
@@ -72,7 +76,6 @@ bool QmakeAndroidRunConfiguration::fromMap(const QVariantMap &map)
if (!extraId.isEmpty()) if (!extraId.isEmpty())
m_proFilePath = Utils::FileName::fromString(extraId); m_proFilePath = Utils::FileName::fromString(extraId);
setDefaultDisplayName(defaultDisplayName());
return true; return true;
} }
@@ -86,17 +89,15 @@ QVariantMap QmakeAndroidRunConfiguration::toMap() const
return map; return map;
} }
QString QmakeAndroidRunConfiguration::defaultDisplayName() void QmakeAndroidRunConfiguration::updateDisplayName()
{ {
QmakeProject *project = qmakeProject(); QmakeProject *project = qmakeProject();
const QmakeProjectManager::QmakeProFileNode *root = project->rootProjectNode(); const QmakeProjectManager::QmakeProFileNode *root = project->rootProjectNode();
if (root) { if (root) {
const QmakeProjectManager::QmakeProFileNode *node = root->findProFileFor(m_proFilePath); const QmakeProjectManager::QmakeProFileNode *node = root->findProFileFor(m_proFilePath);
if (node) // should always be found if (node) // should always be found
return node->displayName(); setDefaultDisplayName(node->displayName());
} }
return QString();
} }
QString QmakeAndroidRunConfiguration::disabledReason() const QString QmakeAndroidRunConfiguration::disabledReason() const

View File

@@ -49,7 +49,7 @@ private:
QString extraId() const final; QString extraId() const final;
bool fromMap(const QVariantMap &map) override; bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override; QVariantMap toMap() const override;
QString defaultDisplayName(); void updateDisplayName();
QmakeProjectManager::QmakeProject *qmakeProject() const; QmakeProjectManager::QmakeProject *qmakeProject() const;

View File

@@ -416,7 +416,7 @@ void ItemLibraryWidget::addResources()
if (!fileNames.isEmpty()) { if (!fileNames.isEmpty()) {
const auto directory = QFileDialog::getExistingDirectory(this, const auto directory = QFileDialog::getExistingDirectory(this,
tr("Target Direcotry"), tr("Target Directory"),
document->fileName().parentDir().toString()); document->fileName().parentDir().toString());
for (const QString &fileName : fileNames) { for (const QString &fileName : fileNames) {
@@ -425,7 +425,7 @@ void ItemLibraryWidget::addResources()
postfix.remove(0, 1); postfix.remove(0, 1);
if (fileName.endsWith(postfix)) if (fileName.endsWith(postfix))
if (!handler.operation(fileName, directory)) if (!handler.operation(fileName, directory))
Core::AsynchronousMessageBox::warning(tr("Failed to add File"), tr("Could not add %1 to project.").arg(fileName)); Core::AsynchronousMessageBox::warning(tr("Failed to Add File"), tr("Could not add %1 to project.").arg(fileName));
} }
} }
} }

View File

@@ -25,19 +25,23 @@
#include "navigatorwidget.h" #include "navigatorwidget.h"
#include "navigatorview.h" #include "navigatorview.h"
#include "qmldesignerconstants.h"
#include "qmldesignericons.h"
#include <designersettings.h> #include <designersettings.h>
#include <qmldesignerconstants.h>
#include <qmldesignericons.h>
#include <qmldesignerplugin.h>
#include <theme.h> #include <theme.h>
#include <QBoxLayout>
#include <QToolButton>
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <QMenu> #include <QBoxLayout>
#include <QHeaderView> #include <QHeaderView>
#include <QtDebug> #include <QMenu>
#include <QStackedWidget>
#include <QToolButton>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <utils/qtcassert.h>
namespace QmlDesigner { namespace QmlDesigner {
@@ -54,18 +58,43 @@ NavigatorWidget::NavigatorWidget(NavigatorView *view) :
m_treeView->setDefaultDropAction(Qt::LinkAction); m_treeView->setDefaultDropAction(Qt::LinkAction);
m_treeView->setHeaderHidden(true); m_treeView->setHeaderHidden(true);
QVBoxLayout *layout = new QVBoxLayout; auto layout = new QVBoxLayout;
layout->setSpacing(0); layout->setSpacing(0);
layout->setMargin(0); layout->setMargin(0);
layout->addWidget(m_treeView);
auto tabBar = new QTabBar(this);
tabBar->addTab(tr("Navigator"));
tabBar->addTab(tr("Project"));
tabBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
QWidget *spacer = new QWidget(this);
spacer->setObjectName(QStringLiteral("itemLibrarySearchInputSpacer"));
spacer->setFixedHeight(4);
layout->addWidget(tabBar);
layout->addWidget(spacer);
auto stackedWidget = new QStackedWidget(this);
stackedWidget->addWidget(m_treeView);
#ifndef QMLDESIGNER_TEST
auto projectManager = QmlDesignerPlugin::instance()->createProjectExplorerWidget(this);
QTC_ASSERT(projectManager, ;);
if (projectManager)
stackedWidget->addWidget(projectManager);
#endif
connect(tabBar, &QTabBar::currentChanged, stackedWidget, &QStackedWidget::setCurrentIndex);
layout->addWidget(stackedWidget);
setLayout(layout); setLayout(layout);
setWindowTitle(tr("Navigator", "Title of navigator view")); setWindowTitle(tr("Navigator", "Title of navigator view"));
#ifndef QMLDESIGNER_TEST #ifndef QMLDESIGNER_TEST
setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/stylesheet.css"))))); setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
m_treeView->setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css"))))); m_treeView->setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css"))));
#endif #endif
} }

View File

@@ -72,6 +72,12 @@ const char SB_PROJECTS[] = "Projects";
const char SB_FILESYSTEM[] = "FileSystem"; const char SB_FILESYSTEM[] = "FileSystem";
const char SB_OPENDOCUMENTS[] = "OpenDocuments"; const char SB_OPENDOCUMENTS[] = "OpenDocuments";
static void hideToolButtons(QList<QToolButton*> &buttons)
{
foreach (QToolButton *button, buttons)
button->hide();
}
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
@@ -169,6 +175,32 @@ void DesignModeWidget::toggleRightSidebar()
m_rightSideBar->setVisible(!m_rightSideBar->isVisible()); m_rightSideBar->setVisible(!m_rightSideBar->isVisible());
} }
QWidget *DesignModeWidget::createProjectExplorerWidget(QWidget *parent)
{
QList<Core::INavigationWidgetFactory *> factories =
ExtensionSystem::PluginManager::getObjects<Core::INavigationWidgetFactory>();
Core::NavigationView navigationView;
navigationView.widget = nullptr;
foreach (Core::INavigationWidgetFactory *factory, factories) {
if (factory->id() == "Projects") {
navigationView = factory->createWidget();
hideToolButtons(navigationView.dockToolBarWidgets);
}
}
if (navigationView.widget) {
QByteArray sheet = Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css");
sheet += Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css");
sheet += "QLabel { background-color: #4f4f4f; }";
navigationView.widget->setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(sheet)));
navigationView.widget->setParent(parent);
}
return navigationView.widget;
}
void DesignModeWidget::readSettings() void DesignModeWidget::readSettings()
{ {
QSettings *settings = Core::ICore::settings(); QSettings *settings = Core::ICore::settings();
@@ -221,12 +253,6 @@ void DesignModeWidget::switchTextOrForm()
m_centralTabWidget->switchTo(viewManager().widget("TextEditor")); m_centralTabWidget->switchTo(viewManager().widget("TextEditor"));
} }
static void hideToolButtons(QList<QToolButton*> &buttons)
{
foreach (QToolButton *button, buttons)
button->hide();
}
void DesignModeWidget::setup() void DesignModeWidget::setup()
{ {
auto &actionManager = viewManager().designerActionManager(); auto &actionManager = viewManager().designerActionManager();

View File

@@ -85,6 +85,8 @@ public:
void toggleLeftSidebar(); void toggleLeftSidebar();
void toggleRightSidebar(); void toggleRightSidebar();
static QWidget *createProjectExplorerWidget(QWidget *parent);
private: // functions private: // functions
enum InitializeStatus { NotInitialized, Initializing, Initialized }; enum InitializeStatus { NotInitialized, Initializing, Initialized };

View File

@@ -34,6 +34,9 @@
#include "dynamicpropertiesmodel.h" #include "dynamicpropertiesmodel.h"
#include "theme.h" #include "theme.h"
#include <designersettings.h>
#include <qmldesignerplugin.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
@@ -66,7 +69,12 @@ ConnectionViewWidget::ConnectionViewWidget(QWidget *parent) :
ui->tabBar->addTab(tr("Connections", "Title of connection view")); ui->tabBar->addTab(tr("Connections", "Title of connection view"));
ui->tabBar->addTab(tr("Bindings", "Title of connection view")); ui->tabBar->addTab(tr("Bindings", "Title of connection view"));
ui->tabBar->addTab(tr("Properties", "Title of dynamic properties view")); ui->tabBar->addTab(tr("Properties", "Title of dynamic properties view"));
ui->tabBar->addTab(tr("Backends", "Title of dynamic properties view"));
auto settings = QmlDesignerPlugin::instance()->settings();
if (!settings.value(DesignerSettingsKey::STANDALONE_MODE).toBool())
ui->tabBar->addTab(tr("Backends", "Title of dynamic properties view"));
ui->tabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); ui->tabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
const QString themedScrollBarCss = Theme::replaceCssColors( const QString themedScrollBarCss = Theme::replaceCssColors(

View File

@@ -455,6 +455,11 @@ Internal::DesignModeWidget *QmlDesignerPlugin::mainWidget() const
return nullptr; return nullptr;
} }
QWidget *QmlDesignerPlugin::createProjectExplorerWidget(QWidget *parent) const
{
return Internal::DesignModeWidget::createProjectExplorerWidget(parent);
}
void QmlDesignerPlugin::switchToTextModeDeferred() void QmlDesignerPlugin::switchToTextModeDeferred()
{ {
QTimer::singleShot(0, this, [] () { QTimer::singleShot(0, this, [] () {

View File

@@ -82,6 +82,8 @@ public:
DesignDocument *currentDesignDocument() const; DesignDocument *currentDesignDocument() const;
Internal::DesignModeWidget *mainWidget() const; Internal::DesignModeWidget *mainWidget() const;
QWidget *createProjectExplorerWidget(QWidget *parent) const;
void switchToTextModeDeferred(); void switchToTextModeDeferred();
void emitCurrentTextEditorChanged(Core::IEditor *editor); void emitCurrentTextEditorChanged(Core::IEditor *editor);

View File

@@ -47,6 +47,28 @@
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
const int DEFAULT_SORT_COLUMN = 2;
struct SortPreserver {
SortPreserver(Utils::TreeView *view) : view(view)
{
const QHeaderView *header = view->header();
column = header->sortIndicatorSection();
order = header->sortIndicatorOrder();
view->setSortingEnabled(false);
}
~SortPreserver()
{
view->setSortingEnabled(true);
view->sortByColumn(column, order);
}
int column;
Qt::SortOrder order;
Utils::TreeView *view;
};
struct Colors { struct Colors {
Colors () : noteBackground(QColor("orange")), defaultBackground(QColor("white")) {} Colors () : noteBackground(QColor("orange")), defaultBackground(QColor("white")) {}
QColor noteBackground; QColor noteBackground;
@@ -374,7 +396,6 @@ public:
QList<bool> m_fieldShown; QList<bool> m_fieldShown;
QHash<int, int> m_columnIndex; // maps field enum to column index QHash<int, int> m_columnIndex; // maps field enum to column index
bool m_showExtendedStatistics; bool m_showExtendedStatistics;
int m_firstNumericColumn;
}; };
QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView( QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(
@@ -384,8 +405,6 @@ QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(
setViewDefaults(this); setViewDefaults(this);
setObjectName(QLatin1String("QmlProfilerEventsTable")); setObjectName(QLatin1String("QmlProfilerEventsTable"));
setSortingEnabled(false);
d->m_model = new QStandardItemModel(this); d->m_model = new QStandardItemModel(this);
d->m_model->setSortRole(SortRole); d->m_model->setSortRole(SortRole);
setModel(d->m_model); setModel(d->m_model);
@@ -396,7 +415,6 @@ QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(
this, &QmlProfilerStatisticsMainView::buildModel); this, &QmlProfilerStatisticsMainView::buildModel);
connect(d->model, &QmlProfilerStatisticsModel::notesAvailable, connect(d->model, &QmlProfilerStatisticsModel::notesAvailable,
this, &QmlProfilerStatisticsMainView::updateNotes); this, &QmlProfilerStatisticsMainView::updateNotes);
d->m_firstNumericColumn = 0;
d->m_showExtendedStatistics = false; d->m_showExtendedStatistics = false;
setFieldViewable(Name, true); setFieldViewable(Name, true);
@@ -412,6 +430,9 @@ QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(
setFieldViewable(MedianTime, true); setFieldViewable(MedianTime, true);
setFieldViewable(Details, true); setFieldViewable(Details, true);
setSortingEnabled(true);
sortByColumn(DEFAULT_SORT_COLUMN, Qt::DescendingOrder);
buildModel(); buildModel();
} }
@@ -438,18 +459,15 @@ void QmlProfilerStatisticsMainView::setFieldViewable(Fields field, bool show)
void QmlProfilerStatisticsMainView::setHeaderLabels() void QmlProfilerStatisticsMainView::setHeaderLabels()
{ {
int fieldIndex = 0; int fieldIndex = 0;
d->m_firstNumericColumn = 0;
d->m_columnIndex.clear(); d->m_columnIndex.clear();
if (d->m_fieldShown[Name]) { if (d->m_fieldShown[Name]) {
d->m_columnIndex[Name] = fieldIndex; d->m_columnIndex[Name] = fieldIndex;
d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Location))); d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Location)));
d->m_firstNumericColumn++;
} }
if (d->m_fieldShown[Type]) { if (d->m_fieldShown[Type]) {
d->m_columnIndex[Type] = fieldIndex; d->m_columnIndex[Type] = fieldIndex;
d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Type))); d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Type)));
d->m_firstNumericColumn++;
} }
if (d->m_fieldShown[TimeInPercent]) { if (d->m_fieldShown[TimeInPercent]) {
d->m_columnIndex[TimeInPercent] = fieldIndex; d->m_columnIndex[TimeInPercent] = fieldIndex;
@@ -521,11 +539,10 @@ bool QmlProfilerStatisticsMainView::showExtendedStatistics() const
void QmlProfilerStatisticsMainView::clear() void QmlProfilerStatisticsMainView::clear()
{ {
SortPreserver sorter(this);
d->m_model->clear(); d->m_model->clear();
d->m_model->setColumnCount(d->getFieldCount()); d->m_model->setColumnCount(d->getFieldCount());
setHeaderLabels(); setHeaderLabels();
setSortingEnabled(false);
} }
int QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainViewPrivate::getFieldCount() int QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainViewPrivate::getFieldCount()
@@ -540,12 +557,13 @@ int QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainViewPrivate::getFiel
void QmlProfilerStatisticsMainView::buildModel() void QmlProfilerStatisticsMainView::buildModel()
{ {
clear(); clear();
parseModel();
setShowExtendedStatistics(d->m_showExtendedStatistics);
setRootIsDecorated(false); {
setSortingEnabled(true); SortPreserver sorter(this);
sortByColumn(d->m_firstNumericColumn,Qt::DescendingOrder); parseModel();
setShowExtendedStatistics(d->m_showExtendedStatistics);
setRootIsDecorated(false);
}
expandAll(); expandAll();
if (d->m_fieldShown[Name]) if (d->m_fieldShown[Name])
@@ -839,7 +857,6 @@ QmlProfilerStatisticsRelativesView::QmlProfilerStatisticsRelativesView(
Utils::TreeView(parent), d(new QmlProfilerStatisticsRelativesViewPrivate(this)) Utils::TreeView(parent), d(new QmlProfilerStatisticsRelativesViewPrivate(this))
{ {
setViewDefaults(this); setViewDefaults(this);
setSortingEnabled(false);
d->model = model; d->model = model;
QStandardItemModel *itemModel = new QStandardItemModel(this); QStandardItemModel *itemModel = new QStandardItemModel(this);
itemModel->setSortRole(SortRole); itemModel->setSortRole(SortRole);
@@ -847,6 +864,9 @@ QmlProfilerStatisticsRelativesView::QmlProfilerStatisticsRelativesView(
setRootIsDecorated(false); setRootIsDecorated(false);
updateHeader(); updateHeader();
setSortingEnabled(true);
sortByColumn(DEFAULT_SORT_COLUMN, Qt::DescendingOrder);
connect(this, &QAbstractItemView::activated, connect(this, &QAbstractItemView::activated,
this, &QmlProfilerStatisticsRelativesView::jumpToItem); this, &QmlProfilerStatisticsRelativesView::jumpToItem);
@@ -862,12 +882,11 @@ QmlProfilerStatisticsRelativesView::~QmlProfilerStatisticsRelativesView()
void QmlProfilerStatisticsRelativesView::displayType(int typeIndex) void QmlProfilerStatisticsRelativesView::displayType(int typeIndex)
{ {
SortPreserver sorter(this);
rebuildTree(d->model->getData(typeIndex)); rebuildTree(d->model->getData(typeIndex));
updateHeader(); updateHeader();
resizeColumnToContents(0); resizeColumnToContents(0);
setSortingEnabled(true);
sortByColumn(2);
} }
void QmlProfilerStatisticsRelativesView::rebuildTree( void QmlProfilerStatisticsRelativesView::rebuildTree(
@@ -929,6 +948,7 @@ void QmlProfilerStatisticsRelativesView::rebuildTree(
void QmlProfilerStatisticsRelativesView::clear() void QmlProfilerStatisticsRelativesView::clear()
{ {
if (treeModel()) { if (treeModel()) {
SortPreserver sorter(this);
treeModel()->clear(); treeModel()->clear();
updateHeader(); updateHeader();
} }

View File

@@ -127,6 +127,13 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FileName &fi
OtherFileFilterItem *otherFileFilterItem = new OtherFileFilterItem(projectItem); OtherFileFilterItem *otherFileFilterItem = new OtherFileFilterItem(projectItem);
setupFileFilterItem(otherFileFilterItem, childNode); setupFileFilterItem(otherFileFilterItem, childNode);
projectItem->appendContent(otherFileFilterItem); projectItem->appendContent(otherFileFilterItem);
} else if (childNode->name() == "Environment") {
const auto properties = childNode->properties();
auto i = properties.constBegin();
while (i != properties.constEnd()) {
projectItem->addToEnviroment(i.key(), i.value().toString());
++i;
}
} else { } else {
qWarning() << "Unknown type:" << childNode->name(); qWarning() << "Unknown type:" << childNode->name();
} }

View File

@@ -106,4 +106,14 @@ bool QmlProjectItem::matchesFile(const QString &filePath) const
return false; return false;
} }
QList<Utils::EnvironmentItem> QmlProjectItem::environment() const
{
return m_environment;
}
void QmlProjectItem::addToEnviroment(const QString &key, const QString &value)
{
m_environment.append(Utils::EnvironmentItem(key, value));
}
} // namespace QmlProjectManager } // namespace QmlProjectManager

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include <utils/environment.h>
#include <QObject> #include <QObject>
#include <QSet> #include <QSet>
#include <QStringList> #include <QStringList>
@@ -60,6 +62,9 @@ public:
void appendContent(QmlProjectContentItem *item) { m_content.append(item); } void appendContent(QmlProjectContentItem *item) { m_content.append(item); }
QList<Utils::EnvironmentItem> environment() const;
void addToEnviroment(const QString &key, const QString &value);
signals: signals:
void qmlFilesChanged(const QSet<QString> &, const QSet<QString> &); void qmlFilesChanged(const QSet<QString> &, const QSet<QString> &);
@@ -69,6 +74,7 @@ protected:
QStringList m_importPaths; QStringList m_importPaths;
QStringList m_absoluteImportPaths; QStringList m_absoluteImportPaths;
QString m_mainFile; QString m_mainFile;
QList<Utils::EnvironmentItem> m_environment;
QList<QmlProjectContentItem *> m_content; // content property QList<QmlProjectContentItem *> m_content; // content property
}; };

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