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
@@ -505,10 +505,10 @@ index c788abb881..ed4773b132 100644
|
||||
+clang_PrintingPolicy_setProperty
|
||||
+clang_PrintingPolicy_dispose
|
||||
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
|
||||
+++ 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));
|
||||
DisplayDiagnostics();
|
||||
}
|
||||
@@ -536,6 +536,8 @@ index f2a96d6be6..a9f5ee1da4 100644
|
||||
+ for (unsigned Value = 0; Value < 2; ++Value) {
|
||||
+ for (int I = 0; I < CXPrintingPolicy_LastProperty; ++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);
|
||||
+ EXPECT_EQ(Value, clang_PrintingPolicy_getProperty(Policy, Property));
|
||||
|
@@ -96,12 +96,10 @@
|
||||
|
||||
\li \uicontrol Copyright is a one-line, short copyright string.
|
||||
|
||||
\li \uicontrol License is a multi-line license text (but
|
||||
shouldn't be pages over pages long, since the interface
|
||||
doesn't allow nice reading of long texts).
|
||||
\li \uicontrol License is a license text.
|
||||
|
||||
\li \uicontrol{Description} is a relatively short, but possibly
|
||||
multi-line description of what the plugin does.
|
||||
\li \uicontrol{Description} is a short description of what the
|
||||
plugin does.
|
||||
|
||||
\li \uicontrol URL is a website where the user can find more
|
||||
information about the plugin and/or organization providing
|
||||
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 27 KiB |
BIN
doc/images/qtcreator-debugger-expressions.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
doc/images/qtcreator-gerrit-push.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
doc/images/qtcreator-heob-output.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
doc/images/qtcreator-heob-settings.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
doc/images/qtcreator-heob.png
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 32 KiB |
BIN
doc/images/qtcreator-locals.png
Normal file
After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 50 KiB |
@@ -31,7 +31,7 @@
|
||||
|
||||
/*!
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-clang-static-analyzer.html
|
||||
\previouspage creator-heob.html
|
||||
\page creator-cpu-usage-analyzer.html
|
||||
\nextpage creator-autotest.html
|
||||
|
||||
|
@@ -71,6 +71,11 @@
|
||||
Objective-C programs by using the experimental plugin that
|
||||
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}
|
||||
|
||||
You can analyze the CPU usage of embedded applications and Linux
|
||||
|
@@ -33,7 +33,7 @@
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-running-valgrind-remotely.html
|
||||
\page creator-clang-static-analyzer.html
|
||||
\nextpage creator-cpu-usage-analyzer.html
|
||||
\nextpage creator-heob.html
|
||||
|
||||
\title Using Clang Static Analyzer
|
||||
|
||||
|
197
doc/src/analyze/creator-heob.qdoc
Normal 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)}.
|
||||
*/
|
@@ -67,7 +67,7 @@
|
||||
|
||||
\list
|
||||
|
||||
\li \l{Detecting Memory Leaks}
|
||||
\li \l{Detecting Memory Leaks with Memcheck}
|
||||
|
||||
\li \l{Profiling Function Execution}
|
||||
|
||||
|
@@ -35,7 +35,7 @@
|
||||
\page creator-analyzer.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
|
||||
problems that are related to memory management in applications. You can use
|
||||
@@ -43,7 +43,9 @@
|
||||
application is interrupted and you can debug it.
|
||||
|
||||
\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
|
||||
\QC.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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,
|
||||
go to the \uicontrol {Locals and Expressions} view.
|
||||
go to the \uicontrol Locals view.
|
||||
|
||||
\image qtcreator-watcher.png
|
||||
|
||||
|
@@ -170,35 +170,37 @@
|
||||
|
||||
\section1 Installing Native Debuggers
|
||||
|
||||
Check the table below for the supported versions and other important
|
||||
information about installing native debuggers.
|
||||
The following sections provide information about installing native
|
||||
debuggers.
|
||||
|
||||
\table
|
||||
\header
|
||||
\li Native Debugger
|
||||
\li Notes
|
||||
\row
|
||||
\li GDB
|
||||
\li On Windows, use the Python-enabled GDB versions that is bundled
|
||||
\section2 GDB
|
||||
|
||||
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.
|
||||
most Linux distributions, the GDB builds shipped with the system
|
||||
are sufficient.
|
||||
|
||||
\row
|
||||
\li Debugging tools for Windows
|
||||
\li To use the CDB debugger, you must install the
|
||||
You can also build your own GDB, as instructed in
|
||||
\l{http://wiki.qt.io/QtCreator_Build_Gdb}{Building GDB}.
|
||||
|
||||
Builds of GDB shipped with Xcode on \macos are no longer supported.
|
||||
|
||||
\section2 Debugging Tools for Windows
|
||||
|
||||
To use the CDB debugger, you must install the
|
||||
\e{Debugging tools for Windows}. You can download them from
|
||||
\l{https://developer.microsoft.com/windows/downloads/windows-10-sdk}
|
||||
{Download and Install Debugging Tools for Windows} as part of the Windows SDK.
|
||||
{Download and Install Debugging Tools for Windows} as part of the Windows
|
||||
SDK.
|
||||
|
||||
\note Visual Studio does not include the Debugging tools needed,
|
||||
and therefore, you must install them separately.
|
||||
|
||||
The pre-built \QSDK for Windows makes use of the library if it
|
||||
is present on the system. When manually building \QC using
|
||||
In addition, you must select \uicontrol {Qt Creator CDB Debugger Support}
|
||||
(in \uicontrol Qt > \uicontrol Tools > \uicontrol {\QC}) when you install
|
||||
Qt or the stand-alone \QC.
|
||||
|
||||
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"}.
|
||||
@@ -210,9 +212,9 @@
|
||||
For more information, see
|
||||
\l{Setting CDB Paths on Windows}.
|
||||
|
||||
\row
|
||||
\li Debugging tools for \macos
|
||||
\li The Qt binary distribution contains both debug and release
|
||||
\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
|
||||
@@ -227,10 +229,9 @@
|
||||
see: \l{http://developer.apple.com/library/mac/#technotes/tn2124/_index.html#//apple_ref/doc/uid/DTS10003391}
|
||||
{Mac OS X Debugging Magic}.
|
||||
|
||||
\row
|
||||
\li LLDB
|
||||
\li We recommend using the LLDB version that is delivered with Xcode 5.
|
||||
\endtable
|
||||
\section2 LLDB
|
||||
|
||||
We recommend using the LLDB version that is delivered with the latest Xcode.
|
||||
|
||||
\section1 Mapping Source Paths
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
@@ -679,11 +679,10 @@
|
||||
|
||||
\section1 Local Variables and Function Parameters
|
||||
|
||||
The Locals view consists of two parts: the \uicontrol Locals pane at the top
|
||||
and the \uicontrol {Return Value} pane at the bottom. The
|
||||
\uicontrol {Return Value} is only visible if it is not empty.
|
||||
The Locals view consists of the \uicontrol Locals pane and the
|
||||
\uicontrol {Return Value} pane (hidden when 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
|
||||
information about the topmost stack frame and displays it in the
|
||||
@@ -694,7 +693,7 @@
|
||||
pane displays the value returned by the function.
|
||||
|
||||
|
||||
\section1 Evaluating Expresssion
|
||||
\section1 Evaluating Expressions
|
||||
|
||||
To compute values of arithmetic expressions or function calls, use
|
||||
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
|
||||
drop an expression from the code editor.
|
||||
|
||||
\image qtcreator-debugger-expressions.png
|
||||
|
||||
\note Expression evaluators are powerful, but slow down debugger operation
|
||||
significantly. It is advisable to not use them excessively, and to remove
|
||||
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
|
||||
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
|
||||
\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
|
||||
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:
|
||||
|
||||
@@ -1099,6 +1100,16 @@
|
||||
avoid direct access to the \c gdb.* and \c lldb.* namespaces and use the
|
||||
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
|
||||
a regular expression. To do so, the debugging helper's function name must
|
||||
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
|
||||
in a format that is similar to GDB/MI and JSON.
|
||||
|
||||
For each line in the \uicontrol {Locals and Expressions} view, a string like
|
||||
the following needs to be created and channeled to the debugger plugin.
|
||||
For each line in the \uicontrol Locals and \uicontrol Expressions views, a
|
||||
string like the following needs to be created and channeled to the debugger
|
||||
plugin.
|
||||
|
||||
\code
|
||||
{ iname='some internal name', # optional
|
||||
@@ -1575,18 +1587,18 @@
|
||||
|
||||
\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
|
||||
is displayed. To directly display the members of the pointer variable,
|
||||
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
|
||||
|
||||
By default, structure members are displayed in alphabetic order. To inspect
|
||||
the real layout in memory, deselect
|
||||
\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
|
||||
|
||||
|
@@ -218,14 +218,18 @@
|
||||
test list for the currently active test frameworks when you edit tests.
|
||||
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 scan for tests. Select \uicontrol Tools > \uicontrol Options >
|
||||
\uicontrol {Testing} > \uicontrol General > \uicontrol Add, and
|
||||
specify paths to the directories to scan for tests. Wildcards are not
|
||||
supported in the filter expressions.
|
||||
To group related test cases for an active test framework, select
|
||||
\uicontrol Tools > \uicontrol Options > \uicontrol {Testing} >
|
||||
\uicontrol General, and then select the \uicontrol Group check box next to
|
||||
the framework name in the \uicontrol {Active Test Frameworks} list.
|
||||
|
||||
\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
|
||||
view, select \inlineimage filtericon.png
|
||||
(\uicontrol {Filter Test Tree}), and then select \uicontrol {Show Init and
|
||||
|
@@ -177,11 +177,12 @@
|
||||
\li \l{Profiling QML Applications}
|
||||
\li \l{Using Valgrind Code Analysis Tools}
|
||||
\list
|
||||
\li \l{Detecting Memory Leaks}
|
||||
\li \l{Detecting Memory Leaks with Memcheck}
|
||||
\li \l{Profiling Function Execution}
|
||||
\li \l{Running Valgrind Tools on External Applications}
|
||||
\endlist
|
||||
\li \l{Using Clang Static Analyzer}
|
||||
\li \l{Detecting Memory Leaks with Heob}
|
||||
\li \l{Analyzing CPU Usage}
|
||||
\endlist
|
||||
\li \l{Running Autotests}
|
||||
|
@@ -299,6 +299,13 @@
|
||||
\uicontrol Git > \uicontrol {Remote Repository} >
|
||||
\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
|
||||
web interface, select \uicontrol Tools > \uicontrol Git >
|
||||
\uicontrol {Remote Repository} > \uicontrol Gerrit.
|
||||
|
@@ -16,6 +16,7 @@ Module {
|
||||
: ["$ORIGIN/..", "$ORIGIN/../" + qtc.ide_library_path]
|
||||
property string resourcesInstallDir: qtc.ide_data_path + "/qbs"
|
||||
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 libexecInstallDir: qtc.ide_libexec_path
|
||||
property bool installHtml: false
|
||||
|
@@ -258,6 +258,14 @@ def qdump__ProjectExplorer__FolderNode(d, value):
|
||||
d.putStringValue(value["m_displayName"])
|
||||
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):
|
||||
qdump__ProjectExplorer__FolderNode(d, value)
|
||||
|
||||
|
@@ -1,14 +1,32 @@
|
||||
{
|
||||
"name": "qbs",
|
||||
"searchPaths": [
|
||||
"$(QBS_IMPORT_PATH)"],
|
||||
"$(QBS_IMPORT_PATH)"
|
||||
],
|
||||
"installPaths": [
|
||||
"$(QBS_IMPORT_PATH)"],
|
||||
"$(QBS_IMPORT_PATH)"
|
||||
],
|
||||
"implicitImports": [
|
||||
"__javascriptQt5__"],
|
||||
"__javascriptQt5__"
|
||||
],
|
||||
"supportedImports": [
|
||||
"qbs.base 1.0",
|
||||
"qbs 1.0",
|
||||
"qbs.fileinfo 1.0",
|
||||
"qbs.probe 1.0"]
|
||||
"qbs",
|
||||
"qbs.BinaryFile",
|
||||
"qbs.BundleTools",
|
||||
"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"
|
||||
]
|
||||
}
|
||||
|
@@ -60,6 +60,7 @@ Module {
|
||||
Property { name: "fileTags"; type: "string"; isList: true }
|
||||
Property { name: "fileTagsFilter"; type: "string"; isList: true }
|
||||
Property { name: "files"; type: "string"; isList: true }
|
||||
Property { name: "filesAreTargets"; type: "bool" }
|
||||
Property { name: "name"; type: "string" }
|
||||
Property { name: "overrideTags"; type: "bool" }
|
||||
Property { name: "prefix"; type: "string" }
|
||||
@@ -72,6 +73,7 @@ Module {
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "name"; type: "string" }
|
||||
Property { name: "present"; type: "bool" }
|
||||
Property { name: "priority"; type: "int" }
|
||||
Property { name: "setupBuildEnvironment"; type: "QVariant" }
|
||||
Property { name: "setupRunEnvironment"; type: "QVariant" }
|
||||
Property { name: "validate"; type: "bool" }
|
||||
@@ -187,6 +189,7 @@ Module {
|
||||
name: "SubProject"
|
||||
exports: [ "qbs/SubProject 1.0" ]
|
||||
prototype: "QQuickItem"
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "filePath"; type: "string" }
|
||||
Property { name: "inheritProperties"; type: "bool" }
|
||||
}
|
||||
@@ -201,3 +204,4 @@ Module {
|
||||
Property { name: "prepare"; type: "QVariant" }
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -70,4 +70,7 @@ Module {
|
||||
]
|
||||
Property { name: "filter"; type: "string" }
|
||||
}
|
||||
Component {
|
||||
name: "Environment"
|
||||
}
|
||||
}
|
||||
|
@@ -157,7 +157,7 @@ Item {
|
||||
}
|
||||
|
||||
Controls.MenuItem {
|
||||
text: qsTr("Insert keyframe")
|
||||
text: qsTr("Insert Keyframe")
|
||||
visible: hasActiveTimeline
|
||||
onTriggered: insertKeyframe(backendValue.name)
|
||||
}
|
||||
|
@@ -237,11 +237,11 @@ Section {
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: qsTr("Prefer Shaping")
|
||||
text: qsTr("Prefer shaping")
|
||||
Layout.fillWidth: true
|
||||
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" +
|
||||
"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.")
|
||||
}
|
||||
}
|
||||
|
@@ -131,7 +131,7 @@ Section {
|
||||
|
||||
|
||||
Label {
|
||||
text: qsTr("Line Height")
|
||||
text: qsTr("Line height")
|
||||
tooltip: qsTr("Sets the line height for the text.")
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,19 @@ CONFIG += qt warn_on depend_includepath testcase
|
||||
TEMPLATE = app
|
||||
|
||||
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)
|
||||
|
||||
TEMPLATE = app
|
||||
|
@@ -17,6 +17,7 @@ CppApplication {
|
||||
]
|
||||
@else
|
||||
consoleApplication: true
|
||||
@endif
|
||||
|
||||
@if "%{TestFrameWork}" == "GTest"
|
||||
property string googletestDir: {
|
||||
@@ -28,7 +29,6 @@ CppApplication {
|
||||
return Environment.getEnv("GOOGLETEST_DIR")
|
||||
}
|
||||
}
|
||||
@endif
|
||||
|
||||
@if "%{GTestCXX11}" == "true"
|
||||
cpp.cxxLanguageVersion: "c++11"
|
||||
@@ -52,4 +52,24 @@ CppApplication {
|
||||
].concat(googleCommon.getGTestAll(googletestDir))
|
||||
.concat(googleCommon.getGMockAll(googletestDir))
|
||||
@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
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ find_package(Qt5Gui REQUIRED)
|
||||
SET(CMAKE_AUTOMOC ON)
|
||||
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
ENABLE_TESTING()
|
||||
|
||||
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)
|
||||
@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"
|
||||
add_definitions(-DGTEST_LANGUAGE_CXX11)
|
||||
|
@@ -1,3 +1,8 @@
|
||||
@if "%{TestFrameWork}" == "QtQuickTest"
|
||||
#include <QtQuickTest/quicktest.h>
|
||||
|
||||
QUICK_TEST_MAIN(example)
|
||||
@else
|
||||
%{Cpp:LicenseTemplate}\
|
||||
#include "%{TestCaseFileWithHeaderSuffix}"
|
||||
|
||||
@@ -8,3 +13,4 @@ int main(int argc, char *argv[])
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@endif
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -39,6 +39,10 @@
|
||||
{
|
||||
"key": "TestCaseFileWithCppSuffix",
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"trKey": "Googletest",
|
||||
"trKey": "Google Test",
|
||||
"value": "GTest"
|
||||
},
|
||||
{
|
||||
"trKey": "Qt Quick Test",
|
||||
"value": "QtQuickTest"
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -107,7 +116,7 @@
|
||||
{
|
||||
"name": "GenerateInitAndCleanup",
|
||||
"trDisplayName": "Generate initialization and cleanup code",
|
||||
"visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}",
|
||||
"visible": "%{JS: [ 'QtTest', 'QtQuickTest' ].indexOf('%{TestFrameWork}') >= 0 }",
|
||||
"type": "CheckBox",
|
||||
"data": {
|
||||
"checked": false
|
||||
@@ -174,7 +183,7 @@
|
||||
"enabled": "%{IsTopLevelProject}",
|
||||
"data": {
|
||||
"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",
|
||||
"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
|
||||
},
|
||||
{
|
||||
|
@@ -8,7 +8,7 @@
|
||||
"trDisplayCategory": "Modeling",
|
||||
"iconText": "scxml",
|
||||
"platformIndependent": true,
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QtSupport') >= 0}",
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('ScxmlEditor') >= 0}",
|
||||
|
||||
"options":
|
||||
[
|
||||
|
@@ -7,7 +7,7 @@
|
||||
"trDisplayName": "Plain C Application",
|
||||
"trDisplayCategory": "Non-Qt Project",
|
||||
"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":
|
||||
[
|
||||
|
@@ -7,7 +7,7 @@
|
||||
"trDisplayName": "Plain C++ Application",
|
||||
"trDisplayCategory": "Non-Qt Project",
|
||||
"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":
|
||||
[
|
||||
|
@@ -20,25 +20,9 @@ int main(int argc, char *argv[])
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
|
||||
const QUrl mainQml(QStringLiteral("qrc:/main.qml"));
|
||||
|
||||
// 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);
|
||||
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
||||
if (engine.rootObjects().isEmpty())
|
||||
return -1;
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
@@ -27,6 +27,10 @@ Product {
|
||||
"themes/**/*",
|
||||
"welcomescreen/**/*"
|
||||
]
|
||||
excludeFiles: [
|
||||
"qml-type-descriptions/qbs-bundle.json",
|
||||
"qml-type-descriptions/qbs.qmltypes",
|
||||
]
|
||||
}
|
||||
|
||||
Group {
|
||||
|
@@ -158,8 +158,8 @@ static inline int askMsgSendFailed()
|
||||
{
|
||||
return QMessageBox::question(0, QApplication::translate("Application","Could not send message"),
|
||||
QCoreApplication::translate("Application", "Unable to send command line arguments "
|
||||
"to the already running instance. It appears to be not "
|
||||
"responding. Do you want to start a new instance of "
|
||||
"to the already running instance. It does not appear to "
|
||||
"be responding. Do you want to start a new instance of "
|
||||
"%1?").arg(Core::Constants::IDE_DISPLAY_NAME),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Retry,
|
||||
QMessageBox::Retry);
|
||||
|
@@ -85,7 +85,7 @@ void ProcessCreator::checkIfProcessPathExists() const
|
||||
{
|
||||
if (!QFileInfo::exists(m_processPath)) {
|
||||
const QString messageTemplate = QCoreApplication::translate("ProcessCreator",
|
||||
"Executable does not exists: %1");
|
||||
"Executable does not exist: %1");
|
||||
throwProcessException(messageTemplate.arg(m_processPath));
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@ void ProcessCreator::dispatchProcessError(QProcess *process) const
|
||||
switch (process->error()) {
|
||||
case QProcess::UnknownError: {
|
||||
const QString message = QCoreApplication::translate("ProcessCreator",
|
||||
"Unknown error happend.");
|
||||
"Unknown error occurred.");
|
||||
throwProcessException(message);
|
||||
};
|
||||
case QProcess::Crashed: {
|
||||
@@ -116,7 +116,7 @@ void ProcessCreator::dispatchProcessError(QProcess *process) const
|
||||
};
|
||||
case QProcess::Timedout: {
|
||||
const QString message = QCoreApplication::translate("ProcessCreator",
|
||||
"Process timeouted.");
|
||||
"Process timed out.");
|
||||
throwProcessException(message);
|
||||
};
|
||||
case QProcess::WriteError: {
|
||||
|
@@ -515,6 +515,7 @@ bool DiagramSceneModel::exportSvg(const QString &fileName, bool selectedElements
|
||||
return true;
|
||||
#else // QT_NO_SVG
|
||||
Q_UNUSED(fileName);
|
||||
Q_UNUSED(selectedElements);
|
||||
return false;
|
||||
#endif // QT_NO_SVG
|
||||
}
|
||||
|
@@ -217,7 +217,7 @@ void QmlDebugConnectionManager::destroyConnection()
|
||||
|
||||
void QmlDebugConnectionManager::qmlDebugConnectionOpened()
|
||||
{
|
||||
logState(tr("Debug connection opened"));
|
||||
logState(tr("Debug connection opened."));
|
||||
QTC_ASSERT(m_connection, return);
|
||||
QTC_ASSERT(m_connection->isConnected(), return);
|
||||
stopConnectionTimer();
|
||||
@@ -226,7 +226,7 @@ void QmlDebugConnectionManager::qmlDebugConnectionOpened()
|
||||
|
||||
void QmlDebugConnectionManager::qmlDebugConnectionClosed()
|
||||
{
|
||||
logState(tr("Debug connection closed"));
|
||||
logState(tr("Debug connection closed."));
|
||||
QTC_ASSERT(m_connection, return);
|
||||
QTC_ASSERT(!m_connection->isConnected(), return);
|
||||
destroyConnection();
|
||||
@@ -235,7 +235,7 @@ void QmlDebugConnectionManager::qmlDebugConnectionClosed()
|
||||
|
||||
void QmlDebugConnectionManager::qmlDebugConnectionFailed()
|
||||
{
|
||||
logState(tr("Debug connection failed"));
|
||||
logState(tr("Debug connection failed."));
|
||||
QTC_ASSERT(m_connection, return);
|
||||
QTC_ASSERT(!m_connection->isConnected(), /**/);
|
||||
|
||||
|
@@ -68,7 +68,6 @@ ScrollView {
|
||||
// switch to non-interactive ourselves, though.
|
||||
property bool stayInteractive: true
|
||||
onStayInteractiveChanged: flick.interactive = stayInteractive
|
||||
onWidthChanged: scroll()
|
||||
|
||||
Flickable {
|
||||
id: flick
|
||||
@@ -89,6 +88,15 @@ ScrollView {
|
||||
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.
|
||||
onContentXChanged: guarded(function() {
|
||||
var newStartTime = contentX * zoomer.rangeDuration / scroller.width
|
||||
|
@@ -66,7 +66,8 @@ static bool isQmake(const QString &path)
|
||||
QFileInfo fi(path);
|
||||
if (BuildableHelperLibrary::isQtChooser(fi))
|
||||
fi.setFile(BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget()));
|
||||
|
||||
if (!fi.exists() || fi.isDir())
|
||||
return false;
|
||||
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 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)
|
||||
return QStringList(QLatin1String("qmake*"));
|
||||
return QStringList(HostOsInfo::withExecutableSuffix("qmake*"));
|
||||
}
|
||||
|
||||
// Copy helper source files to a target directory, replacing older files.
|
||||
|
@@ -80,7 +80,7 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="removeVCCheckBox">
|
||||
<property name="text">
|
||||
<string>&Remove from Version Control</string>
|
||||
<string>&Remove from version control</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@@ -640,7 +640,7 @@ QVariant SettingsAccessor::retrieveSharedSettings() const
|
||||
QString SettingsAccessor::differentEnvironmentMsg(const QString &projectName)
|
||||
{
|
||||
return QApplication::translate("Utils::EnvironmentIdAccessor",
|
||||
"Settings File for \"%1\" from a different Environment?")
|
||||
"Settings File for \"%1\" from a Different Environment?")
|
||||
.arg(projectName);
|
||||
}
|
||||
|
||||
|
@@ -26,10 +26,10 @@
|
||||
#include "winutils.h"
|
||||
#include "qtcassert.h"
|
||||
|
||||
// Enable WinAPI Windows XP and later
|
||||
// Enable WinAPI Windows Vista and later
|
||||
#ifdef Q_OS_WIN
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define _WIN32_WINNT 0x0600 // Needed for QueryFullProcessImageName
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
@@ -168,6 +168,23 @@ QTCREATOR_UTILS_EXPORT bool is64BitWindowsBinary(const QString &binaryIn)
|
||||
#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()
|
||||
#ifdef Q_OS_WIN
|
||||
: silenceErrorMode(SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS),
|
||||
|
@@ -44,6 +44,9 @@ QTCREATOR_UTILS_EXPORT bool is64BitWindowsSystem();
|
||||
// Check for a 64bit 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
|
||||
// application-global (!) error mode.
|
||||
|
@@ -558,9 +558,8 @@ ClangCompletionAssistProcessor::extractLineColumn(int position)
|
||||
|
||||
int line = -1, column = -1;
|
||||
::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 = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
|
||||
|
||||
column = Utils::clangColumn(m_interface->textDocument()->findBlock(position), column);
|
||||
return {line, column};
|
||||
}
|
||||
|
||||
|
@@ -64,6 +64,9 @@ int positionInText(QTextDocument *textDocument,
|
||||
{
|
||||
auto textBlock = textDocument->findBlockByNumber(
|
||||
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;
|
||||
return textBlock.position() + column;
|
||||
}
|
||||
|
@@ -356,9 +356,7 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams ¶m
|
||||
if (!isCursorOnIdentifier(params.textCursor))
|
||||
return defaultCursorInfoFuture();
|
||||
|
||||
const QTextBlock block = params.textCursor.document()->findBlockByNumber(line - 1);
|
||||
const QString stringOnTheLeft = block.text().left(column);
|
||||
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
|
||||
column = Utils::clangColumn(params.textCursor.document()->findBlockByNumber(line - 1), column);
|
||||
const CppTools::SemanticInfo::LocalUseMap localUses
|
||||
= CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column);
|
||||
|
||||
|
@@ -43,6 +43,7 @@
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QStringList>
|
||||
#include <QTextBlock>
|
||||
|
||||
using namespace ClangCodeModel;
|
||||
using namespace ClangCodeModel::Internal;
|
||||
@@ -190,5 +191,15 @@ void setLastSentDocumentRevision(const QString &filePath, uint 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 Clang
|
||||
|
@@ -27,6 +27,10 @@
|
||||
|
||||
#include <cpptools/projectpart.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTextBlock;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace CppTools {
|
||||
class CppEditorDocumentHandle;
|
||||
}
|
||||
@@ -46,6 +50,7 @@ CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath);
|
||||
CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath);
|
||||
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
|
||||
QString projectPartIdForFile(const QString &filePath);
|
||||
int clangColumn(const QTextBlock &lineText, int cppEditorColumn);
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Clang
|
||||
|
@@ -61,6 +61,7 @@
|
||||
#include <utils/checkablemessagebox.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/temporarydirectory.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QLoggingCategory>
|
||||
@@ -71,6 +72,40 @@ using namespace Utils;
|
||||
|
||||
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 Internal {
|
||||
|
||||
@@ -303,7 +338,9 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
|
||||
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
|
||||
CompilerOptionsBuilder optionsBuilder(*projectPart, clangVersion,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@@ -77,6 +77,9 @@ const char CUT[] = "QtCreator.Cut";
|
||||
const char SELECTALL[] = "QtCreator.SelectAll";
|
||||
|
||||
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 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_PROJECT[] = "QtCreator.Group.File.Project";
|
||||
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_PRINT[] = "QtCreator.Group.File.Print";
|
||||
const char G_FILE_OTHER[] = "QtCreator.Group.File.Other";
|
||||
|
@@ -17,11 +17,18 @@ Project {
|
||||
condition: qbs.targetOS.contains("windows")
|
||||
}
|
||||
|
||||
Depends { name: "Qt.script"; required: false }
|
||||
|
||||
Depends { name: "Utils" }
|
||||
Depends { name: "Aggregation" }
|
||||
|
||||
Depends { name: "app_version_header" }
|
||||
|
||||
Properties {
|
||||
condition: Qt.script.present
|
||||
cpp.defines: base.concat("WITH_JAVASCRIPTFILTER")
|
||||
}
|
||||
|
||||
cpp.dynamicLibraries: {
|
||||
if (qbs.targetOS.contains("windows"))
|
||||
return ["ole32", "user32"]
|
||||
@@ -341,8 +348,6 @@ Project {
|
||||
"filesystemfilter.ui",
|
||||
"ilocatorfilter.cpp",
|
||||
"ilocatorfilter.h",
|
||||
"javascriptfilter.cpp",
|
||||
"javascriptfilter.h",
|
||||
"locatorconstants.h",
|
||||
"locatorfiltersfilter.cpp",
|
||||
"locatorfiltersfilter.h",
|
||||
@@ -362,6 +367,16 @@ Project {
|
||||
]
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "Locator Javascript Filter"
|
||||
condition: Qt.script.present
|
||||
prefix: "locator/"
|
||||
files: [
|
||||
"javascriptfilter.cpp",
|
||||
"javascriptfilter.h",
|
||||
]
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "Locator_mac"
|
||||
condition: qbs.targetOS.contains("macos")
|
||||
|
@@ -50,6 +50,8 @@ namespace {
|
||||
const int ICON_SIZE = 48;
|
||||
const char LAST_CATEGORY_KEY[] = "Core/NewDialog/LastCategory";
|
||||
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
|
||||
{
|
||||
@@ -79,13 +81,28 @@ public:
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void manualReset()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
|
||||
{
|
||||
if (!sourceParent.isValid())
|
||||
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);
|
||||
Core::IWizardFactory *wizard = factoryOfItem(qobject_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(sourceIndex));
|
||||
Core::IWizardFactory *wizard =
|
||||
factoryOfItem(qobject_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(sourceIndex));
|
||||
if (wizard)
|
||||
return wizard->isAvailable(m_platform);
|
||||
|
||||
@@ -95,51 +112,6 @@ private:
|
||||
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
|
||||
|
||||
class FancyTopLevelDelegate : public QItemDelegate
|
||||
@@ -209,12 +181,11 @@ NewDialog::NewDialog(QWidget *parent) :
|
||||
m_okButton->setText(tr("Choose..."));
|
||||
|
||||
m_model = new QStandardItemModel(this);
|
||||
m_twoLevelProxyModel = new TwoLevelProxyModel(this);
|
||||
m_twoLevelProxyModel->setSourceModel(m_model);
|
||||
|
||||
m_filterProxyModel = new PlatformFilterProxyModel(this);
|
||||
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->setItemDelegate(new FancyTopLevelDelegate);
|
||||
|
||||
@@ -269,6 +240,9 @@ void NewDialog::setWizardFactories(QList<IWizardFactory *> factories,
|
||||
m_dummyIcon = QIcon(":/utils/images/wizardicon-file.png");
|
||||
|
||||
QSet<Id> availablePlatforms = IWizardFactory::allAvailablePlatforms();
|
||||
|
||||
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) {
|
||||
@@ -279,6 +253,10 @@ void NewDialog::setWizardFactories(QList<IWizardFactory *> factories,
|
||||
m_ui->comboBox->setCurrentIndex(0); // "All templates"
|
||||
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) {
|
||||
QStandardItem *kindItem;
|
||||
switch (factory->kind()) {
|
||||
@@ -309,21 +287,23 @@ void NewDialog::showDialog()
|
||||
m_ui->comboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
static_cast<PlatformFilterProxyModel*>(m_filterProxyModel)->manualReset();
|
||||
|
||||
if (!lastCategory.isEmpty())
|
||||
foreach (QStandardItem* item, m_categoryItems) {
|
||||
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())
|
||||
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);
|
||||
|
||||
// We need to set ensure that the category has default focus
|
||||
m_ui->templateCategoryView->setFocus(Qt::NoFocusReason);
|
||||
|
||||
for (int row = 0; row < m_twoLevelProxyModel->rowCount(); ++row)
|
||||
m_ui->templateCategoryView->setExpanded(m_twoLevelProxyModel->index(row, 0), true);
|
||||
for (int row = 0; row < m_filterProxyModel->rowCount(); ++row)
|
||||
m_ui->templateCategoryView->setExpanded(m_filterProxyModel->index(row, 0), true);
|
||||
|
||||
// Ensure that item description is visible on first show
|
||||
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)
|
||||
{
|
||||
if (index.parent() != m_model->invisibleRootItem()->index()) {
|
||||
QModelIndex sourceIndex = m_twoLevelProxyModel->mapToSource(index);
|
||||
QModelIndex sourceIndex = m_filterProxyModel->mapToSource(index);
|
||||
sourceIndex = m_filterProxyModel->mapFromSource(sourceIndex);
|
||||
m_ui->templatesView->setRootIndex(sourceIndex);
|
||||
// Focus the first item by default
|
||||
@@ -472,8 +452,9 @@ void NewDialog::currentItemChanged(const QModelIndex &index)
|
||||
|
||||
void NewDialog::saveState()
|
||||
{
|
||||
QModelIndex idx = m_ui->templateCategoryView->currentIndex();
|
||||
QStandardItem *currentItem = m_model->itemFromIndex(m_twoLevelProxyModel->mapToSource(idx));
|
||||
const QModelIndex filterIdx = m_ui->templateCategoryView->currentIndex();
|
||||
const QModelIndex idx = m_filterProxyModel->mapToSource(filterIdx);
|
||||
QStandardItem *currentItem = m_model->itemFromIndex(idx);
|
||||
if (currentItem)
|
||||
ICore::settings()->setValue(QLatin1String(LAST_CATEGORY_KEY),
|
||||
currentItem->data(Qt::UserRole));
|
||||
|
@@ -81,7 +81,6 @@ private:
|
||||
|
||||
Ui::NewDialog *m_ui;
|
||||
QStandardItemModel *m_model;
|
||||
QAbstractProxyModel *m_twoLevelProxyModel;
|
||||
QSortFilterProxyModel *m_filterProxyModel;
|
||||
QPushButton *m_okButton;
|
||||
QIcon m_dummyIcon;
|
||||
|
@@ -27,14 +27,15 @@
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QGuiApplication>
|
||||
#include <QJSEngine>
|
||||
#include <QScriptEngine>
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
enum JavaScriptAction
|
||||
{
|
||||
ResetEngine = QVariant::UserType + 1
|
||||
ResetEngine = QVariant::UserType + 1,
|
||||
AbortEngine
|
||||
};
|
||||
|
||||
JavaScriptFilter::JavaScriptFilter()
|
||||
@@ -43,6 +44,13 @@ JavaScriptFilter::JavaScriptFilter()
|
||||
setDisplayName(tr("Evaluate JavaScript"));
|
||||
setIncludedByDefault(false);
|
||||
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()
|
||||
@@ -55,6 +63,8 @@ void JavaScriptFilter::prepareSearch(const QString &entry)
|
||||
|
||||
if (!m_engine)
|
||||
setupEngine();
|
||||
m_aborted = false;
|
||||
m_abortTimer.start();
|
||||
}
|
||||
|
||||
QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
|
||||
@@ -67,12 +77,16 @@ QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
|
||||
entries.append({this, tr("Reset Engine"), QVariant(ResetEngine, nullptr)});
|
||||
} else {
|
||||
const QString result = m_engine->evaluate(entry).toString();
|
||||
if (m_aborted) {
|
||||
const QString message = entry + " = " + tr("Engine aborted after timeout.");
|
||||
entries.append({this, message, QVariant(AbortEngine, nullptr)});
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
@@ -104,7 +118,7 @@ void JavaScriptFilter::refresh(QFutureInterface<void> &future)
|
||||
|
||||
void JavaScriptFilter::setupEngine()
|
||||
{
|
||||
m_engine.reset(new QJSEngine);
|
||||
m_engine.reset(new QScriptEngine);
|
||||
m_engine->evaluate(
|
||||
"function abs(x) { return Math.abs(x); }\n"
|
||||
"function acos(x) { return Math.acos(x); }\n"
|
||||
|
@@ -27,10 +27,12 @@
|
||||
|
||||
#include <coreplugin/locator/ilocatorfilter.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QJSEngine;
|
||||
class QScriptEngine;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
@@ -53,7 +55,9 @@ public:
|
||||
private:
|
||||
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
|
||||
|
@@ -75,7 +75,9 @@ class LocatorData
|
||||
public:
|
||||
LocatorManager m_locatorManager;
|
||||
|
||||
#ifdef WITH_JAVASCRIPTFILTER
|
||||
JavaScriptFilter m_javaScriptFilter;
|
||||
#endif
|
||||
OpenDocumentsFilter m_openDocumentsFilter;
|
||||
FileSystemFilter m_fileSystemFilter;
|
||||
ExecuteFilter m_executeFilter;
|
||||
@@ -124,7 +126,6 @@ void Locator::initialize()
|
||||
auto locatorWidget = LocatorManager::createLocatorInputWidget(ICore::mainWindow());
|
||||
StatusBarManager::addStatusBarWidget(locatorWidget, StatusBarManager::First,
|
||||
Context("LocatorWidget"));
|
||||
|
||||
connect(ICore::instance(), &ICore::saveSettingsRequested, this, &Locator::saveSettings);
|
||||
}
|
||||
|
||||
|
@@ -15,8 +15,7 @@ HEADERS += \
|
||||
$$PWD/executefilter.h \
|
||||
$$PWD/locatorsearchutils.h \
|
||||
$$PWD/locatorsettingspage.h \
|
||||
$$PWD/externaltoolsfilter.h \
|
||||
$$PWD/javascriptfilter.h
|
||||
$$PWD/externaltoolsfilter.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/locator.cpp \
|
||||
@@ -33,7 +32,18 @@ SOURCES += \
|
||||
$$PWD/locatorsearchutils.cpp \
|
||||
$$PWD/locatorsettingspage.cpp \
|
||||
$$PWD/externaltoolsfilter.cpp \
|
||||
|
||||
qtHaveModule(script) {
|
||||
QT *= script
|
||||
|
||||
DEFINES += WITH_JAVASCRIPTFILTER
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/javascriptfilter.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/javascriptfilter.cpp
|
||||
}
|
||||
|
||||
FORMS += \
|
||||
$$PWD/filesystemfilter.ui \
|
||||
|
@@ -411,6 +411,7 @@ void MainWindow::registerDefaultContainers()
|
||||
filemenu->appendGroup(Constants::G_FILE_OPEN);
|
||||
filemenu->appendGroup(Constants::G_FILE_PROJECT);
|
||||
filemenu->appendGroup(Constants::G_FILE_SAVE);
|
||||
filemenu->appendGroup(Constants::G_FILE_EXPORT);
|
||||
filemenu->appendGroup(Constants::G_FILE_CLOSE);
|
||||
filemenu->appendGroup(Constants::G_FILE_PRINT);
|
||||
filemenu->appendGroup(Constants::G_FILE_OTHER);
|
||||
@@ -465,6 +466,7 @@ void MainWindow::registerDefaultActions()
|
||||
|
||||
// File menu separators
|
||||
mfile->addSeparator(Constants::G_FILE_SAVE);
|
||||
mfile->addSeparator(Constants::G_FILE_EXPORT);
|
||||
mfile->addSeparator(Constants::G_FILE_PRINT);
|
||||
mfile->addSeparator(Constants::G_FILE_CLOSE);
|
||||
mfile->addSeparator(Constants::G_FILE_OTHER);
|
||||
@@ -620,6 +622,30 @@ void MainWindow::registerDefaultActions()
|
||||
medit->addAction(cmd, Constants::G_EDIT_OTHER);
|
||||
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
|
||||
mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
|
||||
mtools->addSeparator(Constants::G_TOOLS_OPTIONS);
|
||||
|
@@ -31,7 +31,6 @@
|
||||
|
||||
#include <utils/link.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <clangsupport/sourcelocationscontainer.h>
|
||||
#include <clangsupport/refactoringclientinterface.h>
|
||||
|
@@ -438,7 +438,7 @@ void extractGdbVersion(const QString &msg,
|
||||
const QChar dot(QLatin1Char('.'));
|
||||
|
||||
const bool ignoreParenthesisContent = msg.contains(QLatin1String("rubenvb"))
|
||||
|| msg.contains(QLatin1String("openSUSE"));
|
||||
|| msg.contains(QLatin1String("SUSE"));
|
||||
|
||||
const QChar parOpen(QLatin1Char('('));
|
||||
const QChar parClose(QLatin1Char(')'));
|
||||
|
@@ -226,22 +226,22 @@ void GerritPushDialog::onRemoteChanged(bool force)
|
||||
m_currentSupportsWip = supportsWip;
|
||||
m_ui->wipCheckBox->setEnabled(supportsWip);
|
||||
if (supportsWip) {
|
||||
m_ui->wipCheckBox->setToolTip(tr("Checked - Mark change as WIP\n"
|
||||
"Unchecked - Mark change as ready\n"
|
||||
"Partially checked - Do not change current state"));
|
||||
m_ui->wipCheckBox->setToolTip(tr("Checked - Mark change as WIP.\n"
|
||||
"Unchecked - Mark change as ready for review.\n"
|
||||
"Partially checked - Do not change current state."));
|
||||
m_ui->draftCheckBox->setTristate(true);
|
||||
if (m_ui->draftCheckBox->checkState() != Qt::Checked)
|
||||
m_ui->draftCheckBox->setCheckState(Qt::PartiallyChecked);
|
||||
m_ui->draftCheckBox->setToolTip(tr("Checked - Mark change as private\n"
|
||||
"Unchecked - Unmark change as private\n"
|
||||
"Partially checked - Do not change current state"));
|
||||
m_ui->draftCheckBox->setToolTip(tr("Checked - Mark change as private.\n"
|
||||
"Unchecked - Remove mark.\n"
|
||||
"Partially checked - Do not change current state."));
|
||||
} 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);
|
||||
if (m_ui->draftCheckBox->checkState() != Qt::Checked)
|
||||
m_ui->draftCheckBox->setCheckState(Qt::Unchecked);
|
||||
m_ui->draftCheckBox->setToolTip(tr("Checked - Mark change as draft\n"
|
||||
"Unchecked - Unmark change as draft"));
|
||||
m_ui->draftCheckBox->setToolTip(tr("Checked - The change is a draft.\n"
|
||||
"Unchecked - The change is not a draft."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -82,14 +82,14 @@ Unchecked - Unmark change as private
|
||||
Semi-checked - Do not change current state</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Draft/Private</string>
|
||||
<string>&Draft/private</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="wipCheckBox">
|
||||
<property name="text">
|
||||
<string>&Work-In-Progress</string>
|
||||
<string>&Work-in-progress</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
|
@@ -33,10 +33,12 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QMap>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
@@ -107,14 +109,14 @@ void ImageViewer::ctor()
|
||||
{QLatin1String(":/utils/images/desktopdevicesmall.png"), Utils::Theme::IconsBaseColor}});
|
||||
d->ui_toolbar.toolButtonBackground->setIcon(backgroundIcon.icon());
|
||||
d->ui_toolbar.toolButtonOutline->setIcon(Utils::Icons::BOUNDING_RECT.icon());
|
||||
d->ui_toolbar.toolButtonZoomIn->setIcon(Utils::Icons::ZOOMIN_TOOLBAR.icon());
|
||||
d->ui_toolbar.toolButtonZoomOut->setIcon(Utils::Icons::ZOOMOUT_TOOLBAR.icon());
|
||||
d->ui_toolbar.toolButtonZoomIn->setIcon(
|
||||
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.toolButtonOriginalSize->setIcon(Utils::Icons::EYE_OPEN_TOOLBAR.icon());
|
||||
// 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"));
|
||||
// a display - something is on the background
|
||||
updateButtonIconByTheme(d->ui_toolbar.toolButtonBackground, QLatin1String("video-display"));
|
||||
@@ -123,9 +125,9 @@ void ImageViewer::ctor()
|
||||
updateButtonIconByTheme(d->ui_toolbar.toolButtonOutline, QLatin1String("emblem-photos"));
|
||||
|
||||
d->ui_toolbar.toolButtonExportImage->setCommandId(Constants::ACTION_EXPORT_IMAGE);
|
||||
d->ui_toolbar.toolButtonZoomIn->setCommandId(Constants::ACTION_ZOOM_IN);
|
||||
d->ui_toolbar.toolButtonZoomOut->setCommandId(Constants::ACTION_ZOOM_OUT);
|
||||
d->ui_toolbar.toolButtonOriginalSize->setCommandId(Constants::ACTION_ORIGINAL_SIZE);
|
||||
d->ui_toolbar.toolButtonZoomIn->setCommandId(Core::Constants::ZOOM_IN);
|
||||
d->ui_toolbar.toolButtonZoomOut->setCommandId(Core::Constants::ZOOM_OUT);
|
||||
d->ui_toolbar.toolButtonOriginalSize->setCommandId(Core::Constants::ZOOM_RESET);
|
||||
d->ui_toolbar.toolButtonFitToScreen->setCommandId(Constants::ACTION_FIT_TO_SCREEN);
|
||||
d->ui_toolbar.toolButtonBackground->setCommandId(Constants::ACTION_BACKGROUND);
|
||||
d->ui_toolbar.toolButtonOutline->setCommandId(Constants::ACTION_OUTLINE);
|
||||
|
@@ -33,9 +33,6 @@ const char IMAGEVIEWER_ID[] = "Editors.ImageViewer";
|
||||
const char IMAGEVIEWER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "Image Viewer");
|
||||
|
||||
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_BACKGROUND[] = "ImageViewer.Background";
|
||||
const char ACTION_OUTLINE[] = "ImageViewer.Outline";
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/id.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
@@ -62,22 +63,19 @@ static inline ImageViewer *currentImageViewer()
|
||||
|
||||
void ImageViewerPlugin::extensionsInitialized()
|
||||
{
|
||||
QAction *a = registerNewAction(Constants::ACTION_ZOOM_IN, tr("Zoom In"),
|
||||
QKeySequence(tr("Ctrl++")));
|
||||
QAction *a = registerNewAction(Core::Constants::ZOOM_IN);
|
||||
connect(a, &QAction::triggered, this, []() {
|
||||
if (ImageViewer *iv = currentImageViewer())
|
||||
iv->zoomIn();
|
||||
});
|
||||
|
||||
a = registerNewAction(Constants::ACTION_ZOOM_OUT, tr("Zoom Out"),
|
||||
QKeySequence(tr("Ctrl+-")));
|
||||
a = registerNewAction(Core::Constants::ZOOM_OUT);
|
||||
connect(a, &QAction::triggered, this, []() {
|
||||
if (ImageViewer *iv = currentImageViewer())
|
||||
iv->zoomOut();
|
||||
});
|
||||
|
||||
a = registerNewAction(Constants::ACTION_ORIGINAL_SIZE, tr("Original Size"),
|
||||
QKeySequence(Core::useMacShortcuts ? tr("Meta+0") : tr("Ctrl+0")));
|
||||
a = registerNewAction(Core::Constants::ZOOM_RESET);
|
||||
connect(a, &QAction::triggered, this, []() {
|
||||
if (ImageViewer *iv = currentImageViewer())
|
||||
iv->resetToOriginalSize();
|
||||
@@ -125,6 +123,7 @@ QAction *ImageViewerPlugin::registerNewAction(Core::Id id,
|
||||
Core::Context context(Constants::IMAGEVIEWER_ID);
|
||||
QAction *action = new QAction(title, this);
|
||||
Core::Command *command = Core::ActionManager::registerAction(action, id, context);
|
||||
if (!key.isEmpty())
|
||||
command->setDefaultKeySequence(key);
|
||||
return action;
|
||||
}
|
||||
|
@@ -28,12 +28,12 @@
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
#include <QKeySequence>
|
||||
#include <QPointer>
|
||||
#include <QtPlugin>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QKeySequence;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core { class Id; }
|
||||
@@ -55,7 +55,8 @@ public:
|
||||
void extensionsInitialized();
|
||||
|
||||
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;
|
||||
};
|
||||
|
@@ -58,9 +58,6 @@ public:
|
||||
QAction *synchronizeBrowserAction = nullptr;
|
||||
QAction *exportDiagramAction = nullptr;
|
||||
QAction *exportSelectedElementsAction = nullptr;
|
||||
QAction *zoomInAction = nullptr;
|
||||
QAction *zoomOutAction = nullptr;
|
||||
QAction *resetZoomAction = nullptr;
|
||||
};
|
||||
|
||||
ActionHandler::ActionHandler(const Core::Context &context, QObject *parent)
|
||||
@@ -135,92 +132,63 @@ QAction *ActionHandler::exportSelectedElementsAction() const
|
||||
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()
|
||||
{
|
||||
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->redoAction = registerCommand(Core::Constants::REDO, [this]() { redo(); }, d->context)->action();
|
||||
d->cutAction = registerCommand(Core::Constants::CUT, [this]() { cut(); }, d->context)->action();
|
||||
d->copyAction = registerCommand(Core::Constants::COPY, [this]() { copy(); }, d->context)->action();
|
||||
d->pasteAction = registerCommand(Core::Constants::PASTE, [this]() { paste(); }, d->context)->action();
|
||||
d->undoAction = registerCommand(Core::Constants::UNDO, &ModelEditor::undo, d->context)->action();
|
||||
d->redoAction = registerCommand(Core::Constants::REDO, &ModelEditor::redo, d->context)->action();
|
||||
d->cutAction = registerCommand(Core::Constants::CUT, &ModelEditor::cut, d->context)->action();
|
||||
d->copyAction = registerCommand(Core::Constants::COPY, &ModelEditor::copy, d->context)->action();
|
||||
d->pasteAction = registerCommand(Core::Constants::PASTE, &ModelEditor::paste, d->context)->action();
|
||||
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);
|
||||
medit->addAction(removeCommand, Core::Constants::G_EDIT_COPYPASTE);
|
||||
d->removeAction = removeCommand->action();
|
||||
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"));
|
||||
medit->addAction(deleteCommand, Core::Constants::G_EDIT_COPYPASTE);
|
||||
d->deleteAction = deleteCommand->action();
|
||||
d->selectAllAction = registerCommand(Core::Constants::SELECTALL, [this]() { 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);
|
||||
d->selectAllAction = registerCommand(Core::Constants::SELECTALL, &ModelEditor::selectAll, d->context)->action();
|
||||
|
||||
Core::Command *exportDiagramCommand = registerCommand(
|
||||
Constants::EXPORT_DIAGRAM, [this]() { exportDiagram(); }, d->context, true,
|
||||
Constants::EXPORT_DIAGRAM, &ModelEditor::exportDiagram, d->context,
|
||||
tr("Export Diagram..."));
|
||||
menuModelEditor->addAction(exportDiagramCommand);
|
||||
exportDiagramCommand->setAttribute(Core::Command::CA_Hide);
|
||||
mfile->addAction(exportDiagramCommand, Core::Constants::G_FILE_EXPORT);
|
||||
d->exportDiagramAction = exportDiagramCommand->action();
|
||||
|
||||
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..."));
|
||||
menuModelEditor->addAction(exportSelectedElementsCommand);
|
||||
exportSelectedElementsCommand->setAttribute(Core::Command::CA_Hide);
|
||||
mfile->addAction(exportSelectedElementsCommand, Core::Constants::G_FILE_EXPORT);
|
||||
d->exportSelectedElementsAction = exportSelectedElementsCommand->action();
|
||||
|
||||
menuModelEditor->addSeparator(d->context);
|
||||
|
||||
Core::Command *zoomInCommand = registerCommand(
|
||||
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();
|
||||
registerCommand(Core::Constants::ZOOM_IN, &ModelEditor::zoomIn, d->context);
|
||||
registerCommand(Core::Constants::ZOOM_OUT, &ModelEditor::zoomOut, d->context);
|
||||
registerCommand(Core::Constants::ZOOM_RESET, &ModelEditor::resetZoom, d->context);
|
||||
|
||||
d->openParentDiagramAction = registerCommand(
|
||||
Constants::OPEN_PARENT_DIAGRAM, [this]() { openParentDiagram(); }, Core::Context(), true,
|
||||
tr("Open Parent Diagram"), QKeySequence("Ctrl+Shift+P"))->action();
|
||||
d->openParentDiagramAction->setIcon(QIcon(":/modeleditor/up.png"));
|
||||
registerCommand(Constants::ACTION_ADD_PACKAGE, nullptr, Core::Context(), true, tr("Add Package"));
|
||||
registerCommand(Constants::ACTION_ADD_COMPONENT, nullptr, Core::Context(), true, tr("Add Component"));
|
||||
registerCommand(Constants::ACTION_ADD_CLASS, nullptr, Core::Context(), true, tr("Add Class"));
|
||||
registerCommand(Constants::ACTION_ADD_CANVAS_DIAGRAM, nullptr, Core::Context(), true, tr("Add Canvas Diagram"));
|
||||
Constants::OPEN_PARENT_DIAGRAM, &ModelEditor::openParentDiagram, Core::Context(),
|
||||
tr("Open Parent Diagram"), QKeySequence("Ctrl+Shift+P"),
|
||||
QIcon(":/modeleditor/up.png"))->action();
|
||||
registerCommand(Constants::ACTION_ADD_PACKAGE, nullptr, Core::Context(), tr("Add Package"),
|
||||
QKeySequence(), QIcon(":/modelinglib/48x48/package.png"));
|
||||
registerCommand(Constants::ACTION_ADD_COMPONENT, nullptr, Core::Context(), tr("Add Component"),
|
||||
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(
|
||||
Constants::ACTION_SYNC_BROWSER, nullptr, Core::Context(), true,
|
||||
Constants::ACTION_SYNC_BROWSER, nullptr, Core::Context(),
|
||||
tr("Synchronize Browser and Diagram") + "<br><i><small>"
|
||||
+ tr("Press && Hold for options") + "</small></i>")->action();
|
||||
d->synchronizeBrowserAction->setIcon(Utils::Icons::LINK.icon());
|
||||
+ tr("Press && Hold for options") + "</small></i>", QKeySequence(),
|
||||
Utils::Icons::LINK.icon())->action();
|
||||
d->synchronizeBrowserAction->setCheckable(true);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
|
||||
@@ -313,51 +218,27 @@ void ActionHandler::onEditItem()
|
||||
editor->editSelectedItem();
|
||||
}
|
||||
|
||||
void ActionHandler::exportDiagram()
|
||||
std::function<void()> invokeOnCurrentModelEditor(void (ModelEditor::*function)())
|
||||
{
|
||||
return [function] {
|
||||
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
|
||||
if (editor)
|
||||
editor->exportDiagram(false);
|
||||
(editor->*function)();
|
||||
};
|
||||
}
|
||||
|
||||
void ActionHandler::exportSelectedElements()
|
||||
{
|
||||
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
|
||||
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)
|
||||
Core::Command *ActionHandler::registerCommand(const Core::Id &id, void (ModelEditor::*function)(),
|
||||
const Core::Context &context, const QString &title,
|
||||
const QKeySequence &keySequence, const QIcon &icon)
|
||||
{
|
||||
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())
|
||||
command->setDefaultKeySequence(keySequence);
|
||||
if (slot)
|
||||
connect(action, &QAction::triggered, this, slot);
|
||||
if (function)
|
||||
connect(action, &QAction::triggered, this, invokeOnCurrentModelEditor(function));
|
||||
return command;
|
||||
}
|
||||
|
||||
|
@@ -25,10 +25,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <coreplugin/icontext.h>
|
||||
|
||||
#include <QIcon>
|
||||
#include <QObject>
|
||||
|
||||
#include <functional>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -43,6 +44,8 @@ class Command;
|
||||
namespace ModelEditor {
|
||||
namespace Internal {
|
||||
|
||||
class ModelEditor;
|
||||
|
||||
class ActionHandler :
|
||||
public QObject
|
||||
{
|
||||
@@ -73,27 +76,13 @@ public:
|
||||
void createActions();
|
||||
|
||||
private:
|
||||
void undo();
|
||||
void redo();
|
||||
void cut();
|
||||
void copy();
|
||||
void paste();
|
||||
void removeSelectedElements();
|
||||
void deleteSelectedElements();
|
||||
void selectAll();
|
||||
void openParentDiagram();
|
||||
void onEditProperties();
|
||||
void onEditItem();
|
||||
void exportDiagram();
|
||||
void exportSelectedElements();
|
||||
void zoomIn();
|
||||
void zoomOut();
|
||||
void resetZoom();
|
||||
|
||||
Core::Command *registerCommand(const Core::Id &id, const std::function<void()> &slot,
|
||||
const Core::Context &context,
|
||||
bool scriptable = true, const QString &title = QString(),
|
||||
const QKeySequence &keySequence = QKeySequence());
|
||||
Core::Command *registerCommand(const Core::Id &id, void (ModelEditor::*function)(),
|
||||
const Core::Context &context, const QString &title = QString(),
|
||||
const QKeySequence &keySequence = QKeySequence(),
|
||||
const QIcon &icon = QIcon());
|
||||
|
||||
private:
|
||||
ActionHandlerPrivate *d;
|
||||
|
@@ -69,6 +69,8 @@
|
||||
#include "qmt/tasks/diagramscenecontroller.h"
|
||||
#include "qmt/tasks/finddiagramvisitor.h"
|
||||
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/minisplitter.h>
|
||||
@@ -323,22 +325,27 @@ void ModelEditor::init(QWidget *parent)
|
||||
toolbarLayout->addWidget(d->diagramSelector, 1);
|
||||
toolbarLayout->addStretch(1);
|
||||
|
||||
toolbarLayout->addWidget(
|
||||
createToolbarCommandButton(Constants::ACTION_ADD_PACKAGE, [this]() { onAddPackage(); },
|
||||
QIcon(":/modelinglib/48x48/package.png"),
|
||||
tr("Add Package"), d->toolbar));
|
||||
toolbarLayout->addWidget(
|
||||
createToolbarCommandButton(Constants::ACTION_ADD_COMPONENT, [this]() { onAddComponent(); },
|
||||
QIcon(":/modelinglib/48x48/component.png"),
|
||||
tr("Add Component"), d->toolbar));
|
||||
toolbarLayout->addWidget(
|
||||
createToolbarCommandButton(Constants::ACTION_ADD_CLASS, [this]() { onAddClass(); },
|
||||
QIcon(":/modelinglib/48x48/class.png"),
|
||||
tr("Add Class"), d->toolbar));
|
||||
toolbarLayout->addWidget(
|
||||
createToolbarCommandButton(Constants::ACTION_ADD_CANVAS_DIAGRAM, [this]() { onAddCanvasDiagram(); },
|
||||
QIcon(":/modelinglib/48x48/canvas-diagram.png"),
|
||||
tr("Add Canvas Diagram"), d->toolbar));
|
||||
toolbarLayout->addWidget(createToolbarCommandButton(Core::Constants::ZOOM_RESET,
|
||||
[this]() { resetZoom(); },
|
||||
d->toolbar));
|
||||
toolbarLayout->addWidget(createToolbarCommandButton(Core::Constants::ZOOM_IN,
|
||||
[this]() { zoomIn(); },
|
||||
d->toolbar));
|
||||
toolbarLayout->addWidget(createToolbarCommandButton(Core::Constants::ZOOM_OUT,
|
||||
[this]() { zoomOut(); },
|
||||
d->toolbar));
|
||||
toolbarLayout->addWidget(createToolbarCommandButton(Constants::ACTION_ADD_PACKAGE,
|
||||
[this]() { onAddPackage(); },
|
||||
d->toolbar));
|
||||
toolbarLayout->addWidget(createToolbarCommandButton(Constants::ACTION_ADD_COMPONENT,
|
||||
[this]() { onAddComponent(); },
|
||||
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);
|
||||
|
||||
auto syncToggleButton = new Core::CommandButton(Constants::ACTION_SYNC_BROWSER, d->toolbar);
|
||||
@@ -569,7 +576,17 @@ void ModelEditor::editSelectedItem()
|
||||
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();
|
||||
if (diagram) {
|
||||
@@ -797,18 +814,18 @@ void ModelEditor::expandModelTreeToDepth(int depth)
|
||||
d->modelTreeView->expandToDepth(depth);
|
||||
}
|
||||
|
||||
QToolButton *ModelEditor::createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
|
||||
const QIcon &icon, const QString &toolTipBase,
|
||||
QToolButton *ModelEditor::createToolbarCommandButton(const Core::Id &id,
|
||||
const std::function<void()> &slot,
|
||||
QWidget *parent)
|
||||
{
|
||||
auto button = new Core::CommandButton(id, parent);
|
||||
auto action = new QAction(button);
|
||||
action->setIcon(icon);
|
||||
action->setToolTip(toolTipBase);
|
||||
button->setDefaultAction(action);
|
||||
//button->setIcon(icon);
|
||||
//button->setToolTipBase(toolTipBase);
|
||||
connect(button, &Core::CommandButton::clicked, this, slot);
|
||||
Core::Command *command = Core::ActionManager::command(id);
|
||||
QTC_CHECK(command);
|
||||
const QString text = command ? command->description() : QString();
|
||||
auto action = new QAction(text, this);
|
||||
action->setIcon(command ? command->action()->icon() : QIcon());
|
||||
auto button = Core::Command::toolButtonWithAppendedShortcut(action, command);
|
||||
button->setParent(parent);
|
||||
connect(button, &QToolButton::clicked, this, slot);
|
||||
return button;
|
||||
}
|
||||
|
||||
|
@@ -87,7 +87,8 @@ public:
|
||||
void openParentDiagram();
|
||||
void editProperties();
|
||||
void editSelectedItem();
|
||||
void exportDiagram(bool selectedElements);
|
||||
void exportDiagram();
|
||||
void exportSelectedElements();
|
||||
void zoomIn();
|
||||
void zoomOut();
|
||||
void resetZoom();
|
||||
@@ -103,9 +104,9 @@ private:
|
||||
void showProperties(qmt::MDiagram *diagram, const QList<qmt::DElement *> &diagramElements);
|
||||
void clearProperties();
|
||||
void expandModelTreeToDepth(int depth);
|
||||
QToolButton *createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
|
||||
const QIcon &icon,
|
||||
const QString &toolTipBase, QWidget *parent);
|
||||
QToolButton *createToolbarCommandButton(const Core::Id &id,
|
||||
const std::function<void()> &slot,
|
||||
QWidget *parent);
|
||||
bool updateButtonIconByTheme(QAbstractButton *button, const QString &name);
|
||||
void showZoomIndicator();
|
||||
|
||||
@@ -158,6 +159,8 @@ private:
|
||||
void synchronizeDiagramWithBrowser();
|
||||
void synchronizeBrowserWithDiagram(const qmt::MDiagram *diagram);
|
||||
|
||||
void exportToImage(bool selectedElements);
|
||||
|
||||
private:
|
||||
ModelEditorPrivate *d;
|
||||
};
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace ModelEditor {
|
||||
namespace Constants {
|
||||
|
||||
@@ -37,9 +39,6 @@ const char OPEN_PARENT_DIAGRAM[] = "ModelEditor.OpenParentDiagram";
|
||||
const char MENU_ID[] = "ModelEditor.Menu";
|
||||
const char EXPORT_DIAGRAM[] = "ModelEditor.ExportDiagram";
|
||||
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_COMPONENT[] = "ModelEditor.Action.AddComponent";
|
||||
const char ACTION_ADD_CLASS[] = "ModelEditor.Action.AddClass";
|
||||
|
@@ -54,40 +54,6 @@ namespace Internal {
|
||||
|
||||
#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)
|
||||
: DeviceProcessList(device, parent)
|
||||
, m_myPid(GetCurrentProcessId())
|
||||
@@ -108,7 +74,7 @@ QList<DeviceProcessItem> LocalProcessList::getLocalProcesses()
|
||||
DeviceProcessItem p;
|
||||
p.pid = pe.th32ProcessID;
|
||||
// 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() ?
|
||||
QString::fromWCharArray(pe.szExeFile) :
|
||||
image;
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import qbs 1.0
|
||||
import qbs.File
|
||||
import qbs.FileInfo
|
||||
|
||||
QtcPlugin {
|
||||
name: "QbsProjectManager"
|
||||
type: base.concat(["qmltype-update"])
|
||||
|
||||
property var externalQbsIncludes: project.useExternalQbs
|
||||
? [project.qbs_install_dir + "/include/qbs"] : []
|
||||
@@ -116,5 +118,42 @@ QtcPlugin {
|
||||
"qbsrunconfiguration.cpp",
|
||||
"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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -51,7 +51,11 @@ static const char ANDROID_RC_ID_PREFIX[] = "Qt4ProjectManager.AndroidRunConfigur
|
||||
|
||||
QmakeAndroidRunConfiguration::QmakeAndroidRunConfiguration(Target *target)
|
||||
: AndroidRunConfiguration(target, ANDROID_RC_ID_PREFIX)
|
||||
{}
|
||||
{
|
||||
connect(target->project(), &Project::parsingFinished, this, [this]() {
|
||||
updateDisplayName();
|
||||
});
|
||||
}
|
||||
|
||||
QString QmakeAndroidRunConfiguration::extraId() const
|
||||
{
|
||||
@@ -72,7 +76,6 @@ bool QmakeAndroidRunConfiguration::fromMap(const QVariantMap &map)
|
||||
if (!extraId.isEmpty())
|
||||
m_proFilePath = Utils::FileName::fromString(extraId);
|
||||
|
||||
setDefaultDisplayName(defaultDisplayName());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,17 +89,15 @@ QVariantMap QmakeAndroidRunConfiguration::toMap() const
|
||||
return map;
|
||||
}
|
||||
|
||||
QString QmakeAndroidRunConfiguration::defaultDisplayName()
|
||||
void QmakeAndroidRunConfiguration::updateDisplayName()
|
||||
{
|
||||
QmakeProject *project = qmakeProject();
|
||||
const QmakeProjectManager::QmakeProFileNode *root = project->rootProjectNode();
|
||||
if (root) {
|
||||
const QmakeProjectManager::QmakeProFileNode *node = root->findProFileFor(m_proFilePath);
|
||||
if (node) // should always be found
|
||||
return node->displayName();
|
||||
setDefaultDisplayName(node->displayName());
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString QmakeAndroidRunConfiguration::disabledReason() const
|
||||
|
@@ -49,7 +49,7 @@ private:
|
||||
QString extraId() const final;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
QString defaultDisplayName();
|
||||
void updateDisplayName();
|
||||
|
||||
QmakeProjectManager::QmakeProject *qmakeProject() const;
|
||||
|
||||
|
@@ -416,7 +416,7 @@ void ItemLibraryWidget::addResources()
|
||||
|
||||
if (!fileNames.isEmpty()) {
|
||||
const auto directory = QFileDialog::getExistingDirectory(this,
|
||||
tr("Target Direcotry"),
|
||||
tr("Target Directory"),
|
||||
document->fileName().parentDir().toString());
|
||||
|
||||
for (const QString &fileName : fileNames) {
|
||||
@@ -425,7 +425,7 @@ void ItemLibraryWidget::addResources()
|
||||
postfix.remove(0, 1);
|
||||
if (fileName.endsWith(postfix))
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,19 +25,23 @@
|
||||
|
||||
#include "navigatorwidget.h"
|
||||
#include "navigatorview.h"
|
||||
#include "qmldesignerconstants.h"
|
||||
#include "qmldesignericons.h"
|
||||
|
||||
#include <designersettings.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <qmldesignericons.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <theme.h>
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QToolButton>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QMenu>
|
||||
#include <QBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QtDebug>
|
||||
#include <QMenu>
|
||||
#include <QStackedWidget>
|
||||
#include <QToolButton>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/utilsicons.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
@@ -54,18 +58,43 @@ NavigatorWidget::NavigatorWidget(NavigatorView *view) :
|
||||
m_treeView->setDefaultDropAction(Qt::LinkAction);
|
||||
m_treeView->setHeaderHidden(true);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
auto layout = new QVBoxLayout;
|
||||
layout->setSpacing(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);
|
||||
|
||||
setWindowTitle(tr("Navigator", "Title of navigator view"));
|
||||
|
||||
#ifndef QMLDESIGNER_TEST
|
||||
setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/stylesheet.css")))));
|
||||
m_treeView->setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css")))));
|
||||
setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
|
||||
m_treeView->setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css"))));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -72,6 +72,12 @@ const char SB_PROJECTS[] = "Projects";
|
||||
const char SB_FILESYSTEM[] = "FileSystem";
|
||||
const char SB_OPENDOCUMENTS[] = "OpenDocuments";
|
||||
|
||||
static void hideToolButtons(QList<QToolButton*> &buttons)
|
||||
{
|
||||
foreach (QToolButton *button, buttons)
|
||||
button->hide();
|
||||
}
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
@@ -169,6 +175,32 @@ void DesignModeWidget::toggleRightSidebar()
|
||||
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()
|
||||
{
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
@@ -221,12 +253,6 @@ void DesignModeWidget::switchTextOrForm()
|
||||
m_centralTabWidget->switchTo(viewManager().widget("TextEditor"));
|
||||
}
|
||||
|
||||
static void hideToolButtons(QList<QToolButton*> &buttons)
|
||||
{
|
||||
foreach (QToolButton *button, buttons)
|
||||
button->hide();
|
||||
}
|
||||
|
||||
void DesignModeWidget::setup()
|
||||
{
|
||||
auto &actionManager = viewManager().designerActionManager();
|
||||
|
@@ -85,6 +85,8 @@ public:
|
||||
void toggleLeftSidebar();
|
||||
void toggleRightSidebar();
|
||||
|
||||
static QWidget *createProjectExplorerWidget(QWidget *parent);
|
||||
|
||||
private: // functions
|
||||
enum InitializeStatus { NotInitialized, Initializing, Initialized };
|
||||
|
||||
|
@@ -34,6 +34,9 @@
|
||||
#include "dynamicpropertiesmodel.h"
|
||||
#include "theme.h"
|
||||
|
||||
#include <designersettings.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <utils/fileutils.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("Bindings", "Title of connection view"));
|
||||
ui->tabBar->addTab(tr("Properties", "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);
|
||||
|
||||
const QString themedScrollBarCss = Theme::replaceCssColors(
|
||||
|
@@ -455,6 +455,11 @@ Internal::DesignModeWidget *QmlDesignerPlugin::mainWidget() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QWidget *QmlDesignerPlugin::createProjectExplorerWidget(QWidget *parent) const
|
||||
{
|
||||
return Internal::DesignModeWidget::createProjectExplorerWidget(parent);
|
||||
}
|
||||
|
||||
void QmlDesignerPlugin::switchToTextModeDeferred()
|
||||
{
|
||||
QTimer::singleShot(0, this, [] () {
|
||||
|
@@ -82,6 +82,8 @@ public:
|
||||
DesignDocument *currentDesignDocument() const;
|
||||
Internal::DesignModeWidget *mainWidget() const;
|
||||
|
||||
QWidget *createProjectExplorerWidget(QWidget *parent) const;
|
||||
|
||||
void switchToTextModeDeferred();
|
||||
void emitCurrentTextEditorChanged(Core::IEditor *editor);
|
||||
|
||||
|
@@ -47,6 +47,28 @@
|
||||
namespace QmlProfiler {
|
||||
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 {
|
||||
Colors () : noteBackground(QColor("orange")), defaultBackground(QColor("white")) {}
|
||||
QColor noteBackground;
|
||||
@@ -374,7 +396,6 @@ public:
|
||||
QList<bool> m_fieldShown;
|
||||
QHash<int, int> m_columnIndex; // maps field enum to column index
|
||||
bool m_showExtendedStatistics;
|
||||
int m_firstNumericColumn;
|
||||
};
|
||||
|
||||
QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(
|
||||
@@ -384,8 +405,6 @@ QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(
|
||||
setViewDefaults(this);
|
||||
setObjectName(QLatin1String("QmlProfilerEventsTable"));
|
||||
|
||||
setSortingEnabled(false);
|
||||
|
||||
d->m_model = new QStandardItemModel(this);
|
||||
d->m_model->setSortRole(SortRole);
|
||||
setModel(d->m_model);
|
||||
@@ -396,7 +415,6 @@ QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(
|
||||
this, &QmlProfilerStatisticsMainView::buildModel);
|
||||
connect(d->model, &QmlProfilerStatisticsModel::notesAvailable,
|
||||
this, &QmlProfilerStatisticsMainView::updateNotes);
|
||||
d->m_firstNumericColumn = 0;
|
||||
d->m_showExtendedStatistics = false;
|
||||
|
||||
setFieldViewable(Name, true);
|
||||
@@ -412,6 +430,9 @@ QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(
|
||||
setFieldViewable(MedianTime, true);
|
||||
setFieldViewable(Details, true);
|
||||
|
||||
setSortingEnabled(true);
|
||||
sortByColumn(DEFAULT_SORT_COLUMN, Qt::DescendingOrder);
|
||||
|
||||
buildModel();
|
||||
}
|
||||
|
||||
@@ -438,18 +459,15 @@ void QmlProfilerStatisticsMainView::setFieldViewable(Fields field, bool show)
|
||||
void QmlProfilerStatisticsMainView::setHeaderLabels()
|
||||
{
|
||||
int fieldIndex = 0;
|
||||
d->m_firstNumericColumn = 0;
|
||||
|
||||
d->m_columnIndex.clear();
|
||||
if (d->m_fieldShown[Name]) {
|
||||
d->m_columnIndex[Name] = fieldIndex;
|
||||
d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Location)));
|
||||
d->m_firstNumericColumn++;
|
||||
}
|
||||
if (d->m_fieldShown[Type]) {
|
||||
d->m_columnIndex[Type] = fieldIndex;
|
||||
d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Type)));
|
||||
d->m_firstNumericColumn++;
|
||||
}
|
||||
if (d->m_fieldShown[TimeInPercent]) {
|
||||
d->m_columnIndex[TimeInPercent] = fieldIndex;
|
||||
@@ -521,11 +539,10 @@ bool QmlProfilerStatisticsMainView::showExtendedStatistics() const
|
||||
|
||||
void QmlProfilerStatisticsMainView::clear()
|
||||
{
|
||||
SortPreserver sorter(this);
|
||||
d->m_model->clear();
|
||||
d->m_model->setColumnCount(d->getFieldCount());
|
||||
|
||||
setHeaderLabels();
|
||||
setSortingEnabled(false);
|
||||
}
|
||||
|
||||
int QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainViewPrivate::getFieldCount()
|
||||
@@ -540,12 +557,13 @@ int QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainViewPrivate::getFiel
|
||||
void QmlProfilerStatisticsMainView::buildModel()
|
||||
{
|
||||
clear();
|
||||
|
||||
{
|
||||
SortPreserver sorter(this);
|
||||
parseModel();
|
||||
setShowExtendedStatistics(d->m_showExtendedStatistics);
|
||||
|
||||
setRootIsDecorated(false);
|
||||
setSortingEnabled(true);
|
||||
sortByColumn(d->m_firstNumericColumn,Qt::DescendingOrder);
|
||||
}
|
||||
|
||||
expandAll();
|
||||
if (d->m_fieldShown[Name])
|
||||
@@ -839,7 +857,6 @@ QmlProfilerStatisticsRelativesView::QmlProfilerStatisticsRelativesView(
|
||||
Utils::TreeView(parent), d(new QmlProfilerStatisticsRelativesViewPrivate(this))
|
||||
{
|
||||
setViewDefaults(this);
|
||||
setSortingEnabled(false);
|
||||
d->model = model;
|
||||
QStandardItemModel *itemModel = new QStandardItemModel(this);
|
||||
itemModel->setSortRole(SortRole);
|
||||
@@ -847,6 +864,9 @@ QmlProfilerStatisticsRelativesView::QmlProfilerStatisticsRelativesView(
|
||||
setRootIsDecorated(false);
|
||||
updateHeader();
|
||||
|
||||
setSortingEnabled(true);
|
||||
sortByColumn(DEFAULT_SORT_COLUMN, Qt::DescendingOrder);
|
||||
|
||||
connect(this, &QAbstractItemView::activated,
|
||||
this, &QmlProfilerStatisticsRelativesView::jumpToItem);
|
||||
|
||||
@@ -862,12 +882,11 @@ QmlProfilerStatisticsRelativesView::~QmlProfilerStatisticsRelativesView()
|
||||
|
||||
void QmlProfilerStatisticsRelativesView::displayType(int typeIndex)
|
||||
{
|
||||
SortPreserver sorter(this);
|
||||
rebuildTree(d->model->getData(typeIndex));
|
||||
|
||||
updateHeader();
|
||||
resizeColumnToContents(0);
|
||||
setSortingEnabled(true);
|
||||
sortByColumn(2);
|
||||
}
|
||||
|
||||
void QmlProfilerStatisticsRelativesView::rebuildTree(
|
||||
@@ -929,6 +948,7 @@ void QmlProfilerStatisticsRelativesView::rebuildTree(
|
||||
void QmlProfilerStatisticsRelativesView::clear()
|
||||
{
|
||||
if (treeModel()) {
|
||||
SortPreserver sorter(this);
|
||||
treeModel()->clear();
|
||||
updateHeader();
|
||||
}
|
||||
|
@@ -127,6 +127,13 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FileName &fi
|
||||
OtherFileFilterItem *otherFileFilterItem = new OtherFileFilterItem(projectItem);
|
||||
setupFileFilterItem(otherFileFilterItem, childNode);
|
||||
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 {
|
||||
qWarning() << "Unknown type:" << childNode->name();
|
||||
}
|
||||
|
@@ -106,4 +106,14 @@ bool QmlProjectItem::matchesFile(const QString &filePath) const
|
||||
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
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QStringList>
|
||||
@@ -60,6 +62,9 @@ public:
|
||||
|
||||
void appendContent(QmlProjectContentItem *item) { m_content.append(item); }
|
||||
|
||||
QList<Utils::EnvironmentItem> environment() const;
|
||||
void addToEnviroment(const QString &key, const QString &value);
|
||||
|
||||
signals:
|
||||
void qmlFilesChanged(const QSet<QString> &, const QSet<QString> &);
|
||||
|
||||
@@ -69,6 +74,7 @@ protected:
|
||||
QStringList m_importPaths;
|
||||
QStringList m_absoluteImportPaths;
|
||||
QString m_mainFile;
|
||||
QList<Utils::EnvironmentItem> m_environment;
|
||||
QList<QmlProjectContentItem *> m_content; // content property
|
||||
};
|
||||
|
||||
|