forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.6'
Change-Id: Iddfa0d2f3c0fb8ba65c0e5d479ad8e2f2cb95685
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -196,6 +196,7 @@ tmp/
|
||||
/tests/auto/treeviewfind/tst_treeviewfind
|
||||
/tests/auto/utils/ansiescapecodehandler/tst_ansiescapecodehandler
|
||||
/tests/auto/utils/fileutils/tst_fileutils
|
||||
/tests/auto/utils/templateengine/tst_templateengine
|
||||
/tests/auto/utils_stringutils/tst_utils_stringutils
|
||||
/tests/auto/valgrind/callgrind/tst_callgrindparsertests
|
||||
/tests/auto/valgrind/memcheck/modeldemo
|
||||
|
||||
127
dist/changes-3.6.0.md
vendored
Normal file
127
dist/changes-3.6.0.md
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
Qt Creator version 3.6 contains bug fixes and new features.
|
||||
|
||||
The most important changes are listed in this document. For a complete
|
||||
list of changes, see the Git log for the Qt Creator sources that
|
||||
you can check out from the public Git repository. For example:
|
||||
|
||||
git clone git://code.qt.io/qt-creator/qt-creator.git
|
||||
git log --cherry-pick --pretty=oneline origin/3.5..origin/3.6
|
||||
|
||||
General
|
||||
|
||||
* Added text zoom in application and compile output (QTCREATORBUG-12476)
|
||||
* Fixed that context help was shown for current keyboard focus widget, even when
|
||||
a tool tip with help icon was visible (QTCREATORBUG-5345)
|
||||
|
||||
Editing
|
||||
|
||||
* Added experimental editor for UML-like diagrams (`ModelEditor` plugin)
|
||||
* Made it possible to use Qt Creator variables in snippets
|
||||
* Fixed indentation in block selection mode (QTCREATORBUG-12697)
|
||||
* Fixed that Qt Creator tried to write auto-save files in read-only
|
||||
directories
|
||||
* Fixed possible crash with code completion (QTCREATORBUG-14875)
|
||||
|
||||
Project Management
|
||||
|
||||
* Added actions for building without dependencies and for rebuilding
|
||||
and cleaning with dependencies to context menu of project tree
|
||||
(QTCREATORBUG-14606)
|
||||
* Added option to synchronize kits between all projects in a session
|
||||
(QTCREATORBUG-5823)
|
||||
|
||||
QMake Projects
|
||||
|
||||
* Changed project display names to be `QMAKE_PROJECT_NAME` if set
|
||||
(QTCREATORBUG-13950)
|
||||
* Fixed that `.pri` files were shown in flat list instead of tree
|
||||
(QTCREATORBUG-487)
|
||||
* Fixed that `QMAKE_EXT_H` was ignored for UI code model (QTCREATORBUG-14910)
|
||||
* Fixed that `make` build step was not updated on environment changes
|
||||
(QTCREATORBUG-14831)
|
||||
|
||||
CMake Projects
|
||||
|
||||
* Improved handling of projects with CMake errors (QTCREATORBUG-6903)
|
||||
* Added option for `Debug`, `Release`, `ReleaseWithDebugInfo` and
|
||||
`MinSizeRelease` build types (QTCREATORBUG-12219)
|
||||
* Added auto-indent and parentheses and quote matching to CMake editor
|
||||
|
||||
C++ Support
|
||||
|
||||
* Added support for `noexcept`
|
||||
* Clang code model
|
||||
* Added diagnostic messages to editors
|
||||
* Added Clang's Fix-its to refactoring actions (QTCREATORBUG-14868)
|
||||
|
||||
Debugging
|
||||
|
||||
* Made sub-registers editable
|
||||
* Fixed breakpoint removal from disassembler view (QTCREATORBUG-14973)
|
||||
* CDB
|
||||
* Fixed auto-detection of CDB from Windows 10 Kits
|
||||
* LLDB
|
||||
* Fixed handling of large registers
|
||||
* QML/JS Console
|
||||
* Implemented lazy loading of sub-items
|
||||
* Improved error reporting
|
||||
|
||||
Analyzer
|
||||
|
||||
* Improved diagnostics view to use tree view instead of list
|
||||
|
||||
QML Profiler
|
||||
|
||||
* Improved performance of timeline view (QTCREATORBUG-14983)
|
||||
|
||||
Qt Quick Designer
|
||||
|
||||
* Made Qt Quick Designer aware of QRC files in project
|
||||
* Improved selection behavior with regard to z-order in form editor
|
||||
(QTCREATORBUG-11703)
|
||||
* Added `Go to Implementation` action from `.ui.qml` file to its
|
||||
associated `.qml` file
|
||||
* Added connection editor and path editor
|
||||
|
||||
Version Control Systems
|
||||
|
||||
* Subversion
|
||||
* Fixed encoding issues for commit message (QTCREATORBUG-14965)
|
||||
* Perforce
|
||||
* Fixed showing differences of files in submit editor when using
|
||||
P4CONFIG (QTCREATORBUG-14538)
|
||||
|
||||
TODO
|
||||
|
||||
* Added option to show TODOs only for current sub-project
|
||||
|
||||
Platform Specific
|
||||
|
||||
Windows
|
||||
|
||||
* Fixed detection of `cygwin` ABIs
|
||||
|
||||
OS X
|
||||
|
||||
* Added option for file system case-sensitivity and made it case-insensitive by
|
||||
default (QTCREATORBUG-13507)
|
||||
* Added option to set `DYLD_LIBRARY_PATH` and `DYLD_FRAMEWORK_PATH` in
|
||||
run configurations (QTCREATORBUG-14022)
|
||||
|
||||
Android
|
||||
|
||||
* Fixed that QML syntax errors where not clickable in application output
|
||||
(QTCREATORBUG-14832)
|
||||
* Fixed deployment on devices without `readlink` (QTCREATORBUG-15006)
|
||||
* Fixed debugging of signed applications (requires Qt 5.6) (QTCREATORBUG-13035)
|
||||
|
||||
iOS
|
||||
|
||||
* Improved error messages for deployment
|
||||
|
||||
Remote Linux
|
||||
|
||||
* Added support for ECDSA public keys with 384 and 521 bits,
|
||||
ECDSA user keys, and ECDSA key creation
|
||||
* Fixed environment and working directory for Valgrind analyzer
|
||||
|
||||
@@ -47,6 +47,15 @@ Component.prototype.loaded = function()
|
||||
}
|
||||
}
|
||||
|
||||
Component.prototype.createOperationsForArchive = function(archive)
|
||||
{
|
||||
// if there are additional plugin 7zips, these must be extracted in .app/Contents on OS X
|
||||
if (systemInfo.productType !== "osx" || archive.indexOf('qtcreator.7z') !== -1)
|
||||
component.addOperation("Extract", archive, "@TargetDir@");
|
||||
else
|
||||
component.addOperation("Extract", archive, "@TargetDir@/Qt Creator.app/Contents");
|
||||
}
|
||||
|
||||
Component.prototype.beginInstallation = function()
|
||||
{
|
||||
component.qtCreatorBinaryPath = installer.value("TargetDir");
|
||||
|
||||
4
dist/installer/mac/qmldesigner_qt.conf
vendored
Normal file
4
dist/installer/mac/qmldesigner_qt.conf
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[Paths]
|
||||
Imports = ../../Imports/qtquick1
|
||||
Qml2Imports = ../../Imports/qtquick2
|
||||
Plugins = ../../PlugIns
|
||||
BIN
doc/images/qtcreator-modeleditor-classes.png
Normal file
BIN
doc/images/qtcreator-modeleditor-classes.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
BIN
doc/images/qtcreator-modeleditor-packages.png
Normal file
BIN
doc/images/qtcreator-modeleditor-packages.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
doc/images/qtcreator-modeleditor.png
Normal file
BIN
doc/images/qtcreator-modeleditor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
doc/images/qtcreator-options-cpp-files.png
Normal file
BIN
doc/images/qtcreator-options-cpp-files.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
@@ -50,11 +50,15 @@
|
||||
|
||||
\section1 Setting Up Clang Static Analyzer
|
||||
|
||||
You must have Clang installed to use the Clang Static Analyzer. On Windows,
|
||||
Clang version 3.6, or later, is required to use the MSVC tool chain.
|
||||
As a tested version of Clang is shipped together with Qt Creator, no manual
|
||||
setup is required.
|
||||
|
||||
To set up the Clang Static Analyzer, select \uicontrol Tools >
|
||||
\uicontrol Options > \uicontrol Analyzer >
|
||||
To profit from improved checkers in newer Clang versions, \QC can be set up
|
||||
to use those. However, only the shipped version of Clang is tested and known
|
||||
to work. Other versions might not work at all.
|
||||
|
||||
To set up a particular Clang version for the Clang Static Analyzer, select
|
||||
\uicontrol Tools > \uicontrol Options > \uicontrol Analyzer >
|
||||
\uicontrol {Clang Static Analyzer} and check that the path to the Clang
|
||||
executable is set correctly in the \uicontrol {Clang executable} field.
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-usability.html
|
||||
\page creator-coding.html
|
||||
\nextpage creator-editor-functions.html
|
||||
\nextpage creator-modeling.html
|
||||
|
||||
\title Coding
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
|
||||
\list
|
||||
|
||||
\li \l{Modeling}
|
||||
|
||||
You can use the experimental model editor to create Universal
|
||||
Modeling Language (UML) style models with structured diagrams and
|
||||
store them in XML format.
|
||||
|
||||
\li \l{Writing Code}
|
||||
|
||||
Writing, editing, and navigating in source code are core tasks in
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
/*!
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-coding.html
|
||||
\previouspage creator-modeling.html
|
||||
\page creator-editor-functions.html
|
||||
\nextpage creator-coding-navigating.html
|
||||
|
||||
|
||||
@@ -895,7 +895,8 @@
|
||||
snippet, select \uicontrol Add. Specify a trigger and, if the trigger is
|
||||
already in use, an optional variant, which appear in the list of suggestions
|
||||
when you write code. Also specify a text string or C++ or QML code construct
|
||||
in the snippet editor, depending on the snippet category.
|
||||
in the snippet editor, depending on the snippet category. You can use
|
||||
\l{Using Qt Creator Variables}{predefined variables} in snippets.
|
||||
|
||||
The snippet editor provides you with:
|
||||
|
||||
@@ -913,7 +914,18 @@
|
||||
|
||||
Specify the variables for the snippets in the following format:
|
||||
|
||||
\c $variable$
|
||||
\code
|
||||
$variable$
|
||||
\endcode
|
||||
|
||||
Specify \QC variables in the following format:
|
||||
|
||||
\code
|
||||
%{variable}
|
||||
\endcode
|
||||
|
||||
For example, the following variable expands to the name of the current
|
||||
project: \c {%{CurrentProject:Name}}.
|
||||
|
||||
Use unique variable names within a snippet, because all instances of a
|
||||
variable are renamed when you specify a value for it.
|
||||
|
||||
327
doc/src/editors/creator-modeling.qdoc
Normal file
327
doc/src/editors/creator-modeling.qdoc
Normal file
@@ -0,0 +1,327 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
**
|
||||
** GNU Free Documentation License
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of this
|
||||
** file.
|
||||
**
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
// **********************************************************************
|
||||
// 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-coding.html
|
||||
\page creator-modeling.html
|
||||
\nextpage creator-editor-functions.html
|
||||
|
||||
\title Modeling
|
||||
|
||||
You can use the experimental model editor to create Universal Modeling
|
||||
Language (UML) style models with structured diagrams. However, the editor
|
||||
uses a variant of UML and only a subset of properties are provided for
|
||||
specifying the appearance of model elements.
|
||||
|
||||
You can create the following types of diagrams:
|
||||
|
||||
\list
|
||||
\li Package
|
||||
\li Class
|
||||
\li Component
|
||||
\li Use case
|
||||
\li Activity
|
||||
\endlist
|
||||
|
||||
You can add elements to the diagrams and specify properties for them. You
|
||||
can either use standard model elements or add your own elements with custom
|
||||
icons.
|
||||
|
||||
\image qtcreator-modeleditor.png
|
||||
|
||||
You can add model elements to diagrams in the following ways:
|
||||
|
||||
\list
|
||||
\li Drag and drop model elements from the element tool bar (1) to the
|
||||
editor (2).
|
||||
\li Select tool bar buttons (3) to add elements to the element tree (4).
|
||||
\li Drag elements from the element tree to the editor to add them and
|
||||
all their relations to the diagram.
|
||||
\li Drag and drop source files from \uicontrol Projects to the editor
|
||||
to add C++ classes or components to a class or component diagram.
|
||||
\endlist
|
||||
|
||||
You can group elements by surrounding them with a boundary. When you move
|
||||
the boundary, all elements within it are moved together. Similarly, classes
|
||||
that you lay on packages are moved with the packages. You can move
|
||||
individual elements and modify their properties (5) by selecting them. You
|
||||
can also use \e multiselection to group elements temporarily.
|
||||
|
||||
Drag the mouse over elements to select them and apply actions such as
|
||||
changing their \e stereotype or color. A stereotype is a classifier for
|
||||
elements, such as \e entity, \e control, \e interface, or \e boundary. An
|
||||
entity is usually a class that is used to store data. For some stereotypes,
|
||||
a custom icon is defined. You can assign several comma-separated stereotypes
|
||||
to one element.
|
||||
|
||||
To print diagrams, press \key Ctrl+C when no elements are selected in
|
||||
the editor to copy all elements to the clipboard by using 300 dpi. Then
|
||||
paste the diagram to an application that can print images.
|
||||
|
||||
\section1 Creating Models
|
||||
|
||||
To create models:
|
||||
|
||||
\list 1
|
||||
|
||||
\li Select \uicontrol Help > \uicontrol {About Plugins} >
|
||||
\uicontrol Modeling > \uicontrol ModelEditor and restart \QC to
|
||||
enable the plugin.
|
||||
|
||||
\li Select \uicontrol File > \uicontrol {New File or Project} >
|
||||
\uicontrol Modeling > \uicontrol Model > \uicontrol Choose to
|
||||
create a model.
|
||||
|
||||
\li Drag and drop model elements to the editor and select them to
|
||||
specify properties for them:
|
||||
|
||||
\list 1
|
||||
|
||||
\li In the \uicontrol Stereotypes field, enter the stereotype to
|
||||
apply to the model element or select a predefined stereotype
|
||||
from the list.
|
||||
|
||||
\li In the \uicontrol Name field, give a name to the model element.
|
||||
|
||||
\li Select the \uicontrol {Auto sized} check box to reset the
|
||||
element to its default size after you have changed the element
|
||||
size by dragging its borders.
|
||||
|
||||
\li In the \uicontrol Color field, select the color of the model
|
||||
element.
|
||||
|
||||
\li In the \uicontrol Role field, select a \e role to make the model
|
||||
element color lighter, darker, or softer or to remove color and
|
||||
draw the element outline.
|
||||
|
||||
\li Select the \uicontrol Emphasized check box to draw the model
|
||||
element with a thicker line.
|
||||
|
||||
\li In the \uicontrol {Stereotype display} field, select:
|
||||
|
||||
\list
|
||||
|
||||
\li \uicontrol Smart to display the stereotype as a
|
||||
\uicontrol Label, a \uicontrol Decoration, or an
|
||||
\uicontrol Icon, depending on the properties of the
|
||||
element. For example, if a class has the stereotype
|
||||
\uicontrol interface, it is displayed as an icon until
|
||||
it becomes displayed members, after which it is
|
||||
displayed as a decoration.
|
||||
|
||||
\li \uicontrol None to suppress the displaying of the
|
||||
stereotype.
|
||||
|
||||
\li \uicontrol Label to display the stereotype as a line of
|
||||
text using the standard form above the element name
|
||||
even if the stereotype defines a custom icon.
|
||||
|
||||
\li \uicontrol Decoration to show the standard form of the
|
||||
element with the stereotype as a small icon placed top
|
||||
right if the stereotype defines a custom icon.
|
||||
|
||||
\li \uicontrol Icon to display the element using the custom
|
||||
icon.
|
||||
|
||||
\endlist
|
||||
|
||||
\endlist
|
||||
|
||||
\li To create a relation between two elements, select the arrow icon
|
||||
next to an element and drag it to the end point of the relation.
|
||||
|
||||
\li Select the relation to specify settings for it, according to its
|
||||
type: inheritance, association, or dependency. You can specify the
|
||||
following settings for dependency relations, which are available for
|
||||
all element types:
|
||||
|
||||
\list 1
|
||||
|
||||
\li In the \uicontrol Stereotypes field, select the
|
||||
\e stereotype to apply to the relation.
|
||||
|
||||
\li In the \uicontrol Name field, give a name to the relation.
|
||||
|
||||
\li In the \uicontrol Direction field, you can change the direction
|
||||
of the connection or make it bidirectional.
|
||||
|
||||
\endlist
|
||||
|
||||
\li To create \e {sampling points} that divide a relation into two
|
||||
connected lines, select a relation and press \key Shift+Click.
|
||||
If possible, the end point of a relation is moved automatically to
|
||||
draw the line to the next sampling point either vertically or
|
||||
horizontally. To remove the selected sampling point, press
|
||||
\key Ctrl+Click.
|
||||
|
||||
\li To group elements, drag and drop a \uicontrol Boundary element to
|
||||
the editor and resize it to enclose the elements in the group.
|
||||
|
||||
\endlist
|
||||
|
||||
\section1 Creating Package Diagrams
|
||||
|
||||
You can add nested package elements to a package diagram. The depth of the
|
||||
elements in the diagram corresponds to the depth of the structured model.
|
||||
Elements stacked on other elements of the same type are automatically drawn
|
||||
in a darker shade of the selected color.
|
||||
|
||||
\image qtcreator-modeleditor-packages.png
|
||||
|
||||
\section1 Creating Class Diagrams
|
||||
|
||||
\image qtcreator-modeleditor-classes.png
|
||||
|
||||
To create class diagrams:
|
||||
|
||||
\list 1
|
||||
|
||||
\li To add C++ classes to class diagrams, drag and drop files from
|
||||
\uicontrol Projects to the editor, and select
|
||||
\uicontrol {Add Class}.
|
||||
|
||||
\li In addition to the common element properties, you can specify the
|
||||
following properties:
|
||||
|
||||
\list
|
||||
|
||||
\li In the \uicontrol Template field, specify the template to
|
||||
use.
|
||||
|
||||
\li In the \uicontrol {Template display} field, select the
|
||||
display format for the template:
|
||||
|
||||
\list
|
||||
|
||||
\li \uicontrol Smart displays the template as
|
||||
\uicontrol Box or \uicontrol {Angle brackets},
|
||||
depending on the class properties.
|
||||
|
||||
\li \uicontrol Box displays the template in a small box
|
||||
with a dotted border in the top right corner of the
|
||||
class icon.
|
||||
|
||||
\li \uicontrol {Angle brackets} writes the template
|
||||
in angle brackets behind the class name using the
|
||||
C++ syntax.
|
||||
|
||||
\endlist
|
||||
|
||||
\li In the \uicontrol Members field, specify members for the
|
||||
class. Enter each member on a separate line using a C++
|
||||
like syntax. For example, the following lines define the
|
||||
method \c m that is private, virtual, and constant:
|
||||
|
||||
\code
|
||||
private:
|
||||
virtual int m(string a) const;
|
||||
\endcode
|
||||
|
||||
\li Select \uicontrol {Clean Up} to format the contents of
|
||||
the \uicontrol Members field depending on their visibility
|
||||
(private, protected, public) and following the rules set for
|
||||
whitespace, line breaks, and so on.
|
||||
|
||||
\li Select the \uicontrol {Show members} check box to show
|
||||
the members in the diagram.
|
||||
|
||||
\endlist
|
||||
|
||||
\endlist
|
||||
|
||||
To navigate from a class in a diagram to the source code, double-click the
|
||||
class in the editor or select \uicontrol {Show Definition} in the context
|
||||
menu.
|
||||
|
||||
\section2 Adding Relations
|
||||
|
||||
Elements in class diagrams can have the following types of relations:
|
||||
inheritance, association, and dependency. The end points of association
|
||||
relations can have the following properties: role, cardinality, navigable,
|
||||
and relationship.
|
||||
|
||||
To create self-relations, start creating a new association and press
|
||||
\key Shift to create a new \e {intermediate point} while dragging the
|
||||
association. Create another intermediate point and drop the association
|
||||
at the same class.
|
||||
|
||||
To add more points, press \key Shift and click a relation. To delete a
|
||||
point, press \key Ctrl and click a point.
|
||||
|
||||
\section1 Creating Component Diagrams
|
||||
|
||||
You can add source code components, such as libraries, databases, programs,
|
||||
and architectural layers to a component diagram. To add components to
|
||||
component diagrams, drag and drop source code from \uicontrol Projects to
|
||||
the editor, and select \uicontrol {Add Component}.
|
||||
|
||||
To navigate from a component in a diagram to the source code, double-click
|
||||
the component in the editor or select \uicontrol {Show Definition} in the
|
||||
context menu.
|
||||
|
||||
\section1 Adding Custom Elements
|
||||
|
||||
The model editor provides the following built-in element types: package,
|
||||
component, class, and item. For package, component, and class elements, you
|
||||
can specify custom icons. The color, size, and form of the icon are
|
||||
determined by a stereotype. If you attach the stereotype to an element, the
|
||||
element icon is replaced by the custom icon. For example, you can attach the
|
||||
entity and interface stereotypes to classes and the database stereotype to
|
||||
components.
|
||||
|
||||
The use case and activity diagrams are examples of using the built-in
|
||||
\e item element type to add custom elements. The item element has the form
|
||||
of a simple rectangle. The use case illustrates how to use a custom icon for
|
||||
an item. The attached stereotype is called \e usecase but it is hidden.
|
||||
Therefore, if you drag the use case to the diagram, it is shown as a use
|
||||
case but no stereotype appears to be defined and you can attach an
|
||||
additional stereotype to the use case.
|
||||
|
||||
Color and icons are attached to elements in use case and activity diagrams
|
||||
by using a simple definition file format. For example, the following code
|
||||
adds the \c UseCase custom element:
|
||||
|
||||
\code
|
||||
Icon UseCase
|
||||
Title: "Use-Case"
|
||||
Elements: item
|
||||
Stereotype: 'usecase'
|
||||
Display: icon
|
||||
Width: 40
|
||||
Height: 20
|
||||
BaseColor: #5fb4f0
|
||||
Begin
|
||||
Ellipse 20, 10, 20, 10
|
||||
End
|
||||
\endcode
|
||||
|
||||
For more information about the available options, see \e standard.def
|
||||
in the \e share/qtcreator/modeleditor directory in the \QC installation
|
||||
directory.
|
||||
|
||||
You can add your own definition file and save it with the file extension
|
||||
\e .def to add custom colors and icons for stereotypes, elements, or tool
|
||||
bars.
|
||||
*/
|
||||
@@ -321,6 +321,12 @@
|
||||
change the default suffix of a file, select \uicontrol Tools > \uicontrol Options >
|
||||
\uicontrol {C++} > \uicontrol {File Naming}.
|
||||
|
||||
\image qtcreator-options-cpp-files.png "File Naming tab in Options"
|
||||
|
||||
In the \uicontrol {License template} field, you can use
|
||||
\l{Using Variables in Wizards}{predefined wizard variables} to specify the
|
||||
path and filename of the license to use in the source and header files.
|
||||
|
||||
You can create your own project and class wizards. For more information,
|
||||
see \l{Adding New Custom Wizards}.
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
\row
|
||||
\li \b {\l{Coding}}
|
||||
\list
|
||||
\li \l{Modeling}
|
||||
\li \l{Writing Code}
|
||||
\li \l{Finding}
|
||||
\li \l{Refactoring}
|
||||
@@ -195,6 +196,7 @@
|
||||
\endlist
|
||||
\li \l{Coding}
|
||||
\list
|
||||
\li \l{Modeling}
|
||||
\li \l{Writing Code}
|
||||
\list
|
||||
\li \l{Working in Edit Mode}
|
||||
|
||||
164
scripts/common.py
Normal file
164
scripts/common.py
Normal file
@@ -0,0 +1,164 @@
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2015 The Qt Company Ltd.
|
||||
## Contact: http://www.qt.io/licensing
|
||||
##
|
||||
## This file is part of Qt Creator.
|
||||
##
|
||||
## Commercial License Usage
|
||||
## Licensees holding valid commercial Qt licenses may use this file in
|
||||
## accordance with the commercial license agreement provided with the
|
||||
## Software or, alternatively, in accordance with the terms contained in
|
||||
## a written agreement between you and The Qt Company. For licensing terms and
|
||||
## conditions see http://www.qt.io/terms-conditions. For further information
|
||||
## use the contact form at http://www.qt.io/contact-us.
|
||||
##
|
||||
## GNU Lesser General Public License Usage
|
||||
## Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
## General Public License version 2.1 or version 3 as published by the Free
|
||||
## Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
## LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
## following information to ensure the GNU Lesser General Public License
|
||||
## requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
##
|
||||
## In addition, as a special exception, The Qt Company gives you certain additional
|
||||
## rights. These rights are described in The Qt Company LGPL Exception
|
||||
## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
##
|
||||
#############################################################################
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def is_windows_platform():
|
||||
return sys.platform.startswith('win')
|
||||
|
||||
def is_linux_platform():
|
||||
return sys.platform.startswith('linux')
|
||||
|
||||
def is_mac_platform():
|
||||
return sys.platform.startswith('darwin')
|
||||
|
||||
# copy of shutil.copytree that does not bail out if the target directory already exists
|
||||
# and that does not create empty directories
|
||||
def copytree(src, dst, symlinks=False, ignore=None):
|
||||
def ensure_dir(destdir, ensure):
|
||||
if ensure and not os.path.isdir(destdir):
|
||||
os.makedirs(destdir)
|
||||
return False
|
||||
|
||||
names = os.listdir(src)
|
||||
if ignore is not None:
|
||||
ignored_names = ignore(src, names)
|
||||
else:
|
||||
ignored_names = set()
|
||||
|
||||
needs_ensure_dest_dir = True
|
||||
errors = []
|
||||
for name in names:
|
||||
if name in ignored_names:
|
||||
continue
|
||||
srcname = os.path.join(src, name)
|
||||
dstname = os.path.join(dst, name)
|
||||
try:
|
||||
if symlinks and os.path.islink(srcname):
|
||||
needs_ensure_dest_dir = ensure_dir(dst, needs_ensure_dest_dir)
|
||||
linkto = os.readlink(srcname)
|
||||
os.symlink(linkto, dstname)
|
||||
elif os.path.isdir(srcname):
|
||||
copytree(srcname, dstname, symlinks, ignore)
|
||||
else:
|
||||
needs_ensure_dest_dir = ensure_dir(dst, needs_ensure_dest_dir)
|
||||
shutil.copy2(srcname, dstname)
|
||||
# XXX What about devices, sockets etc.?
|
||||
except (IOError, os.error) as why:
|
||||
errors.append((srcname, dstname, str(why)))
|
||||
# catch the Error from the recursive copytree so that we can
|
||||
# continue with other files
|
||||
except shutil.Error as err:
|
||||
errors.extend(err.args[0])
|
||||
try:
|
||||
if os.path.exists(dst):
|
||||
shutil.copystat(src, dst)
|
||||
except shutil.WindowsError:
|
||||
# can't copy file access times on Windows
|
||||
pass
|
||||
except OSError as why:
|
||||
errors.extend((src, dst, str(why)))
|
||||
if errors:
|
||||
raise shutil.Error(errors)
|
||||
|
||||
def get_qt_install_info(qmake_bin):
|
||||
output = subprocess.check_output([qmake_bin, '-query'])
|
||||
lines = output.strip().split('\n')
|
||||
info = {}
|
||||
for line in lines:
|
||||
(var, sep, value) = line.partition(':')
|
||||
info[var.strip()] = value.strip()
|
||||
return info
|
||||
|
||||
def get_rpath(libfilepath, chrpath=None):
|
||||
if chrpath is None:
|
||||
chrpath = 'chrpath'
|
||||
try:
|
||||
output = subprocess.check_output([chrpath, '-l', libfilepath]).strip()
|
||||
except subprocess.CalledProcessError: # no RPATH or RUNPATH
|
||||
return []
|
||||
marker = 'RPATH='
|
||||
index = output.find(marker)
|
||||
if index < 0:
|
||||
marker = 'RUNPATH='
|
||||
index = output.find(marker)
|
||||
if index < 0:
|
||||
return []
|
||||
return output[index + len(marker):].split(':')
|
||||
|
||||
def fix_rpaths(path, qt_deploy_path, qt_install_info, chrpath=None):
|
||||
if chrpath is None:
|
||||
chrpath = 'chrpath'
|
||||
qt_install_prefix = qt_install_info['QT_INSTALL_PREFIX']
|
||||
qt_install_libs = qt_install_info['QT_INSTALL_LIBS']
|
||||
|
||||
def fix_rpaths_helper(filepath):
|
||||
rpath = get_rpath(filepath, chrpath)
|
||||
if len(rpath) <= 0:
|
||||
return
|
||||
# remove previous Qt RPATH
|
||||
new_rpath = filter(lambda path: not path.startswith(qt_install_prefix) and not path.startswith(qt_install_libs),
|
||||
rpath)
|
||||
|
||||
# add Qt RPATH if necessary
|
||||
relative_path = os.path.relpath(qt_deploy_path, os.path.dirname(filepath))
|
||||
if relative_path == '.':
|
||||
relative_path = ''
|
||||
else:
|
||||
relative_path = '/' + relative_path
|
||||
qt_rpath = '$ORIGIN' + relative_path
|
||||
if not any((path == qt_rpath) for path in rpath):
|
||||
new_rpath.append(qt_rpath)
|
||||
|
||||
# change RPATH
|
||||
if len(new_rpath) > 0:
|
||||
subprocess.check_call([chrpath, '-r', ':'.join(new_rpath), filepath])
|
||||
else: # no RPATH / RUNPATH left. delete.
|
||||
subprocess.check_call([chrpath, '-d', filepath])
|
||||
|
||||
def is_unix_executable(filepath):
|
||||
# Whether a file is really a binary executable and not a script and not a symlink (unix only)
|
||||
if os.path.exists(filepath) and os.access(filepath, os.X_OK) and not os.path.islink(filepath):
|
||||
with open(filepath) as f:
|
||||
return f.read(2) != "#!"
|
||||
|
||||
def is_unix_library(filepath):
|
||||
# Whether a file is really a library and not a symlink (unix only)
|
||||
return os.path.basename(filepath).find('.so') != -1 and not os.path.islink(filepath)
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
for filename in filenames:
|
||||
filepath = os.path.join(dirpath, filename)
|
||||
if is_unix_executable(filepath) or is_unix_library(filepath):
|
||||
fix_rpaths_helper(filepath)
|
||||
|
||||
@@ -36,6 +36,8 @@ import string
|
||||
import shutil
|
||||
from glob import glob
|
||||
|
||||
import common
|
||||
|
||||
ignoreErrors = False
|
||||
debug_build = False
|
||||
|
||||
@@ -50,7 +52,7 @@ def which(program):
|
||||
if fpath:
|
||||
if is_exe(program):
|
||||
return program
|
||||
if sys.platform.startswith('win'):
|
||||
if common.is_windows_platform():
|
||||
if is_exe(program + ".exe"):
|
||||
return program + ".exe"
|
||||
else:
|
||||
@@ -58,7 +60,7 @@ def which(program):
|
||||
exe_file = os.path.join(path, program)
|
||||
if is_exe(exe_file):
|
||||
return exe_file
|
||||
if sys.platform.startswith('win'):
|
||||
if common.is_windows_platform():
|
||||
if is_exe(exe_file + ".exe"):
|
||||
return exe_file + ".exe"
|
||||
|
||||
@@ -86,44 +88,6 @@ def op_failed(details = None):
|
||||
else:
|
||||
print("Error: operation failed, but proceeding gracefully.")
|
||||
|
||||
def fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames):
|
||||
# patch file
|
||||
for filename in filenames:
|
||||
fpath = os.path.join(dirpath, filename)
|
||||
relpath = os.path.relpath(install_dir+'/lib/qtcreator', dirpath)
|
||||
relpluginpath = os.path.relpath(install_dir+'/lib/qtcreator/plugins', dirpath)
|
||||
command = [chrpath_bin, '-r', '$ORIGIN/'+relpath+':$ORIGIN/'+relpluginpath, fpath]
|
||||
print fpath, ':', command
|
||||
try:
|
||||
subprocess.check_call(command)
|
||||
except:
|
||||
op_failed()
|
||||
|
||||
def check_unix_binary_exec_helper(dirpath, filename):
|
||||
""" Whether a file is really a binary executable and not a script (unix only)"""
|
||||
fpath = os.path.join(dirpath, filename)
|
||||
if os.path.exists(fpath) and os.access(fpath, os.X_OK):
|
||||
with open(fpath) as f:
|
||||
return f.read(2) != "#!"
|
||||
|
||||
def check_unix_library_helper(dirpath, filename):
|
||||
""" Whether a file is really a library and not a symlink (unix only)"""
|
||||
fpath = os.path.join(dirpath, filename)
|
||||
return filename.find('.so') != -1 and not os.path.islink(fpath)
|
||||
|
||||
def fix_rpaths(chrpath_bin, install_dir):
|
||||
print "fixing rpaths..."
|
||||
for dirpath, dirnames, filenames in os.walk(os.path.join(install_dir, 'bin')):
|
||||
#TODO remove library_helper once all libs moved out of bin/ on linux
|
||||
filenames = [filename for filename in filenames if check_unix_binary_exec_helper(dirpath, filename) or check_unix_library_helper(dirpath, filename)]
|
||||
fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames)
|
||||
for dirpath, dirnames, filenames in os.walk(os.path.join(install_dir, 'libexec', 'qtcreator')):
|
||||
filenames = [filename for filename in filenames if check_unix_binary_exec_helper(dirpath, filename)]
|
||||
fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames)
|
||||
for dirpath, dirnames, filenames in os.walk(os.path.join(install_dir, 'lib')):
|
||||
filenames = [filename for filename in filenames if check_unix_library_helper(dirpath, filename)]
|
||||
fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames)
|
||||
|
||||
def windows_debug_files_filter(filename):
|
||||
ignore_patterns = ['.lib', '.pdb', '.exp', '.ilk']
|
||||
for ip in ignore_patterns:
|
||||
@@ -132,7 +96,7 @@ def windows_debug_files_filter(filename):
|
||||
return False
|
||||
|
||||
def copy_ignore_patterns_helper(dir, filenames):
|
||||
if not sys.platform.startswith('win'):
|
||||
if not common.is_windows_platform:
|
||||
return filenames
|
||||
|
||||
if debug_build:
|
||||
@@ -146,17 +110,17 @@ def copy_ignore_patterns_helper(dir, filenames):
|
||||
def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, qt_qml_dir, plugins, imports):
|
||||
print "copying Qt libraries..."
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
if common.is_windows_platform():
|
||||
libraries = glob(os.path.join(qt_libs_dir, '*.dll'))
|
||||
else:
|
||||
libraries = glob(os.path.join(qt_libs_dir, '*.so.*'))
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
if common.is_windows_platform():
|
||||
dest = os.path.join(install_dir, 'bin')
|
||||
else:
|
||||
dest = os.path.join(install_dir, 'lib', 'qtcreator')
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
if common.is_windows_platform():
|
||||
if debug_build:
|
||||
libraries = filter(lambda library: is_debug(library), libraries)
|
||||
else:
|
||||
@@ -174,7 +138,7 @@ def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, qt_qml_
|
||||
shutil.copy(library, dest)
|
||||
|
||||
copy_ignore_func = None
|
||||
if sys.platform.startswith('win'):
|
||||
if common.is_windows_platform():
|
||||
copy_ignore_func = copy_ignore_patterns_helper
|
||||
|
||||
print "Copying plugins:", plugins
|
||||
@@ -184,7 +148,7 @@ def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, qt_qml_
|
||||
shutil.rmtree(target)
|
||||
pluginPath = os.path.join(qt_plugin_dir, plugin)
|
||||
if (os.path.exists(pluginPath)):
|
||||
shutil.copytree(pluginPath, target, ignore=copy_ignore_func, symlinks=True)
|
||||
common.copytree(pluginPath, target, ignore=copy_ignore_func, symlinks=True)
|
||||
|
||||
print "Copying imports:", imports
|
||||
for qtimport in imports:
|
||||
@@ -193,23 +157,24 @@ def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, qt_qml_
|
||||
shutil.rmtree(target)
|
||||
import_path = os.path.join(qt_import_dir, qtimport)
|
||||
if os.path.exists(import_path):
|
||||
shutil.copytree(import_path, target, ignore=copy_ignore_func, symlinks=True)
|
||||
common.copytree(import_path, target, ignore=copy_ignore_func, symlinks=True)
|
||||
|
||||
if (os.path.exists(qt_qml_dir)):
|
||||
print "Copying qt quick 2 imports"
|
||||
target = os.path.join(install_dir, 'bin', 'qml')
|
||||
if (os.path.exists(target)):
|
||||
shutil.rmtree(target)
|
||||
shutil.copytree(qt_qml_dir, target, ignore=copy_ignore_func, symlinks=True)
|
||||
common.copytree(qt_qml_dir, target, ignore=copy_ignore_func, symlinks=True)
|
||||
|
||||
def add_qt_conf(install_dir):
|
||||
print "Creating qt.conf:"
|
||||
f = open(install_dir + '/bin/qt.conf', 'w')
|
||||
def add_qt_conf(target_dir, install_dir):
|
||||
qtconf_filepath = os.path.join(target_dir, 'qt.conf')
|
||||
print('Creating qt.conf in "{0}":'.format(qtconf_filepath))
|
||||
f = open(qtconf_filepath, 'w')
|
||||
f.write('[Paths]\n')
|
||||
f.write('Libraries=../lib/qtcreator\n')
|
||||
f.write('Plugins=plugins\n')
|
||||
f.write('Imports=imports\n')
|
||||
f.write('Qml2Imports=qml\n')
|
||||
f.write('Libraries={0}\n'.format(os.path.relpath(os.path.join(install_dir, 'lib', 'qtcreator'), target_dir).replace('\\', '/')))
|
||||
f.write('Plugins={0}\n'.format(os.path.relpath(os.path.join(install_dir, 'bin', 'plugins'), target_dir).replace('\\', '/')))
|
||||
f.write('Imports={0}\n'.format(os.path.relpath(os.path.join(install_dir, 'bin', 'imports'), target_dir).replace('\\', '/')))
|
||||
f.write('Qml2Imports={0}\n'.format(os.path.relpath(os.path.join(install_dir, 'bin', 'qml'), target_dir).replace('\\', '/')))
|
||||
f.close()
|
||||
|
||||
def copy_translations(install_dir, qt_tr_dir):
|
||||
@@ -231,12 +196,14 @@ def copyPreservingLinks(source, destination):
|
||||
else:
|
||||
shutil.copy(source, destination)
|
||||
|
||||
def copy_libclang(install_dir, llvm_install_dir):
|
||||
def deploy_libclang(install_dir, llvm_install_dir, chrpath_bin):
|
||||
# contains pairs of (source, target directory)
|
||||
deployinfo = []
|
||||
if sys.platform.startswith("win"):
|
||||
if common.is_windows_platform():
|
||||
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'libclang.dll'),
|
||||
os.path.join(install_dir, 'bin')))
|
||||
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'clang.exe'),
|
||||
os.path.join(install_dir, 'bin')))
|
||||
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'clang-cl.exe'),
|
||||
os.path.join(install_dir, 'bin')))
|
||||
else:
|
||||
@@ -259,14 +226,20 @@ def copy_libclang(install_dir, llvm_install_dir):
|
||||
for source, target in deployinfo:
|
||||
print source, '->', target
|
||||
copyPreservingLinks(source, target)
|
||||
|
||||
if common.is_linux_platform():
|
||||
# libclang was statically compiled, so there is no need for the RPATHs
|
||||
# and they are confusing when fixing RPATHs later in the process
|
||||
print "removing libclang RPATHs..."
|
||||
for source, target in deployinfo:
|
||||
if not os.path.islink(target):
|
||||
targetfilepath = target if not os.path.isdir(target) else os.path.join(target, os.path.basename(source))
|
||||
subprocess.check_call([chrpath_bin, '-d', targetfilepath])
|
||||
|
||||
print resourcesource, '->', resourcetarget
|
||||
if (os.path.exists(resourcetarget)):
|
||||
shutil.rmtree(resourcetarget)
|
||||
shutil.copytree(resourcesource, resourcetarget, symlinks=True)
|
||||
|
||||
def readQmakeVar(qmake_bin, var):
|
||||
pipe = os.popen(' '.join([qmake_bin, '-query', var]))
|
||||
return pipe.read().rstrip('\n')
|
||||
common.copytree(resourcesource, resourcetarget, symlinks=True)
|
||||
|
||||
def main():
|
||||
try:
|
||||
@@ -298,40 +271,45 @@ def main():
|
||||
print "Cannot find required binary 'qmake'."
|
||||
sys.exit(2)
|
||||
|
||||
if not sys.platform.startswith('win'):
|
||||
chrpath_bin = None
|
||||
if common.is_linux_platform():
|
||||
chrpath_bin = which('chrpath')
|
||||
if chrpath_bin == None:
|
||||
print "Cannot find required binary 'chrpath'."
|
||||
sys.exit(2)
|
||||
|
||||
QT_INSTALL_LIBS = readQmakeVar(qmake_bin, 'QT_INSTALL_LIBS')
|
||||
QT_INSTALL_BINS = readQmakeVar(qmake_bin, 'QT_INSTALL_BINS')
|
||||
QT_INSTALL_PLUGINS = readQmakeVar(qmake_bin, 'QT_INSTALL_PLUGINS')
|
||||
QT_INSTALL_IMPORTS = readQmakeVar(qmake_bin, 'QT_INSTALL_IMPORTS')
|
||||
QT_INSTALL_QML = readQmakeVar(qmake_bin, 'QT_INSTALL_QML')
|
||||
QT_INSTALL_TRANSLATIONS = readQmakeVar(qmake_bin, 'QT_INSTALL_TRANSLATIONS')
|
||||
qt_install_info = common.get_qt_install_info(qmake_bin)
|
||||
QT_INSTALL_LIBS = qt_install_info['QT_INSTALL_LIBS']
|
||||
QT_INSTALL_BINS = qt_install_info['QT_INSTALL_BINS']
|
||||
QT_INSTALL_PLUGINS = qt_install_info['QT_INSTALL_PLUGINS']
|
||||
QT_INSTALL_IMPORTS = qt_install_info['QT_INSTALL_IMPORTS']
|
||||
QT_INSTALL_QML = qt_install_info['QT_INSTALL_QML']
|
||||
QT_INSTALL_TRANSLATIONS = qt_install_info['QT_INSTALL_TRANSLATIONS']
|
||||
|
||||
plugins = ['accessible', 'codecs', 'designer', 'iconengines', 'imageformats', 'platformthemes', 'platforminputcontexts', 'platforms', 'printsupport', 'sqldrivers', 'xcbglintegrations']
|
||||
imports = ['Qt', 'QtWebKit']
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
if common.is_windows_platform():
|
||||
global debug_build
|
||||
debug_build = is_debug_build(install_dir)
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
if common.is_windows_platform():
|
||||
copy_qt_libs(install_dir, QT_INSTALL_BINS, QT_INSTALL_PLUGINS, QT_INSTALL_IMPORTS, QT_INSTALL_QML, plugins, imports)
|
||||
else:
|
||||
copy_qt_libs(install_dir, QT_INSTALL_LIBS, QT_INSTALL_PLUGINS, QT_INSTALL_IMPORTS, QT_INSTALL_QML, plugins, imports)
|
||||
copy_translations(install_dir, QT_INSTALL_TRANSLATIONS)
|
||||
if "LLVM_INSTALL_DIR" in os.environ:
|
||||
copy_libclang(install_dir, os.environ["LLVM_INSTALL_DIR"])
|
||||
deploy_libclang(install_dir, os.environ["LLVM_INSTALL_DIR"], chrpath_bin)
|
||||
|
||||
if not sys.platform.startswith('win'):
|
||||
fix_rpaths(chrpath_bin, install_dir)
|
||||
add_qt_conf(install_dir)
|
||||
if not common.is_windows_platform():
|
||||
print "fixing rpaths..."
|
||||
common.fix_rpaths(install_dir, os.path.join(install_dir, 'lib', 'qtcreator'),
|
||||
qt_install_info, chrpath_bin)
|
||||
add_qt_conf(os.path.join(install_dir, 'libexec', 'qtcreator'), install_dir) # e.g. for qml2puppet
|
||||
add_qt_conf(os.path.join(install_dir, 'bin'), install_dir)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if sys.platform == 'darwin':
|
||||
if common.is_mac_platform():
|
||||
print "Mac OS is not supported by this script, please use macqtdeploy!"
|
||||
sys.exit(2)
|
||||
else:
|
||||
|
||||
@@ -46,6 +46,12 @@ if [ ! -f "$1/Contents/Resources/ios/qt.conf" ]; then
|
||||
cp -f "$(dirname "${BASH_SOURCE[0]}")/../dist/installer/mac/ios_qt.conf" "$1/Contents/Resources/ios/qt.conf" || exit 1
|
||||
fi
|
||||
|
||||
# copy qml2puppet's qt.conf
|
||||
if [ ! -f "$1/Contents/Resources/qmldesigner/qt.conf" ]; then
|
||||
echo "- Copying qmldesigner/qt.conf"
|
||||
cp -f "$(dirname "${BASH_SOURCE[0]}")/../dist/installer/mac/qmldesigner_qt.conf" "$1/Contents/Resources/qmldesigner/qt.conf" || exit 1
|
||||
fi
|
||||
|
||||
# copy Qt translations
|
||||
# check for known existing translation to avoid copying multiple times
|
||||
if [ ! -f "$1/Contents/Resources/translations/qt_de.qm" ]; then
|
||||
@@ -82,7 +88,7 @@ fi
|
||||
|
||||
if [ ! -d "$1/Contents/Frameworks/QtCore.framework" ]; then
|
||||
|
||||
qml2puppetapp="$1/Contents/Resources/qml2puppet"
|
||||
qml2puppetapp="$1/Contents/Resources/qmldesigner/qml2puppet"
|
||||
if [ -f "$qml2puppetapp" ]; then
|
||||
qml2puppetArgument="-executable=$qml2puppetapp"
|
||||
fi
|
||||
|
||||
@@ -38,7 +38,7 @@ import shutil
|
||||
import inspect
|
||||
|
||||
def usage():
|
||||
print('Usage: %s [-v|--version-string=versionstring] [-i|--installer-path=/path/to/installerfw] [-a|--archive=archive.7z] <outputname>' % os.path.basename(sys.argv[0]))
|
||||
print('Usage: %s [-v|--version-string=versionstring] [-i|--installer-path=/path/to/installerfw] [-a|--archive=archive.7z] [-d|--debug] <outputname>' % os.path.basename(sys.argv[0]))
|
||||
|
||||
def substitute_file(infile, outfile, substitutions):
|
||||
with open(infile, 'r') as f:
|
||||
@@ -53,7 +53,7 @@ def ifw_template_dir():
|
||||
|
||||
def main():
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], 'hv:i:a:', ['help', 'version-string=', 'installer-path=', 'archive'])
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], 'hv:i:a:d', ['help', 'version-string=', 'installer-path=', 'archive', 'debug'])
|
||||
except:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
@@ -64,7 +64,8 @@ def main():
|
||||
|
||||
version = ''
|
||||
ifw_location = ''
|
||||
archive = ''
|
||||
archives = []
|
||||
debug = False
|
||||
for o, a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
usage()
|
||||
@@ -74,7 +75,9 @@ def main():
|
||||
if o in ('-i', '--installer-path'):
|
||||
ifw_location = a
|
||||
if o in ('-a', '--archive'):
|
||||
archive = a
|
||||
archives.append(a)
|
||||
if o in ('-d', '--debug'):
|
||||
debug = True
|
||||
|
||||
if (version == ''):
|
||||
raise Exception('Version not specified (--version-string)!')
|
||||
@@ -82,8 +85,8 @@ def main():
|
||||
if (ifw_location == ''):
|
||||
raise Exception('Installer framework location not specified (--installer-path)!')
|
||||
|
||||
if (archive == ''):
|
||||
raise Exception('Archive not specified (--archive)!')
|
||||
if not archives:
|
||||
raise ValueError('No archive(s) specified (--archive)!')
|
||||
|
||||
installer_name = args[0]
|
||||
config_postfix = ''
|
||||
@@ -100,12 +103,15 @@ def main():
|
||||
try:
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
except:
|
||||
raise Exception('Failed to create a temporary directory!')
|
||||
raise IOError('Failed to create a temporary directory!')
|
||||
|
||||
if debug:
|
||||
print('Working directory: {0}'.format(temp_dir))
|
||||
try:
|
||||
substs = {}
|
||||
substs['version'] = version
|
||||
substs['date'] = datetime.date.today().isoformat()
|
||||
substs['archives'] = ','.join(archives)
|
||||
|
||||
template_dir = ifw_template_dir()
|
||||
out_config_dir = os.path.join(temp_dir,'config')
|
||||
@@ -127,11 +133,15 @@ def main():
|
||||
data_path = os.path.join(out_packages_dir, 'org.qtproject.qtcreator.application', 'data')
|
||||
if not os.path.exists(data_path):
|
||||
os.makedirs(data_path)
|
||||
for archive in archives:
|
||||
shutil.copy(archive, data_path)
|
||||
|
||||
ifw_call = [os.path.join(ifw_location, 'bin', 'binarycreator'), '-c', os.path.join(out_config_dir, config_name), '-p', out_packages_dir, installer_name, '--offline-only' ]
|
||||
if debug:
|
||||
ifw_call.append('-v')
|
||||
subprocess.check_call(ifw_call, stderr=subprocess.STDOUT)
|
||||
finally:
|
||||
if not debug:
|
||||
print('Cleaning up...')
|
||||
shutil.rmtree(temp_dir)
|
||||
print('Done.')
|
||||
|
||||
58
scripts/packagePlugins.py
Executable file
58
scripts/packagePlugins.py
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2015 The Qt Company Ltd.
|
||||
## Contact: http://www.qt.io/licensing
|
||||
##
|
||||
## This file is part of Qt Creator.
|
||||
##
|
||||
## Commercial License Usage
|
||||
## Licensees holding valid commercial Qt licenses may use this file in
|
||||
## accordance with the commercial license agreement provided with the
|
||||
## Software or, alternatively, in accordance with the terms contained in
|
||||
## a written agreement between you and The Qt Company. For licensing terms and
|
||||
## conditions see http://www.qt.io/terms-conditions. For further information
|
||||
## use the contact form at http://www.qt.io/contact-us.
|
||||
##
|
||||
## GNU Lesser General Public License Usage
|
||||
## Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
## General Public License version 2.1 or version 3 as published by the Free
|
||||
## Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
## LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
## following information to ensure the GNU Lesser General Public License
|
||||
## requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
##
|
||||
## In addition, as a special exception, The Qt Company gives you certain additional
|
||||
## rights. These rights are described in The Qt Company LGPL Exception
|
||||
## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
##
|
||||
#############################################################################
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import common
|
||||
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser(description="Deploy and 7z a directory of plugins.")
|
||||
parser.add_argument('--7z', help='path to 7z binary',
|
||||
default='7z.exe' if common.is_windows_platform() else '7z',
|
||||
metavar='<7z_binary>', dest='sevenzip')
|
||||
parser.add_argument('--qmake_binary', help='path to qmake binary which was used for compilation',
|
||||
required=common.is_linux_platform(), metavar='<qmake_binary>')
|
||||
parser.add_argument('source_directory', help='directory to deploy and 7z')
|
||||
parser.add_argument('target_file', help='target file path of the resulting 7z')
|
||||
return parser.parse_args()
|
||||
|
||||
if __name__ == "__main__":
|
||||
arguments = parse_arguments()
|
||||
if common.is_linux_platform():
|
||||
qt_install_info = common.get_qt_install_info(arguments.qmake_binary)
|
||||
common.fix_rpaths(arguments.source_directory,
|
||||
os.path.join(arguments.source_directory, 'lib', 'qtcreator'),
|
||||
qt_install_info)
|
||||
subprocess.check_call([arguments.sevenzip, 'a', '-mx9', arguments.target_file,
|
||||
os.path.join(arguments.source_directory, '*')])
|
||||
@@ -414,8 +414,6 @@ class DumperBase:
|
||||
"personaltypes",
|
||||
]
|
||||
|
||||
self.interpreterSeq = 0
|
||||
|
||||
|
||||
def resetCaches(self):
|
||||
# This is a cache mapping from 'type name' to 'display alternatives'.
|
||||
@@ -601,9 +599,6 @@ class DumperBase:
|
||||
data = self.extractBlob(addr, size).toBytes()
|
||||
return self.hexencode(data)
|
||||
|
||||
def readJsonFromMemory(self, addr, size):
|
||||
return json.loads(self.hexdecode(self.readMemory(addr, size)))
|
||||
|
||||
def encodeByteArray(self, value, limit = 0):
|
||||
elided, data = self.encodeByteArrayHelper(self.extractPointer(value), limit)
|
||||
return data
|
||||
@@ -834,16 +829,99 @@ class DumperBase:
|
||||
self.putSpecialValue(SpecialItemCountValue, count)
|
||||
self.putNumChild(count)
|
||||
|
||||
def dictToMi(self, value):
|
||||
def resultToMi(self, value):
|
||||
if type(value) is bool:
|
||||
return '"%d"' % int(value)
|
||||
if type(value) is dict:
|
||||
return '{' + ','.join(['%s=%s' % (k, self.dictToMi(v))
|
||||
return '{' + ','.join(['%s=%s' % (k, self.resultToMi(v))
|
||||
for (k, v) in list(value.items())]) + '}'
|
||||
if type(value) is list:
|
||||
return '[' + ','.join([self.dictToMi(v) for v in value]) + ']'
|
||||
return '[' + ','.join([self.resultToMi(k)
|
||||
for k in list(value.items())]) + ']'
|
||||
return '"%s"' % value
|
||||
|
||||
def variablesToMi(self, value, prefix):
|
||||
if type(value) is bool:
|
||||
return '"%d"' % int(value)
|
||||
if type(value) is dict:
|
||||
pairs = []
|
||||
for (k, v) in list(value.items()):
|
||||
if k == 'iname':
|
||||
if v.startswith('.'):
|
||||
v = '"%s%s"' % (prefix, v)
|
||||
else:
|
||||
v = '"%s"' % v
|
||||
else:
|
||||
v = self.variablesToMi(v, prefix)
|
||||
pairs.append('%s=%s' % (k, v))
|
||||
return '{' + ','.join(pairs) + '}'
|
||||
if type(value) is list:
|
||||
index = 0
|
||||
pairs = []
|
||||
for item in value:
|
||||
if item.get('type', '') == 'function':
|
||||
continue
|
||||
name = item.get('name', '')
|
||||
if len(name) == 0:
|
||||
name = str(index)
|
||||
index += 1
|
||||
pairs.append((name, self.variablesToMi(item, prefix)))
|
||||
pairs.sort(key = lambda pair: pair[0])
|
||||
return '[' + ','.join([pair[1] for pair in pairs]) + ']'
|
||||
return '"%s"' % value
|
||||
|
||||
def filterPrefix(self, prefix, items):
|
||||
return [i[len(prefix):] for i in items if i.startswith(prefix)]
|
||||
|
||||
def tryFetchInterpreterVariables(self, args):
|
||||
if not int(args.get('nativemixed', 0)):
|
||||
return (False, '')
|
||||
context = args.get('context', '')
|
||||
if not len(context):
|
||||
return (False, '')
|
||||
|
||||
expanded = args.get('expanded')
|
||||
args['expanded'] = self.filterPrefix('local', expanded)
|
||||
|
||||
res = self.sendInterpreterRequest('variables', args)
|
||||
if not res:
|
||||
return (False, '')
|
||||
|
||||
reslist = []
|
||||
for item in res.get('variables', {}):
|
||||
if not 'iname' in item:
|
||||
item['iname'] = '.' + item.get('name')
|
||||
reslist.append(self.variablesToMi(item, 'local'))
|
||||
|
||||
watchers = args.get('watchers', None)
|
||||
if watchers:
|
||||
toevaluate = []
|
||||
name2expr = {}
|
||||
seq = 0
|
||||
for watcher in watchers:
|
||||
expr = self.hexdecode(watcher.get('exp'))
|
||||
name = str(seq)
|
||||
toevaluate.append({'name': name, 'expression': expr})
|
||||
name2expr[name] = expr
|
||||
seq += 1
|
||||
args['expressions'] = toevaluate
|
||||
|
||||
args['expanded'] = self.filterPrefix('watch', expanded)
|
||||
del args['watchers']
|
||||
res = self.sendInterpreterRequest('expressions', args)
|
||||
|
||||
if res:
|
||||
for item in res.get('expressions', {}):
|
||||
name = item.get('name')
|
||||
iname = 'watch.' + name
|
||||
expr = name2expr.get(name)
|
||||
item['iname'] = iname
|
||||
item['wname'] = self.hexencode(expr)
|
||||
item['exp'] = expr
|
||||
reslist.append(self.variablesToMi(item, 'watch'))
|
||||
|
||||
return (True, 'data=[%s]' % ','.join(reslist))
|
||||
|
||||
def putField(self, name, value):
|
||||
self.put('%s="%s",' % (name, value))
|
||||
|
||||
@@ -1753,34 +1831,86 @@ class DumperBase:
|
||||
value = struct.unpack_from("!I", buf, offset)[0]
|
||||
return (value, offset + 4)
|
||||
|
||||
def readInterpreterOutput(self):
|
||||
buf = self.parseAndEvaluate("qt_qmlDebugOutputBuffer")
|
||||
size = self.parseAndEvaluate("qt_qmlDebugOutputLength")
|
||||
return self.readJsonFromMemory(buf, size)
|
||||
|
||||
def handleInterpreterEvent(self):
|
||||
def handleInterpreterMessage(self):
|
||||
""" Return True if inferior stopped """
|
||||
buf = self.parseAndEvaluate("qt_qmlDebugEventBuffer")
|
||||
size = self.parseAndEvaluate("qt_qmlDebugEventLength")
|
||||
resdict = self.readJsonFromMemory(buf, size)
|
||||
warn("RES DICT : %s" % resdict)
|
||||
resdict = self.fetchInterpreterResult()
|
||||
return resdict.get('event') == 'break'
|
||||
|
||||
def reportInterpreterResult(self, resdict, args):
|
||||
print('interpreterresult=%s,token="%s"'
|
||||
% (self.resultToMi(resdict), args.get('token', -1)))
|
||||
|
||||
def reportInterpreterAsync(self, resdict, asyncclass):
|
||||
print('interpreterasync=%s,asyncclass="%s"'
|
||||
% (self.resultToMi(resdict), asyncclass))
|
||||
|
||||
def removeInterpreterBreakpoint(self, args):
|
||||
res = self.sendInterpreterRequest('removebreakpoint', { 'id' : args['id'] })
|
||||
return res
|
||||
|
||||
def insertInterpreterBreakpoint(self, args):
|
||||
args['condition'] = self.hexdecode(args.get('condition', ''))
|
||||
warn("Insert interpreter breakpoint %s:%s (%s)"
|
||||
% (args['file'], args['line'], args['condition']))
|
||||
bp = self.doInsertInterpreterBreakpoint(args, False)
|
||||
return str(bp)
|
||||
# Will fail if the service is not yet up and running.
|
||||
response = self.sendInterpreterRequest('setbreakpoint', args)
|
||||
resdict = args.copy()
|
||||
bp = None if response is None else response.get("breakpoint", None)
|
||||
if bp:
|
||||
resdict['number'] = bp
|
||||
resdict['pending'] = 0
|
||||
else:
|
||||
self.createResolvePendingBreakpointsHookBreakpoint(args)
|
||||
resdict['number'] = -1
|
||||
resdict['pending'] = 1
|
||||
resdict['warning'] = 'Direct interpreter breakpoint insertion failed.'
|
||||
self.reportInterpreterResult(resdict, args)
|
||||
|
||||
def resolvePendingInterpreterBreakpoint(self, args):
|
||||
self.parseAndEvaluate('qt_qmlDebugEnableService("NativeQmlDebugger")')
|
||||
response = self.sendInterpreterRequest('setbreakpoint', args)
|
||||
bp = None if response is None else response.get("breakpoint", None)
|
||||
resdict = args.copy()
|
||||
if bp:
|
||||
resdict['number'] = bp
|
||||
resdict['pending'] = 0
|
||||
else:
|
||||
resdict['number'] = -1
|
||||
resdict['pending'] = 0
|
||||
resdict['error'] = 'Pending interpreter breakpoint insertion failed.'
|
||||
self.reportInterpreterAsync(resdict, 'breakpointmodified')
|
||||
|
||||
def fetchInterpreterResult(self):
|
||||
buf = self.parseAndEvaluate("qt_qmlDebugMessageBuffer")
|
||||
size = self.parseAndEvaluate("qt_qmlDebugMessageLength")
|
||||
msg = self.hexdecode(self.readMemory(buf, size))
|
||||
# msg is a sequence of 'servicename<space>msglen<space>msg' items.
|
||||
resdict = {} # Native payload.
|
||||
while len(msg):
|
||||
pos0 = msg.index(' ') # End of service name
|
||||
pos1 = msg.index(' ', pos0 + 1) # End of message length
|
||||
service = msg[0:pos0]
|
||||
msglen = int(msg[pos0+1:pos1])
|
||||
msgend = pos1+1+msglen
|
||||
payload = msg[pos1+1:msgend]
|
||||
msg = msg[msgend:]
|
||||
if service == 'NativeQmlDebugger':
|
||||
try:
|
||||
resdict = json.loads(payload)
|
||||
continue
|
||||
except:
|
||||
warn("Cannot parse native payload: %s" % payload)
|
||||
else:
|
||||
print('interpreteralien=%s'
|
||||
% {'service': service, 'payload': self.hexencode(payload)})
|
||||
try:
|
||||
expr = 'qt_qmlDebugClearBuffer()'
|
||||
res = self.parseAndEvaluate(expr)
|
||||
except RuntimeError as error:
|
||||
warn("Cleaning buffer failed: %s: %s" % (expr, error))
|
||||
|
||||
return resdict
|
||||
|
||||
def sendInterpreterRequest(self, command, args = {}):
|
||||
self.interpreterSeq += 1
|
||||
cmd = { 'seq': self.interpreterSeq, 'type': 'request', 'command': command, 'arguments': args }
|
||||
encoded = json.dumps(cmd)
|
||||
encoded = json.dumps({ 'command': command, 'arguments': args })
|
||||
hexdata = self.hexencode(encoded)
|
||||
expr = 'qt_qmlDebugSendDataToService("NativeQmlDebugger","%s")' % hexdata
|
||||
try:
|
||||
@@ -1792,21 +1922,10 @@ class DumperBase:
|
||||
# Happens with LLDB and 'None' current thread.
|
||||
warn("Interpreter command failed: %s: %s" % (encoded, error))
|
||||
return {}
|
||||
|
||||
if not res:
|
||||
warn("Interpreter command failed: %s " % encoded)
|
||||
return {}
|
||||
resdict = self.readInterpreterOutput()
|
||||
warn("Interpreter command output: '%s'" % resdict)
|
||||
service = resdict.get("service")
|
||||
if service == "NativeQmlDebugger":
|
||||
messages = resdict.get("messages", [])
|
||||
if len(messages) == 1:
|
||||
return messages[0]
|
||||
warn("Unexpected multiple interpreter messages: %s" % messages)
|
||||
else:
|
||||
warn("Interpreter result from alien service: %s" % service)
|
||||
return {'messages': messages }
|
||||
return self.fetchInterpreterResult()
|
||||
|
||||
def executeStep(self, args):
|
||||
if self.nativeMixed:
|
||||
@@ -1829,23 +1948,22 @@ class DumperBase:
|
||||
self.doContinue()
|
||||
|
||||
def doInsertInterpreterBreakpoint(self, args, wasPending):
|
||||
warn("DO INSERT INTERPRETER BREAKPOINT, WAS PENDING: %s" % wasPending)
|
||||
#warn("DO INSERT INTERPRETER BREAKPOINT, WAS PENDING: %s" % wasPending)
|
||||
# Will fail if the service is not yet up and running.
|
||||
response = self.sendInterpreterRequest('setbreakpoint', args)
|
||||
bp = None if response is None else response.get("breakpoint", None)
|
||||
if wasPending:
|
||||
if not bp:
|
||||
warn("ERROR: Pending interpreter breakpoint insertion failed.")
|
||||
return -1
|
||||
self.reportInterpreterResult({'bpnr': -1, 'pending': 1,
|
||||
'error': 'Pending interpreter breakpoint insertion failed.'}, args)
|
||||
return
|
||||
else:
|
||||
if not bp:
|
||||
warn("Direct interpreter breakpoint insertion failed.")
|
||||
warn("Make pending.")
|
||||
self.reportInterpreterResult({'bpnr': -1, 'pending': 1,
|
||||
'warning': 'Direct interpreter breakpoint insertion failed.'}, args)
|
||||
self.createResolvePendingBreakpointsHookBreakpoint(args)
|
||||
return -1
|
||||
|
||||
warn("Resolved interpreter breakpoint: BP: %s" % bp)
|
||||
return int(bp)
|
||||
return
|
||||
self.reportInterpreterResult({'bpnr': bp, 'pending': 0}, args)
|
||||
|
||||
def isInternalInterpreterFrame(self, functionName):
|
||||
if functionName is None:
|
||||
@@ -1875,6 +1993,11 @@ class DumperBase:
|
||||
def extractInterpreterStack(self):
|
||||
return self.sendInterpreterRequest('backtrace', {'limit': 10 })
|
||||
|
||||
def extractInterpreterVariables(self, args):
|
||||
return self.sendInterpreterRequest('variables', args)
|
||||
def polishWatchers(self, watchers):
|
||||
out = []
|
||||
for watcher in watchers:
|
||||
iname = watcher.get('iname')
|
||||
exp = self.hexdecode(watcher.get('exp'))
|
||||
out.append({'iname': iname, 'expression': exp, 'name': exp })
|
||||
return out
|
||||
|
||||
|
||||
@@ -220,12 +220,11 @@ class Dumper(DumperBase):
|
||||
|
||||
# These values will be kept between calls to 'fetchVariables'.
|
||||
self.isGdb = True
|
||||
self.childEventAddress = None
|
||||
self.typeCache = {}
|
||||
self.typesReported = {}
|
||||
self.typesToReport = {}
|
||||
self.qtNamespaceToReport = None
|
||||
self.interpreterBreakpoints = []
|
||||
self.interpreterBreakpointResolvers = []
|
||||
|
||||
def prepare(self, args):
|
||||
self.output = []
|
||||
@@ -359,12 +358,9 @@ class Dumper(DumperBase):
|
||||
partialVariable = args.get("partialVariable", "")
|
||||
isPartial = len(partialVariable) > 0
|
||||
|
||||
if self.nativeMixed:
|
||||
context = args.get('context', '')
|
||||
if len(context):
|
||||
res = self.extractInterpreterVariables(args)
|
||||
if res:
|
||||
safePrint('data=%s' % self.dictToMi(res.get('data', {})))
|
||||
(ok, res) = self.tryFetchInterpreterVariables(args)
|
||||
if ok:
|
||||
safePrint(res)
|
||||
return
|
||||
|
||||
#
|
||||
@@ -1607,7 +1603,7 @@ class Dumper(DumperBase):
|
||||
objfile = fromNativePath(symtab.objfile.filename)
|
||||
fileName = fromNativePath(symtab.fullname())
|
||||
|
||||
if self.nativeMixed and functionName == "qt_qmlDebugEventFromService":
|
||||
if self.nativeMixed and functionName == "qt_qmlDebugMessageAvailable":
|
||||
interpreterStack = self.extractInterpreterStack()
|
||||
#print("EXTRACTED INTEPRETER STACK: %s" % interpreterStack)
|
||||
for interpreterFrame in interpreterStack.get('frames', []):
|
||||
@@ -1645,17 +1641,15 @@ class Dumper(DumperBase):
|
||||
self.dumper = dumper
|
||||
self.args = args
|
||||
spec = "qt_qmlDebugConnectorOpen"
|
||||
print("Preparing hook to resolve pending QML breakpoint at %s" % args)
|
||||
super(Resolver, self).\
|
||||
__init__(spec, gdb.BP_BREAKPOINT, internal=True, temporary=False)
|
||||
|
||||
def stop(self):
|
||||
bp = self.dumper.doInsertInterpreterBreakpoint(args, True)
|
||||
print("Resolving QML breakpoint %s -> %s" % (args, bp))
|
||||
self.dumper.resolvePendingInterpreterBreakpoint(args)
|
||||
self.enabled = False
|
||||
return False
|
||||
|
||||
self.interpreterBreakpoints.append(Resolver(self, args))
|
||||
self.interpreterBreakpointResolvers.append(Resolver(self, args))
|
||||
|
||||
def exitGdb(self, _):
|
||||
gdb.execute("quit")
|
||||
@@ -1804,26 +1798,14 @@ registerCommand("threadnames", threadnames)
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
class TriggeredBreakpointHookBreakpoint(gdb.Breakpoint):
|
||||
class InterpreterMessageBreakpoint(gdb.Breakpoint):
|
||||
def __init__(self):
|
||||
spec = "qt_v4TriggeredBreakpointHook"
|
||||
super(TriggeredBreakpointHookBreakpoint, self).\
|
||||
spec = "qt_qmlDebugMessageAvailable"
|
||||
super(InterpreterMessageBreakpoint, self).\
|
||||
__init__(spec, gdb.BP_BREAKPOINT, internal=True)
|
||||
|
||||
def stop(self):
|
||||
print("QML engine stopped.")
|
||||
return True
|
||||
print("Interpreter event received.")
|
||||
return theDumper.handleInterpreterMessage()
|
||||
|
||||
TriggeredBreakpointHookBreakpoint()
|
||||
|
||||
class QmlEngineEventBreakpoint(gdb.Breakpoint):
|
||||
def __init__(self):
|
||||
spec = "qt_qmlDebugEventFromService"
|
||||
super(QmlEngineEventBreakpoint, self).\
|
||||
__init__(spec, gdb.BP_BREAKPOINT, internal=True)
|
||||
|
||||
def stop(self):
|
||||
print("QML engine event received.")
|
||||
return theDumper.handleInterpreterEvent()
|
||||
|
||||
QmlEngineEventBreakpoint()
|
||||
InterpreterMessageBreakpoint()
|
||||
|
||||
@@ -48,9 +48,6 @@ from dumper import *
|
||||
|
||||
qqWatchpointOffset = 10000
|
||||
|
||||
def warn(message):
|
||||
print('\n\nWARNING="%s",\n' % message.encode("latin1").replace('"', "'"))
|
||||
|
||||
def showException(msg, exType, exValue, exTraceback):
|
||||
warn("**** CAUGHT EXCEPTION: %s ****" % msg)
|
||||
import traceback
|
||||
@@ -230,8 +227,7 @@ class Dumper(DumperBase):
|
||||
self.voidPtrType_ = None
|
||||
self.isShuttingDown_ = False
|
||||
self.isInterrupting_ = False
|
||||
self.qmlBreakpointResolvers = {}
|
||||
self.qmlTriggeredBreakpoint = None
|
||||
self.interpreterBreakpointResolvers = []
|
||||
|
||||
self.report('lldbversion=\"%s\"' % lldb.SBDebugger.GetVersionString())
|
||||
self.reportState("enginesetupok")
|
||||
@@ -549,7 +545,7 @@ class Dumper(DumperBase):
|
||||
self.report('error="%s"' % result.GetError())
|
||||
|
||||
def put(self, stuff):
|
||||
self.out += stuff
|
||||
self.output += stuff
|
||||
|
||||
def isMovableType(self, type):
|
||||
if type.GetTypeClass() in (lldb.eTypeClassBuiltin, lldb.eTypeClassPointer):
|
||||
@@ -667,6 +663,7 @@ class Dumper(DumperBase):
|
||||
self.sysRoot_ = args.get('sysRoot', '')
|
||||
self.remoteChannel_ = args.get('remoteChannel', '')
|
||||
self.platform_ = args.get('platform', '')
|
||||
self.nativeMixed = int(args.get('nativemixed', 0))
|
||||
|
||||
self.ignoreStops = 0
|
||||
self.silentStops = 0
|
||||
@@ -689,12 +686,15 @@ class Dumper(DumperBase):
|
||||
if self.sysRoot_:
|
||||
self.debugger.SetCurrentPlatformSDKRoot(self.sysRoot_)
|
||||
|
||||
|
||||
if os.path.isfile(self.executable_):
|
||||
self.target = self.debugger.CreateTarget(self.executable_, None, None, True, error)
|
||||
else:
|
||||
self.target = self.debugger.CreateTarget(None, None, None, True, error)
|
||||
|
||||
if self.nativeMixed:
|
||||
self.interpreterEventBreakpoint = \
|
||||
self.target.BreakpointCreateByName("qt_qmlDebugMessageAvailable")
|
||||
|
||||
state = 1 if self.target.IsValid() else 0
|
||||
self.reportResult('success="%s",msg="%s",exe="%s"' % (state, error, self.executable_), args)
|
||||
|
||||
@@ -775,9 +775,11 @@ class Dumper(DumperBase):
|
||||
def describeLocation(self, frame):
|
||||
if int(frame.pc) == 0xffffffffffffffff:
|
||||
return ''
|
||||
file = fileNameAsString(frame.line_entry.file)
|
||||
fileName = fileNameAsString(frame.line_entry.file)
|
||||
function = frame.GetFunctionName()
|
||||
line = frame.line_entry.line
|
||||
return 'location={file="%s",line="%s",addr="%s"}' % (file, line, frame.pc)
|
||||
return 'location={file="%s",line="%s",address="%s",function="%s"}' \
|
||||
% (fileName, line, frame.pc, function)
|
||||
|
||||
def currentThread(self):
|
||||
return None if self.process is None else self.process.GetSelectedThread()
|
||||
@@ -847,8 +849,6 @@ class Dumper(DumperBase):
|
||||
self.reportResult('msg="No thread"', args)
|
||||
return
|
||||
|
||||
self.report(self.describeLocation(thread.GetFrameAtIndex(0))) # FIXME
|
||||
|
||||
isNativeMixed = int(args.get('nativemixed', 0))
|
||||
|
||||
limit = args.get('stacklimit', -1)
|
||||
@@ -868,38 +868,27 @@ class Dumper(DumperBase):
|
||||
pc = frame.GetPC()
|
||||
level = frame.idx
|
||||
addr = frame.GetPCAddress().GetLoadAddress(self.target)
|
||||
|
||||
functionName = frame.GetFunctionName()
|
||||
|
||||
if isNativeMixed and functionName == "::qt_qmlDebugMessageAvailable()":
|
||||
interpreterStack = self.extractInterpreterStack()
|
||||
for interpreterFrame in interpreterStack.get('frames', []):
|
||||
function = interpreterFrame.get('function', '')
|
||||
fileName = interpreterFrame.get('file', '')
|
||||
language = interpreterFrame.get('language', '')
|
||||
lineNumber = interpreterFrame.get('line', 0)
|
||||
context = interpreterFrame.get('context', 0)
|
||||
result += ('frame={function="%s",file="%s",'
|
||||
'line="%s",language="%s",context="%s"}'
|
||||
% (function, fileName, lineNumber, language, context))
|
||||
|
||||
fileName = fileNameAsString(lineEntry.file)
|
||||
usable = None
|
||||
language = None
|
||||
|
||||
if False and isNativeMixed:
|
||||
if self.isReportableInterpreterFrame(functionName):
|
||||
engine = frame.FindVariable("engine")
|
||||
self.context = engine
|
||||
h = self.extractQmlLocation(engine)
|
||||
pc = 0
|
||||
functionName = h['function']
|
||||
fileName = h['file']
|
||||
lineNumber = h['line']
|
||||
addr = h['context']
|
||||
language = 'js'
|
||||
|
||||
#elif not functionName is None:
|
||||
# if functionName.startswith("qt_v4"):
|
||||
# usable = 0
|
||||
# elif functionName.find("QV4::") >= 0:
|
||||
# usable = 0
|
||||
|
||||
result += '{pc="0x%x"' % pc
|
||||
result += ',level="%d"' % level
|
||||
result += ',address="0x%x"' % addr
|
||||
if not usable is None:
|
||||
result += ',usable="%s"' % usable
|
||||
result += ',function="%s"' % functionName
|
||||
result += ',line="%d"' % lineNumber
|
||||
if not language is None:
|
||||
result += ',language="%s"' % language
|
||||
result += ',file="%s"},' % fileName
|
||||
result += ']'
|
||||
result += ',hasmore="%d"' % isLimited
|
||||
@@ -1155,16 +1144,28 @@ class Dumper(DumperBase):
|
||||
with SubItem(self, child):
|
||||
self.putItem(child)
|
||||
|
||||
def reportVariables(self, args):
|
||||
self.out = ""
|
||||
self.reportVariablesHelper(args)
|
||||
self.reportResult(self.out, args)
|
||||
|
||||
def reportVariablesHelper(self, args = {}):
|
||||
frame = self.currentFrame()
|
||||
if frame is None:
|
||||
def fetchVariables(self, args):
|
||||
(ok, res) = self.tryFetchInterpreterVariables(args)
|
||||
if ok:
|
||||
self.reportResult(res, args)
|
||||
return
|
||||
|
||||
self.expandedINames = set(args.get('expanded', []))
|
||||
self.autoDerefPointers = int(args.get('autoderef', '0'))
|
||||
self.sortStructMembers = bool(args.get('sortStructMembers', True));
|
||||
self.useDynamicType = int(args.get('dyntype', '0'))
|
||||
self.useFancy = int(args.get('fancy', '0'))
|
||||
self.passExceptions = int(args.get('passexceptions', '0'))
|
||||
self.currentWatchers = args.get('watchers', {})
|
||||
self.typeformats = args.get("typeformats", {})
|
||||
self.formats = args.get("formats", {})
|
||||
|
||||
frame = self.currentFrame()
|
||||
if frame is None:
|
||||
self.reportResult('error="No frame"', args)
|
||||
return
|
||||
|
||||
self.output = ''
|
||||
partialVariable = args.get("partialVariable", "")
|
||||
isPartial = len(partialVariable) > 0
|
||||
|
||||
@@ -1232,6 +1233,7 @@ class Dumper(DumperBase):
|
||||
self.handleWatches(args)
|
||||
|
||||
self.put('],partial="%d"' % isPartial)
|
||||
self.reportResult(self.output, args)
|
||||
|
||||
def fetchRegisters(self, args = None):
|
||||
if self.process is None:
|
||||
@@ -1281,7 +1283,7 @@ class Dumper(DumperBase):
|
||||
else:
|
||||
self.isInterrupting_ = True
|
||||
error = self.process.Stop()
|
||||
self.reportResult(describeError(error), args)
|
||||
self.reportResult(self.describeError(error), args)
|
||||
|
||||
def detachInferior(self, args):
|
||||
if self.process is None:
|
||||
@@ -1330,28 +1332,31 @@ class Dumper(DumperBase):
|
||||
frame = stoppedThread.GetFrameAtIndex(0)
|
||||
#self.report("FRAME: %s" % frame)
|
||||
function = frame.GetFunction()
|
||||
#self.report("FUNCTION: %s" % function)
|
||||
if function.GetName() == "qt_v4ResolvePendingBreakpointsHook":
|
||||
#self.report("RESOLVER HIT")
|
||||
for bp in self.qmlBreakpointResolvers:
|
||||
self.qmlBreakpointResolvers[bp]()
|
||||
self.target.BreakpointDelete(bp.GetID())
|
||||
self.qmlBreakpointResolvers = {}
|
||||
functionName = function.GetName()
|
||||
if functionName == "::qt_qmlDebugConnectorOpen()":
|
||||
self.report("RESOLVER HIT")
|
||||
for resolver in self.interpreterBreakpointResolvers:
|
||||
resolver()
|
||||
self.report("AUTO-CONTINUE AFTER RESOLVING")
|
||||
self.reportState("inferiorstopok")
|
||||
self.process.Continue();
|
||||
return
|
||||
if functionName == "::qt_qmlDebugMessageAvailable()":
|
||||
self.report("ASYNC MESSAGE FROM SERVICE")
|
||||
res = self.handleInterpreterMessage()
|
||||
if not res:
|
||||
self.report("EVENT NEEDS NO STOP")
|
||||
self.reportState("stopped")
|
||||
self.process.Continue();
|
||||
return
|
||||
|
||||
if self.isInterrupting_:
|
||||
self.isInterrupting_ = False
|
||||
self.reportState("inferiorstopok")
|
||||
self.reportState("stopped")
|
||||
elif self.ignoreStops > 0:
|
||||
self.ignoreStops -= 1
|
||||
self.process.Continue()
|
||||
elif self.silentStops > 0:
|
||||
self.silentStops -= 1
|
||||
#elif bp and bp in self.qmlBreakpointResolvers:
|
||||
# self.report("RESOLVER HIT")
|
||||
# self.qmlBreakpointResolvers[bp]()
|
||||
# self.process.Continue();
|
||||
else:
|
||||
self.reportState("stopped")
|
||||
else:
|
||||
@@ -1422,7 +1427,7 @@ class Dumper(DumperBase):
|
||||
if bpType == BreakpointByFileAndLine:
|
||||
fileName = args["file"]
|
||||
if fileName.endswith(".js") or fileName.endswith(".qml"):
|
||||
self.doInsertInterpreterBreakpoint(args, False)
|
||||
self.insertInterpreterBreakpoint(args)
|
||||
return
|
||||
|
||||
extra = ''
|
||||
@@ -1645,19 +1650,6 @@ class Dumper(DumperBase):
|
||||
error = str(result.GetError())
|
||||
self.report('success="%d",output="%s",error="%s"' % (success, output, error))
|
||||
|
||||
def fetchLocals(self, args):
|
||||
self.output = ''
|
||||
self.expandedINames = set(args.get('expanded', []))
|
||||
self.autoDerefPointers = int(args.get('autoderef', '0'))
|
||||
self.sortStructMembers = bool(args.get("sortStructMembers", True));
|
||||
self.useDynamicType = int(args.get('dyntype', '0'))
|
||||
self.useFancy = int(args.get('fancy', '0'))
|
||||
self.passExceptions = int(args.get('passexceptions', '0'))
|
||||
self.currentWatchers = args.get('watchers', {})
|
||||
self.typeformats = args.get("typeformats", {})
|
||||
self.formats = args.get("formats", {})
|
||||
self.reportVariables(args)
|
||||
|
||||
def fetchDisassembler(self, args):
|
||||
functionName = args.get('function', '')
|
||||
flavor = args.get('flavor', '')
|
||||
@@ -1744,17 +1736,13 @@ class Dumper(DumperBase):
|
||||
value = self.hexdecode(args['value'])
|
||||
lhs = self.findValueByExpression(exp)
|
||||
lhs.SetValueFromCString(value, error)
|
||||
self.reportResult(describeError(error), args)
|
||||
self.reportResult(self.describeError(error), args)
|
||||
|
||||
def createResolvePendingBreakpointsHookBreakpoint(self, args):
|
||||
if self.qmlTriggeredBreakpoint is None:
|
||||
self.qmlTriggeredBreakpoint = \
|
||||
self.target.BreakpointCreateByName("qt_v4TriggeredBreakpointHook")
|
||||
|
||||
bp = self.target.BreakpointCreateByName("qt_v4ResolvePendingBreakpointsHook")
|
||||
bp = self.target.BreakpointCreateByName("qt_qmlDebugConnectorOpen")
|
||||
bp.SetOneShot(True)
|
||||
self.qmlBreakpointResolvers[bp] = lambda: \
|
||||
self.doInsertQmlBreakpoint(args)
|
||||
self.interpreterBreakpointResolvers.append(
|
||||
lambda: self.resolvePendingInterpreterBreakpoint(args))
|
||||
|
||||
|
||||
# Used in dumper auto test.
|
||||
@@ -1825,7 +1813,7 @@ class Tester(Dumper):
|
||||
if line != 0:
|
||||
self.report = savedReport
|
||||
self.process.SetSelectedThread(stoppedThread)
|
||||
self.reportVariables({'token':2})
|
||||
self.fetchVariables({'token':2, 'fancy':1})
|
||||
#self.describeLocation(frame)
|
||||
self.report("@NS@%s@" % self.qtNamespace())
|
||||
#self.report("ENV=%s" % os.environ.items())
|
||||
|
||||
@@ -2308,7 +2308,7 @@ def qdump__QV4__String(d, value):
|
||||
d.putStringValue(d.addressOf(value) + 2 * d.ptrSize())
|
||||
|
||||
def qdump__QV4__Value(d, value):
|
||||
v = toInteger(str(value["val"]))
|
||||
v = toInteger(str(value["_val"]))
|
||||
NaNEncodeMask = 0xffff800000000000
|
||||
IsInt32Mask = 0x0002000000000000
|
||||
IsDoubleMask = 0xfffc000000000000
|
||||
@@ -2319,7 +2319,10 @@ def qdump__QV4__Value(d, value):
|
||||
ns = d.qtNamespace()
|
||||
if v & IsInt32Mask:
|
||||
d.putBetterType("%sQV4::Value (int32)" % ns)
|
||||
d.putValue(value["int_32"])
|
||||
vv = v & 0xffffffff
|
||||
vv = vv if vv < 0x80000000 else -(0x100000000 - vv)
|
||||
d.putBetterType("%sQV4::Value (int32)" % ns)
|
||||
d.putValue("%d" % vv)
|
||||
elif v & IsDoubleMask:
|
||||
d.putBetterType("%sQV4::Value (double)" % ns)
|
||||
d.putValue("%x" % (v ^ 0xffff800000000000), Hex2EncodedFloat8)
|
||||
@@ -2332,6 +2335,7 @@ def qdump__QV4__Value(d, value):
|
||||
elif v & IsNullOrBooleanMask:
|
||||
d.putBetterType("%sQV4::Value (null/bool)" % ns)
|
||||
d.putValue("(null/bool)")
|
||||
d.putValue(v & 1)
|
||||
else:
|
||||
vtable = value["m"]["vtable"]
|
||||
if toInteger(vtable["isString"]):
|
||||
|
||||
@@ -53,6 +53,129 @@ public:
|
||||
$$
|
||||
} else {
|
||||
}</snippet>
|
||||
<snippet group="C++" trigger="lic" id="license-configured" complement="" removed="false" modified="false">%{Cpp:LicenseTemplate}
|
||||
$$</snippet>
|
||||
<snippet group="C++" trigger="licbsd" id="license-bsd" complement="" removed="false" modified="false">/**
|
||||
@if ('%{CurrentProject:Name}' !== '')
|
||||
** This file is part of the %{CurrentProject:Name} project.
|
||||
@endif
|
||||
@if ('%{Env:QTC_COPYRIGHT_USER}' === '' || '%{Env:QTC_COPYRIGHT_EMAIL}' === '')
|
||||
** Copyright %{CurrentDate:yyyy} $copyright_user$ <$copyright_email$>.
|
||||
@else
|
||||
** Copyright %{CurrentDate:yyyy} %{Env:QTC_COPYRIGHT_USER} <%{Env:QTC_COPYRIGHT_EMAIL}>.
|
||||
@endif
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright notice,
|
||||
** this list of conditions and the following disclaimer.
|
||||
**
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
** SUCH DAMAGE.
|
||||
**/
|
||||
|
||||
$$</snippet>
|
||||
<snippet group="C++" trigger="licgpl" id="license-gpl" complement="" removed="false" modified="false">/**
|
||||
@if ('%{CurrentProject:Name}' !== '')
|
||||
** This file is part of the %{CurrentProject:Name} project.
|
||||
@endif
|
||||
@if ('%{Env:QTC_COPYRIGHT_USER}' === '' || '%{Env:QTC_COPYRIGHT_EMAIL}' === '')
|
||||
** Copyright %{CurrentDate:yyyy} $copyright_user$ <$copyright_email$>.
|
||||
@else
|
||||
** Copyright %{CurrentDate:yyyy} %{Env:QTC_COPYRIGHT_USER} <%{Env:QTC_COPYRIGHT_EMAIL}>.
|
||||
@endif
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
$$</snippet>
|
||||
<snippet group="C++" trigger="liclgpl" id="license-lgpl" complement="" removed="false" modified="false">/**
|
||||
@if ('%{CurrentProject:Name}' !== '')
|
||||
** This file is part of the %{CurrentProject:Name} project.
|
||||
@endif
|
||||
@if ('%{Env:QTC_COPYRIGHT_USER}' === '' || '%{Env:QTC_COPYRIGHT_EMAIL}' === '')
|
||||
** Copyright %{CurrentDate:yyyy} $copyright_user$ <$copyright_email$>.
|
||||
@else
|
||||
** Copyright %{CurrentDate:yyyy} %{Env:QTC_COPYRIGHT_USER} <%{Env:QTC_COPYRIGHT_EMAIL}>.
|
||||
@endif
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU Lesser General Public License as
|
||||
** published by the Free Software Foundation, either version 3 of the
|
||||
** License, or (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU Lesser General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU Lesser General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
$$</snippet>
|
||||
<snippet group="C++" trigger="licqtc" id="license-qtc" complement="" removed="false" modified="false">/****************************************************************************
|
||||
**
|
||||
@if ('%{Env:QTC_COPYRIGHT_USER}' === '' || '%{Env:QTC_COPYRIGHT_EMAIL}' === '')
|
||||
** Copyright (C) %{CurrentDate:yyyy} $copyright_user$ <$copyright_email$>.
|
||||
@else
|
||||
** Copyright (C) %{CurrentDate:yyyy} %{Env:QTC_COPYRIGHT_USER} <%{Env:QTC_COPYRIGHT_EMAIL}>.
|
||||
@endif
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of %{CurrentProject:Name}
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
$$</snippet>
|
||||
<snippet group="C++" trigger="namespace" id="cpp_namespace">namespace $name$ {
|
||||
$$
|
||||
}</snippet>
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
%{Cpp:LicenseTemplate}\
|
||||
#include "%{HdrFileName}"
|
||||
%{JS: Cpp.openNamespaces('%{Class}')}\
|
||||
|
||||
%{CN}::%{CN}(QObject *parent)
|
||||
: %{Base}(parent)
|
||||
{
|
||||
}
|
||||
@if %{CustomHeader}
|
||||
|
||||
QVariant %{CN}::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
@if %{Editable}
|
||||
|
||||
bool %{CN}::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
if (value != headerData(section, orientation, role)) {
|
||||
// FIXME: Implement me!
|
||||
emit headerDataChanged(orientation, section, section);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@endif
|
||||
@endif
|
||||
|
||||
QModelIndex %{CN}::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
QModelIndex %{CN}::parent(const QModelIndex &index) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
int %{CN}::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return 0;
|
||||
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
int %{CN}::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return 0;
|
||||
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
@if %{DynamicFetch}
|
||||
|
||||
bool %{CN}::hasChildren(const QModelIndex &parent) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
bool %{CN}::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
return false;
|
||||
}
|
||||
|
||||
void %{CN}::fetchMore(const QModelIndex &parent)
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
@endif
|
||||
|
||||
QVariant %{CN}::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
// FIXME: Implement me!
|
||||
return QVariant();
|
||||
}
|
||||
@if %{Editable}
|
||||
|
||||
bool %{CN}::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (data(index, role) != value) {
|
||||
// FIXME: Implement me!
|
||||
emit dataChanged(index, index, QVector<int>() << role);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags %{CN}::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsEditable; // FIXME: Implement me!
|
||||
}
|
||||
@endif
|
||||
@if %{AddData}
|
||||
|
||||
bool %{CN}::insertRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginInsertRows(parent, row, row + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
bool %{CN}::insertColumns(int column, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginInsertColumns(parent, column, column + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endInsertColumns();
|
||||
}
|
||||
@endif
|
||||
@if %{RemoveData}
|
||||
|
||||
bool %{CN}::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
bool %{CN}::removeColumns(int column, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginRemoveColumns(parent, column, column + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endRemoveColumns();
|
||||
}
|
||||
@endif
|
||||
%{JS: Cpp.closeNamespaces('%{Class}')}\
|
||||
@@ -0,0 +1,65 @@
|
||||
%{Cpp:LicenseTemplate}\
|
||||
#ifndef %{GUARD}
|
||||
#define %{GUARD}
|
||||
|
||||
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
|
||||
%{JS: Cpp.openNamespaces('%{Class}')}\
|
||||
|
||||
class %{CN} : public %{Base}
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit %{CN}(QObject *parent = 0);
|
||||
|
||||
@if %{CustomHeader}
|
||||
// Header:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
@if %{Editable}
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
@endif
|
||||
@endif
|
||||
// Basic functionality:
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
@if %{DynamicFetch}
|
||||
// Fetch data dynamically:
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool canFetchMore(const QModelIndex &parent) const override;
|
||||
void fetchMore(const QModelIndex &parent) override;
|
||||
|
||||
@endif
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
@if %{Editable}
|
||||
// Editable:
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole) override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
|
||||
@endif
|
||||
@if %{AddData}
|
||||
// Add data:
|
||||
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
@endif
|
||||
@if %{RemoveData}
|
||||
// Remove data:
|
||||
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
@endif
|
||||
private:
|
||||
};
|
||||
%{JS: Cpp.closeNamespaces('%{Class}')}
|
||||
#endif // %{GUARD}\
|
||||
@@ -0,0 +1,83 @@
|
||||
%{Cpp:LicenseTemplate}\
|
||||
#include "%{HdrFileName}"
|
||||
%{JS: Cpp.openNamespaces('%{Class}')}\
|
||||
|
||||
%{CN}::%{CN}(QObject *parent)
|
||||
: %{Base}(parent)
|
||||
{
|
||||
}
|
||||
@if %{CustomHeader}
|
||||
|
||||
QVariant %{CN}::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
@if %{Editable}
|
||||
|
||||
bool %{CN}::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
if (value != headerData(section, orientation, role)) {
|
||||
// FIXME: Implement me!
|
||||
emit headerDataChanged(orientation, section, section);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@endif
|
||||
@endif
|
||||
|
||||
int %{CN}::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return 0;
|
||||
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
QVariant %{CN}::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
// FIXME: Implement me!
|
||||
return QVariant();
|
||||
}
|
||||
@if %{Editable}
|
||||
|
||||
bool %{CN}::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (data(index, role) != value) {
|
||||
// FIXME: Implement me!
|
||||
emit dataChanged(index, index, QVector<int>() << role);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags %{CN}::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsEditable; // FIXME: Implement me!
|
||||
}
|
||||
@endif
|
||||
@if %{AddData}
|
||||
|
||||
bool %{CN}::insertRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginInsertRows(parent, row, row + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endInsertRows();
|
||||
}
|
||||
@endif
|
||||
@if %{RemoveData}
|
||||
|
||||
bool %{CN}::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endRemoveRows();
|
||||
}
|
||||
@endif
|
||||
%{JS: Cpp.closeNamespaces('%{Class}')}\
|
||||
@@ -0,0 +1,50 @@
|
||||
%{Cpp:LicenseTemplate}\
|
||||
#ifndef %{GUARD}
|
||||
#define %{GUARD}
|
||||
|
||||
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
|
||||
%{JS: Cpp.openNamespaces('%{Class}')}\
|
||||
|
||||
class %{CN} : public %{Base}
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit %{CN}(QObject *parent = 0);
|
||||
|
||||
@if %{CustomHeader}
|
||||
// Header:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
@if %{Editable}
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
@endif
|
||||
@endif
|
||||
// Basic functionality:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
@if %{Editable}
|
||||
// Editable:
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole) override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
|
||||
@endif
|
||||
@if %{AddData}
|
||||
// Add data:
|
||||
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
@endif
|
||||
@if %{RemoveData}
|
||||
// Remove data:
|
||||
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
@endif
|
||||
private:
|
||||
};
|
||||
%{JS: Cpp.closeNamespaces('%{Class}')}
|
||||
#endif // %{GUARD}\
|
||||
@@ -0,0 +1,106 @@
|
||||
%{Cpp:LicenseTemplate}\
|
||||
#include "%{HdrFileName}"
|
||||
%{JS: Cpp.openNamespaces('%{Class}')}\
|
||||
|
||||
%{CN}::%{CN}(QObject *parent)
|
||||
: %{Base}(parent)
|
||||
{
|
||||
}
|
||||
@if %{CustomHeader}
|
||||
|
||||
QVariant %{CN}::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
@if %{Editable}
|
||||
|
||||
bool %{CN}::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
if (value != headerData(section, orientation, role)) {
|
||||
// FIXME: Implement me!
|
||||
emit headerDataChanged(orientation, section, section);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@endif
|
||||
@endif
|
||||
|
||||
int %{CN}::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return 0;
|
||||
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
int %{CN}::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return 0;
|
||||
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
QVariant %{CN}::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
// FIXME: Implement me!
|
||||
return QVariant();
|
||||
}
|
||||
@if %{Editable}
|
||||
|
||||
bool %{CN}::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (data(index, role) != value) {
|
||||
// FIXME: Implement me!
|
||||
emit dataChanged(index, index, QVector<int>() << role);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags %{CN}::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsEditable; // FIXME: Implement me!
|
||||
}
|
||||
@endif
|
||||
@if %{AddData}
|
||||
|
||||
bool %{CN}::insertRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginInsertRows(parent, row, row + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
bool %{CN}::insertColumns(int column, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginInsertColumns(parent, column, column + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endInsertColumns();
|
||||
}
|
||||
@endif
|
||||
@if %{RemoveData}
|
||||
|
||||
bool %{CN}::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
bool %{CN}::removeColumns(int column, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginRemoveColumns(parent, column, column + count - 1);
|
||||
// FIXME: Implement me!
|
||||
endRemoveColumns();
|
||||
}
|
||||
@endif
|
||||
%{JS: Cpp.closeNamespaces('%{Class}')}\
|
||||
@@ -0,0 +1,53 @@
|
||||
%{Cpp:LicenseTemplate}\
|
||||
#ifndef %{GUARD}
|
||||
#define %{GUARD}
|
||||
|
||||
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
|
||||
%{JS: Cpp.openNamespaces('%{Class}')}\
|
||||
|
||||
class %{CN} : public %{Base}
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit %{CN}(QObject *parent = 0);
|
||||
|
||||
@if %{CustomHeader}
|
||||
// Header:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
@if %{Editable}
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
@endif
|
||||
@endif
|
||||
// Basic functionality:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
@if %{Editable}
|
||||
// Editable:
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole) override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
|
||||
@endif
|
||||
@if %{AddData}
|
||||
// Add data:
|
||||
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
@endif
|
||||
@if %{RemoveData}
|
||||
// Remove data:
|
||||
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
@endif
|
||||
private:
|
||||
};
|
||||
%{JS: Cpp.closeNamespaces('%{Class}')}
|
||||
#endif // %{GUARD}\
|
||||
202
share/qtcreator/templates/wizards/classes/itemmodel/wizard.json
Normal file
202
share/qtcreator/templates/wizards/classes/itemmodel/wizard.json
Normal file
@@ -0,0 +1,202 @@
|
||||
{
|
||||
"version": 1,
|
||||
"kind": "file",
|
||||
"id": "A.ItemView",
|
||||
"category": "R.Qt",
|
||||
"trDescription": "Creates a Qt item model.",
|
||||
"trDisplayName": "Qt Item Model",
|
||||
"trDisplayCategory": "Qt",
|
||||
"icon": "../../global/genericfilewizard.png",
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('CppEditor') >= 0}",
|
||||
|
||||
"options":
|
||||
[
|
||||
{ "key": "TargetPath", "value": "%{Path}" },
|
||||
{ "key": "HdrPath", "value": "%{Path}/%{HdrFileName}" },
|
||||
{ "key": "SrcPath", "value": "%{Path}/%{SrcFileName}" },
|
||||
{ "key": "CN", "value": "%{JS: Cpp.className('%{Class}')}" },
|
||||
{ "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard('%{Class}', '%{JS: Util.preferredSuffix('text/x-c++hdr')}')}" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
[
|
||||
{
|
||||
"trDisplayName": "Define Item Model Class",
|
||||
"trShortTitle": "Details",
|
||||
"typeId": "Fields",
|
||||
"data" :
|
||||
[
|
||||
{
|
||||
"name": "Class",
|
||||
"trDisplayName": "Class name:",
|
||||
"mandatory": true,
|
||||
"type": "LineEdit",
|
||||
"data": { "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)+[a-zA-Z_][a-zA-Z_0-9]*|)" }
|
||||
},
|
||||
{
|
||||
"name": "Base",
|
||||
"trDisplayName": "Base class:",
|
||||
"type": "ComboBox",
|
||||
"data":
|
||||
{
|
||||
"items": [ "QAbstractItemModel", "QAbstractTableModel", "QAbstractListModel" ]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Sp1",
|
||||
"type": "Spacer",
|
||||
"data": { "factor": 2 }
|
||||
},
|
||||
{
|
||||
"name": "CustomHeader",
|
||||
"trDisplayName": "Customize header row",
|
||||
"type": "CheckBox",
|
||||
"data": {
|
||||
"checked": true,
|
||||
"checkedValue": true,
|
||||
"uncheckedValue": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Editable",
|
||||
"trDisplayName": "Items are editable",
|
||||
"type": "CheckBox",
|
||||
"data": {
|
||||
"checked": false,
|
||||
"checkedValue": true,
|
||||
"uncheckedValue": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AddData",
|
||||
"trDisplayName": "Rows and columns can be added",
|
||||
"type": "CheckBox",
|
||||
"data": {
|
||||
"checked": false,
|
||||
"checkedValue": true,
|
||||
"uncheckedValue": false
|
||||
}
|
||||
}, {
|
||||
"name": "RemoveData",
|
||||
"trDisplayName": "Rows and columns can be removed",
|
||||
"type": "CheckBox",
|
||||
"data": {
|
||||
"checked": false,
|
||||
"checkedValue": true,
|
||||
"uncheckedValue": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DynamicFetch",
|
||||
"trDisplayName": "Fetch data dynamically",
|
||||
"type": "CheckBox",
|
||||
"data": {
|
||||
"checked": false,
|
||||
"checkedValue": true,
|
||||
"uncheckedValue": false
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "HdrFileName",
|
||||
"type": "LineEdit",
|
||||
"trDisplayName": "Header file:",
|
||||
"mandatory": true,
|
||||
"data": { "trText": "%{JS: Cpp.classToFileName('%{Class}', '%{JS: Util.preferredSuffix('text/x-c++hdr')}')}" }
|
||||
},
|
||||
{
|
||||
"name": "SrcFileName",
|
||||
"type": "LineEdit",
|
||||
"trDisplayName": "Source file:",
|
||||
"mandatory": true,
|
||||
"data": { "trText": "%{JS: Cpp.classToFileName('%{Class}', '%{JS: Util.preferredSuffix('text/x-c++src')}')}" }
|
||||
},
|
||||
{
|
||||
"name": "Path",
|
||||
"type": "PathChooser",
|
||||
"trDisplayName": "Path:",
|
||||
"mandatory": true,
|
||||
"data":
|
||||
{
|
||||
"kind": "existingDirectory",
|
||||
"basePath": "%{InitialPath}",
|
||||
"path": "%{InitialPath}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"trDisplayName": "Project Management",
|
||||
"trShortTitle": "Summary",
|
||||
"typeId": "Summary"
|
||||
}
|
||||
],
|
||||
|
||||
"generators":
|
||||
[
|
||||
{
|
||||
"typeId": "File",
|
||||
"data":
|
||||
[
|
||||
{
|
||||
"source": "itemmodel.h",
|
||||
"target": "%{HdrPath}",
|
||||
"condition": "%{JS: '%{Base}' === 'QAbstractItemModel'}",
|
||||
"options": [
|
||||
{ "key": "Cpp:License:FileName", "value": "%{HdrFileName}" },
|
||||
{ "key": "Cpp:License:ClassName", "value": "%{CN}" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "itemmodel.cpp",
|
||||
"target": "%{SrcPath}",
|
||||
"openInEditor": true,
|
||||
"condition": "%{JS: '%{Base}' === 'QAbstractItemModel'}",
|
||||
"options": [
|
||||
{ "key": "Cpp:License:FileName", "value": "%{SrcFileName}" },
|
||||
{ "key": "Cpp:License:ClassName", "value": "%{CN}" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "tablemodel.h",
|
||||
"target": "%{HdrPath}",
|
||||
"condition": "%{JS: '%{Base}' === 'QAbstractTableModel'}",
|
||||
"options": [
|
||||
{ "key": "Cpp:License:FileName", "value": "%{HdrFileName}" },
|
||||
{ "key": "Cpp:License:ClassName", "value": "%{CN}" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "tablemodel.cpp",
|
||||
"target": "%{SrcPath}",
|
||||
"openInEditor": true,
|
||||
"condition": "%{JS: '%{Base}' === 'QAbstractTableModel'}",
|
||||
"options": [
|
||||
{ "key": "Cpp:License:FileName", "value": "%{SrcFileName}" },
|
||||
{ "key": "Cpp:License:ClassName", "value": "%{CN}" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "listmodel.h",
|
||||
"target": "%{HdrPath}",
|
||||
"condition": "%{JS: '%{Base}' === 'QAbstractListModel'}",
|
||||
"options": [
|
||||
{ "key": "Cpp:License:FileName", "value": "%{HdrFileName}" },
|
||||
{ "key": "Cpp:License:ClassName", "value": "%{CN}" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "listmodel.cpp",
|
||||
"target": "%{SrcPath}",
|
||||
"openInEditor": true,
|
||||
"condition": "%{JS: '%{Base}' === 'QAbstractListModel'}",
|
||||
"options": [
|
||||
{ "key": "Cpp:License:FileName", "value": "%{SrcFileName}" },
|
||||
{ "key": "Cpp:License:ClassName", "value": "%{CN}" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
QT += core
|
||||
QT -= gui
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
TARGET = %{ProjectName}
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
|
||||
@@ -2,6 +2,8 @@ TEMPLATE = app
|
||||
|
||||
QT += qml quick
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
@@ -6,6 +6,8 @@ QT += qml quick widgets
|
||||
QT += qml quick
|
||||
@endif
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += %{MainCppFileName}
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
@@ -96,42 +96,35 @@ const char PLUGINPATH_OPTION[] = "-pluginpath";
|
||||
typedef QList<PluginSpec *> PluginSpecSet;
|
||||
|
||||
// Helpers for displaying messages. Note that there is no console on Windows.
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
// Format as <pre> HTML
|
||||
static inline void toHtml(QString &t)
|
||||
static inline QString toHtml(const QString &t)
|
||||
{
|
||||
t.replace(QLatin1Char('&'), QLatin1String("&"));
|
||||
t.replace(QLatin1Char('<'), QLatin1String("<"));
|
||||
t.replace(QLatin1Char('>'), QLatin1String(">"));
|
||||
t.insert(0, QLatin1String("<html><pre>"));
|
||||
t.append(QLatin1String("</pre></html>"));
|
||||
QString res = t;
|
||||
res.replace(QLatin1Char('&'), QLatin1String("&"));
|
||||
res.replace(QLatin1Char('<'), QLatin1String("<"));
|
||||
res.replace(QLatin1Char('>'), QLatin1String(">"));
|
||||
res.insert(0, QLatin1String("<html><pre>"));
|
||||
res.append(QLatin1String("</pre></html>"));
|
||||
return res;
|
||||
}
|
||||
|
||||
static void displayHelpText(QString t) // No console on Windows.
|
||||
{
|
||||
toHtml(t);
|
||||
QMessageBox::information(0, QLatin1String(appNameC), t);
|
||||
}
|
||||
|
||||
static void displayError(const QString &t) // No console on Windows.
|
||||
{
|
||||
QMessageBox::critical(0, QLatin1String(appNameC), t);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void displayHelpText(const QString &t)
|
||||
{
|
||||
if (Utils::HostOsInfo::isWindowsHost())
|
||||
QMessageBox::information(0, QLatin1String(appNameC), toHtml(t));
|
||||
else
|
||||
qWarning("%s", qPrintable(t));
|
||||
}
|
||||
|
||||
static void displayError(const QString &t)
|
||||
{
|
||||
if (Utils::HostOsInfo::isWindowsHost())
|
||||
QMessageBox::critical(0, QLatin1String(appNameC), t);
|
||||
else
|
||||
qCritical("%s", qPrintable(t));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void printVersion(const PluginSpec *coreplugin)
|
||||
{
|
||||
QString version;
|
||||
@@ -200,19 +193,19 @@ static inline QStringList getPluginPaths()
|
||||
QDir rootDir = QApplication::applicationDirPath();
|
||||
rootDir.cdUp();
|
||||
const QString rootDirPath = rootDir.canonicalPath();
|
||||
#if !defined(Q_OS_MAC)
|
||||
// 1) "plugins" (Win/Linux)
|
||||
QString pluginPath = rootDirPath;
|
||||
QString pluginPath;
|
||||
if (Utils::HostOsInfo::isMacHost()) {
|
||||
// 1) "PlugIns" (OS X)
|
||||
pluginPath = rootDirPath + QLatin1String("/PlugIns");
|
||||
rc.push_back(pluginPath);
|
||||
} else {
|
||||
// 2) "plugins" (Win/Linux)
|
||||
pluginPath = rootDirPath;
|
||||
pluginPath += QLatin1Char('/');
|
||||
pluginPath += QLatin1String(IDE_LIBRARY_BASENAME);
|
||||
pluginPath += QLatin1String("/qtcreator/plugins");
|
||||
rc.push_back(pluginPath);
|
||||
#else
|
||||
// 2) "PlugIns" (OS X)
|
||||
QString pluginPath = rootDirPath;
|
||||
pluginPath += QLatin1String("/PlugIns");
|
||||
rc.push_back(pluginPath);
|
||||
#endif
|
||||
}
|
||||
// 3) <localappdata>/plugins/<ideversion>
|
||||
// where <localappdata> is e.g.
|
||||
// "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later
|
||||
@@ -225,11 +218,7 @@ static inline QStringList getPluginPaths()
|
||||
pluginPath += QLatin1Char('/')
|
||||
+ QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR)
|
||||
+ QLatin1Char('/');
|
||||
#if !defined(Q_OS_MAC)
|
||||
pluginPath += QLatin1String("qtcreator");
|
||||
#else
|
||||
pluginPath += QLatin1String("Qt Creator");
|
||||
#endif
|
||||
pluginPath += QLatin1String(Utils::HostOsInfo::isMacHost() ? "Qt Creator" : "qtcreator");
|
||||
pluginPath += QLatin1String("/plugins/");
|
||||
pluginPath += QLatin1String(Core::Constants::IDE_VERSION_LONG);
|
||||
rc.push_back(pluginPath);
|
||||
@@ -286,11 +275,8 @@ static inline QSettings *userSettings()
|
||||
return createUserSettings();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
# define SHARE_PATH "/../Resources"
|
||||
#else
|
||||
# define SHARE_PATH "/../share/qtcreator"
|
||||
#endif
|
||||
static const char *SHARE_PATH =
|
||||
Utils::HostOsInfo::isMacHost() ? "/../Resources" : "/../share/qtcreator";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@@ -391,7 +377,7 @@ int main(int argc, char **argv)
|
||||
if (!overrideLanguage.isEmpty())
|
||||
uiLanguages.prepend(overrideLanguage);
|
||||
const QString &creatorTrPath = QCoreApplication::applicationDirPath()
|
||||
+ QLatin1String(SHARE_PATH "/translations");
|
||||
+ QLatin1String(SHARE_PATH) + QLatin1String("/translations");
|
||||
foreach (QString locale, uiLanguages) {
|
||||
locale = QLocale(locale).name();
|
||||
if (translator.load(QLatin1String("qtcreator_") + locale, creatorTrPath)) {
|
||||
|
||||
@@ -50,6 +50,7 @@ DObject::DObject()
|
||||
DObject::DObject(const DObject &rhs)
|
||||
: DElement(rhs),
|
||||
_model_uid(rhs._model_uid),
|
||||
_stereotypes(rhs._stereotypes),
|
||||
_context(rhs._context),
|
||||
_name(rhs._name),
|
||||
_pos(rhs._pos),
|
||||
@@ -72,6 +73,7 @@ DObject &DObject::operator =(const DObject &rhs)
|
||||
if (this != &rhs) {
|
||||
DElement::operator=(rhs);
|
||||
_model_uid = rhs._model_uid;
|
||||
_stereotypes = rhs._stereotypes;
|
||||
_context = rhs._context;
|
||||
_name = rhs._name;
|
||||
_pos = rhs._pos;
|
||||
|
||||
@@ -393,7 +393,7 @@ void PropertiesView::MView::visitMElement(const MElement *element)
|
||||
_stereotype_combo_box = new QComboBox(_top_widget);
|
||||
_stereotype_combo_box->setEditable(true);
|
||||
_stereotype_combo_box->setInsertPolicy(QComboBox::NoInsert);
|
||||
_top_layout->addRow(tr("Stereotypes"), _stereotype_combo_box);
|
||||
_top_layout->addRow(tr("Stereotypes:"), _stereotype_combo_box);
|
||||
_stereotype_combo_box->addItems(_properties_view->getStereotypeController()->getKnownStereotypes(_stereotype_element));
|
||||
connect(_stereotype_combo_box->lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(onStereotypesChanged(QString)));
|
||||
connect(_stereotype_combo_box, SIGNAL(activated(QString)), this, SLOT(onStereotypesChanged(QString)));
|
||||
@@ -414,7 +414,7 @@ void PropertiesView::MView::visitMElement(const MElement *element)
|
||||
#ifdef SHOW_DEBUG_PROPERTIES
|
||||
if (_reverse_engineered_label == 0) {
|
||||
_reverse_engineered_label = new QLabel(_top_widget);
|
||||
_top_layout->addRow(tr("Reverese Engineered"), _reverse_engineered_label);
|
||||
_top_layout->addRow(tr("Reverese engineered:"), _reverse_engineered_label);
|
||||
}
|
||||
QString text = element->getFlags().testFlag(MElement::REVERSE_ENGINEERED) ? tr("Yes") : tr("No");
|
||||
_reverse_engineered_label->setText(text);
|
||||
@@ -428,7 +428,7 @@ void PropertiesView::MView::visitMObject(const MObject *object)
|
||||
bool is_single_selection = selection.size() == 1;
|
||||
if (_element_name_line_edit == 0) {
|
||||
_element_name_line_edit = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Name"), _element_name_line_edit);
|
||||
_top_layout->addRow(tr("Name:"), _element_name_line_edit);
|
||||
connect(_element_name_line_edit, SIGNAL(textChanged(QString)), this, SLOT(onObjectNameChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -445,12 +445,12 @@ void PropertiesView::MView::visitMObject(const MObject *object)
|
||||
#ifdef SHOW_DEBUG_PROPERTIES
|
||||
if (_children_label == 0) {
|
||||
_children_label = new QLabel(_top_widget);
|
||||
_top_layout->addRow(tr("Children"), _children_label);
|
||||
_top_layout->addRow(tr("Children:"), _children_label);
|
||||
}
|
||||
_children_label->setText(QString::number(object->getChildren().size()));
|
||||
if (_relations_label == 0) {
|
||||
_relations_label = new QLabel(_top_widget);
|
||||
_top_layout->addRow(tr("Relations"), _relations_label);
|
||||
_top_layout->addRow(tr("Relations:"), _relations_label);
|
||||
}
|
||||
_relations_label->setText(QString::number(object->getRelations().size()));
|
||||
#endif
|
||||
@@ -474,7 +474,7 @@ void PropertiesView::MView::visitMClass(const MClass *klass)
|
||||
bool is_single_selection = selection.size() == 1;
|
||||
if (_namespace_line_edit == 0) {
|
||||
_namespace_line_edit = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Namespace"), _namespace_line_edit);
|
||||
_top_layout->addRow(tr("Namespace:"), _namespace_line_edit);
|
||||
connect(_namespace_line_edit, SIGNAL(textEdited(QString)), this, SLOT(onNamespaceChanged(QString)));
|
||||
}
|
||||
if (!_namespace_line_edit->hasFocus()) {
|
||||
@@ -491,7 +491,7 @@ void PropertiesView::MView::visitMClass(const MClass *klass)
|
||||
}
|
||||
if (_template_parameters_line_edit == 0) {
|
||||
_template_parameters_line_edit = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Template"), _template_parameters_line_edit);
|
||||
_top_layout->addRow(tr("Template:"), _template_parameters_line_edit);
|
||||
connect(_template_parameters_line_edit, SIGNAL(textChanged(QString)), this, SLOT(onTemplateParametersChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -525,7 +525,7 @@ void PropertiesView::MView::visitMClass(const MClass *klass)
|
||||
if (_class_members_edit == 0) {
|
||||
_class_members_edit = new ClassMembersEdit(_top_widget);
|
||||
_class_members_edit->setLineWrapMode(QPlainTextEdit::NoWrap);
|
||||
_top_layout->addRow(tr("Members"), _class_members_edit);
|
||||
_top_layout->addRow(tr("Members:"), _class_members_edit);
|
||||
connect(_class_members_edit, SIGNAL(membersChanged(QList<MClassMember>&)), this, SLOT(onClassMembersChanged(QList<MClassMember>&)));
|
||||
connect(_class_members_edit, SIGNAL(statusChanged(bool)), this, SLOT(onClassMembersStatusChanged(bool)));
|
||||
}
|
||||
@@ -554,7 +554,7 @@ void PropertiesView::MView::visitMDiagram(const MDiagram *diagram)
|
||||
#ifdef SHOW_DEBUG_PROPERTIES
|
||||
if (_diagrams_label == 0) {
|
||||
_diagrams_label = new QLabel(_top_widget);
|
||||
_top_layout->addRow(tr("Elements"), _diagrams_label);
|
||||
_top_layout->addRow(tr("Elements:"), _diagrams_label);
|
||||
}
|
||||
_diagrams_label->setText(QString::number(diagram->getDiagramElements().size()));
|
||||
#endif
|
||||
@@ -575,7 +575,7 @@ void PropertiesView::MView::visitMItem(const MItem *item)
|
||||
if (item->isVarietyEditable()) {
|
||||
if (_item_variety_edit == 0) {
|
||||
_item_variety_edit = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Variety"), _item_variety_edit);
|
||||
_top_layout->addRow(tr("Variety:"), _item_variety_edit);
|
||||
connect(_item_variety_edit, SIGNAL(textChanged(QString)), this, SLOT(onItemVarietyChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -598,7 +598,7 @@ void PropertiesView::MView::visitMRelation(const MRelation *relation)
|
||||
bool is_single_selection = selection.size() == 1;
|
||||
if (_element_name_line_edit == 0) {
|
||||
_element_name_line_edit = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Name"), _element_name_line_edit);
|
||||
_top_layout->addRow(tr("Name:"), _element_name_line_edit);
|
||||
connect(_element_name_line_edit, SIGNAL(textChanged(QString)), this, SLOT(onRelationNameChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -628,7 +628,7 @@ void PropertiesView::MView::visitMDependency(const MDependency *dependency)
|
||||
if (_direction_selector == 0) {
|
||||
_direction_selector = new QComboBox(_top_widget);
|
||||
_direction_selector->addItems(QStringList() << QStringLiteral("->") << QStringLiteral("<-") << QStringLiteral("<->"));
|
||||
_top_layout->addRow(tr("Direction"), _direction_selector);
|
||||
_top_layout->addRow(tr("Direction:"), _direction_selector);
|
||||
connect(_direction_selector, SIGNAL(activated(int)), this, SLOT(onDependencyDirectionChanged(int)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -649,9 +649,9 @@ void PropertiesView::MView::visitMInheritance(const MInheritance *inheritance)
|
||||
setTitle<MInheritance>(_model_elements, tr("Inheritance"), tr("Inheritances"));
|
||||
MObject *derived_class = _properties_view->getModelController()->findObject(inheritance->getDerived());
|
||||
QMT_CHECK(derived_class);
|
||||
setEndAName(tr("Derived Class: %1").arg(derived_class->getName()));
|
||||
setEndAName(tr("Derived class: %1").arg(derived_class->getName()));
|
||||
MObject *base_class = _properties_view->getModelController()->findObject(inheritance->getBase());
|
||||
setEndBName(tr("Base Class: %1").arg(base_class->getName()));
|
||||
setEndBName(tr("Base class: %1").arg(base_class->getName()));
|
||||
visitMRelation(inheritance);
|
||||
}
|
||||
|
||||
@@ -667,7 +667,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
|
||||
}
|
||||
if (_end_a_end_name == 0) {
|
||||
_end_a_end_name = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Role"), _end_a_end_name);
|
||||
_top_layout->addRow(tr("Role:"), _end_a_end_name);
|
||||
connect(_end_a_end_name, SIGNAL(textChanged(QString)), this, SLOT(onAssociationEndANameChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -682,7 +682,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
|
||||
}
|
||||
if (_end_a_cardinality == 0) {
|
||||
_end_a_cardinality = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Cardinality"), _end_a_cardinality);
|
||||
_top_layout->addRow(tr("Cardinality:"), _end_a_cardinality);
|
||||
connect(_end_a_cardinality, SIGNAL(textChanged(QString)), this, SLOT(onAssociationEndACardinalityChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -713,7 +713,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
|
||||
if (_end_a_kind == 0) {
|
||||
_end_a_kind = new QComboBox(_top_widget);
|
||||
_end_a_kind->addItems(QStringList() << tr("Association") << tr("Aggregation") << tr("Composition"));
|
||||
_top_layout->addRow(tr("Relationship"), _end_a_kind);
|
||||
_top_layout->addRow(tr("Relationship:"), _end_a_kind);
|
||||
connect(_end_a_kind, SIGNAL(activated(int)), this, SLOT(onAssociationEndAKindChanged(int)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -734,7 +734,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
|
||||
}
|
||||
if (_end_b_end_name == 0) {
|
||||
_end_b_end_name = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Role"), _end_b_end_name);
|
||||
_top_layout->addRow(tr("Role:"), _end_b_end_name);
|
||||
connect(_end_b_end_name, SIGNAL(textChanged(QString)), this, SLOT(onAssociationEndBNameChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -749,7 +749,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
|
||||
}
|
||||
if (_end_b_cardinality == 0) {
|
||||
_end_b_cardinality = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Cardinality"), _end_b_cardinality);
|
||||
_top_layout->addRow(tr("Cardinality:"), _end_b_cardinality);
|
||||
connect(_end_b_cardinality, SIGNAL(textChanged(QString)), this, SLOT(onAssociationEndBCardinalityChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -780,7 +780,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
|
||||
if (_end_b_kind == 0) {
|
||||
_end_b_kind = new QComboBox(_top_widget);
|
||||
_end_b_kind->addItems(QStringList() << tr("Association") << tr("Aggregation") << tr("Composition"));
|
||||
_top_layout->addRow(tr("Relationship"), _end_b_kind);
|
||||
_top_layout->addRow(tr("Relationship:"), _end_b_kind);
|
||||
connect(_end_b_kind, SIGNAL(activated(int)), this, SLOT(onAssociationEndBKindChanged(int)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -823,7 +823,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
|
||||
#ifdef SHOW_DEBUG_PROPERTIES
|
||||
if (_pos_rect_label == 0) {
|
||||
_pos_rect_label = new QLabel(_top_widget);
|
||||
_top_layout->addRow(tr("Pos&Size"), _pos_rect_label);
|
||||
_top_layout->addRow(tr("Position and size:"), _pos_rect_label);
|
||||
}
|
||||
_pos_rect_label->setText(QString(QStringLiteral("(%1,%2):(%3,%4)-(%5,%6)"))
|
||||
.arg(object->getPos().x())
|
||||
@@ -835,7 +835,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
|
||||
#endif
|
||||
if (_auto_sized_checkbox == 0) {
|
||||
_auto_sized_checkbox = new QCheckBox(_top_widget);
|
||||
_top_layout->addRow(tr("Auto Sized"), _auto_sized_checkbox);
|
||||
_top_layout->addRow(tr("Auto sized"), _auto_sized_checkbox);
|
||||
connect(_auto_sized_checkbox, SIGNAL(clicked(bool)), this, SLOT(onAutoSizedChanged(bool)));
|
||||
}
|
||||
if (!_auto_sized_checkbox->hasFocus()) {
|
||||
@@ -853,7 +853,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
|
||||
setPrimaryRolePalette(_style_element_type, DObject::PRIMARY_ROLE_CUSTOM3, QColor());
|
||||
setPrimaryRolePalette(_style_element_type, DObject::PRIMARY_ROLE_CUSTOM4, QColor());
|
||||
setPrimaryRolePalette(_style_element_type, DObject::PRIMARY_ROLE_CUSTOM5, QColor());
|
||||
_top_layout->addRow(QStringLiteral("Color"), _visual_primary_role_selector);
|
||||
_top_layout->addRow(tr("Color:"), _visual_primary_role_selector);
|
||||
connect(_visual_primary_role_selector, SIGNAL(activated(int)), this, SLOT(onVisualPrimaryRoleChanged(int)));
|
||||
}
|
||||
if (!_visual_primary_role_selector->hasFocus()) {
|
||||
@@ -880,7 +880,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
|
||||
_visual_secondary_role_selector->addItems(QStringList() << tr("Normal")
|
||||
<< tr("Lighter") << tr("Darker")
|
||||
<< tr("Soften") << tr("Outline"));
|
||||
_top_layout->addRow(tr("Role"), _visual_secondary_role_selector);
|
||||
_top_layout->addRow(tr("Role:"), _visual_secondary_role_selector);
|
||||
connect(_visual_secondary_role_selector, SIGNAL(activated(int)), this, SLOT(onVisualSecondaryRoleChanged(int)));
|
||||
}
|
||||
if (!_visual_secondary_role_selector->hasFocus()) {
|
||||
@@ -908,7 +908,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
|
||||
_stereotype_display_selector = new QComboBox(_top_widget);
|
||||
_stereotype_display_selector->addItems(QStringList() << tr("Smart") << tr("None") << tr("Label")
|
||||
<< tr("Decoration") << tr("Icon"));
|
||||
_top_layout->addRow(tr("Stereotype Display"), _stereotype_display_selector);
|
||||
_top_layout->addRow(tr("Stereotype display:"), _stereotype_display_selector);
|
||||
connect(_stereotype_display_selector, SIGNAL(activated(int)), this, SLOT(onStereotypeDisplayChanged(int)));
|
||||
}
|
||||
if (!_stereotype_display_selector->hasFocus()) {
|
||||
@@ -922,7 +922,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
|
||||
#ifdef SHOW_DEBUG_PROPERTIES
|
||||
if (_depth_label == 0) {
|
||||
_depth_label = new QLabel(_top_widget);
|
||||
_top_layout->addRow(tr("Depth"), _depth_label);
|
||||
_top_layout->addRow(tr("Depth:"), _depth_label);
|
||||
}
|
||||
_depth_label->setText(QString::number(object->getDepth()));
|
||||
#endif
|
||||
@@ -945,7 +945,7 @@ void PropertiesView::MView::visitDClass(const DClass *klass)
|
||||
if (_template_display_selector == 0) {
|
||||
_template_display_selector = new QComboBox(_top_widget);
|
||||
_template_display_selector->addItems(QStringList() << tr("Smart") << tr("Box") << tr("Angle Brackets"));
|
||||
_top_layout->addRow(tr("Template Display"), _template_display_selector);
|
||||
_top_layout->addRow(tr("Template display:"), _template_display_selector);
|
||||
connect(_template_display_selector, SIGNAL(activated(int)), this, SLOT(onTemplateDisplayChanged(int)));
|
||||
}
|
||||
if (!_template_display_selector->hasFocus()) {
|
||||
@@ -958,7 +958,7 @@ void PropertiesView::MView::visitDClass(const DClass *klass)
|
||||
}
|
||||
if (_show_all_members_checkbox == 0) {
|
||||
_show_all_members_checkbox = new QCheckBox(_top_widget);
|
||||
_top_layout->addRow(tr("Show Members"), _show_all_members_checkbox);
|
||||
_top_layout->addRow(tr("Show members"), _show_all_members_checkbox);
|
||||
connect(_show_all_members_checkbox, SIGNAL(clicked(bool)), this, SLOT(onShowAllMembersChanged(bool)));
|
||||
}
|
||||
if (!_show_all_members_checkbox->hasFocus()) {
|
||||
@@ -979,7 +979,7 @@ void PropertiesView::MView::visitDComponent(const DComponent *component)
|
||||
visitDObject(component);
|
||||
if (_plain_shape_checkbox == 0) {
|
||||
_plain_shape_checkbox = new QCheckBox(_top_widget);
|
||||
_top_layout->addRow(tr("Plain Shape"), _plain_shape_checkbox);
|
||||
_top_layout->addRow(tr("Plain shape"), _plain_shape_checkbox);
|
||||
connect(_plain_shape_checkbox, SIGNAL(clicked(bool)), this, SLOT(onPlainShapeChanged(bool)));
|
||||
}
|
||||
if (!_plain_shape_checkbox->hasFocus()) {
|
||||
@@ -1010,7 +1010,7 @@ void PropertiesView::MView::visitDItem(const DItem *item)
|
||||
if (item->isShapeEditable()) {
|
||||
if (_item_shape_edit == 0) {
|
||||
_item_shape_edit = new QLineEdit(_top_widget);
|
||||
_top_layout->addRow(tr("Shape"), _item_shape_edit);
|
||||
_top_layout->addRow(tr("Shape:"), _item_shape_edit);
|
||||
connect(_item_shape_edit, SIGNAL(textChanged(QString)), this, SLOT(onItemShapeChanged(QString)));
|
||||
}
|
||||
if (is_single_selection) {
|
||||
@@ -1055,7 +1055,7 @@ void PropertiesView::MView::visitDAnnotation(const DAnnotation *annotation)
|
||||
visitDElement(annotation);
|
||||
if (_annotation_auto_width_checkbox == 0) {
|
||||
_annotation_auto_width_checkbox = new QCheckBox(_top_widget);
|
||||
_top_layout->addRow(tr("Auto Width"), _annotation_auto_width_checkbox);
|
||||
_top_layout->addRow(tr("Auto width"), _annotation_auto_width_checkbox);
|
||||
connect(_annotation_auto_width_checkbox, SIGNAL(clicked(bool)), this, SLOT(onAutoWidthChanged(bool)));
|
||||
}
|
||||
if (!_annotation_auto_width_checkbox->hasFocus()) {
|
||||
@@ -1069,7 +1069,7 @@ void PropertiesView::MView::visitDAnnotation(const DAnnotation *annotation)
|
||||
if (_annotation_visual_role_selector == 0) {
|
||||
_annotation_visual_role_selector = new QComboBox(_top_widget);
|
||||
_annotation_visual_role_selector->addItems(QStringList() << tr("Normal") << tr("Title") << tr("Subtitle") << tr("Emphasized") << tr("Soften") << tr("Footnote"));
|
||||
_top_layout->addRow(tr("Role"), _annotation_visual_role_selector);
|
||||
_top_layout->addRow(tr("Role:"), _annotation_visual_role_selector);
|
||||
connect(_annotation_visual_role_selector, SIGNAL(activated(int)), this, SLOT(onAnnotationVisualRoleChanged(int)));
|
||||
}
|
||||
if (!_annotation_visual_role_selector->hasFocus()) {
|
||||
|
||||
2
src/libs/3rdparty/modeling/qmt/qmt.pri
vendored
2
src/libs/3rdparty/modeling/qmt/qmt.pri
vendored
@@ -125,7 +125,6 @@ HEADERS += \
|
||||
$$PWD/model_widgets_ui/propertiesviewmview.h \
|
||||
$$PWD/project_controller/projectcontroller.h \
|
||||
$$PWD/project/project.h \
|
||||
$$PWD/serializer/diagramreferenceserializer.h \
|
||||
$$PWD/serializer/diagramserializer.h \
|
||||
$$PWD/serializer/infrastructureserializer.h \
|
||||
$$PWD/serializer/modelserializer.h \
|
||||
@@ -253,7 +252,6 @@ SOURCES += \
|
||||
$$PWD/model_widgets_ui/propertiesviewmview.cpp \
|
||||
$$PWD/project_controller/projectcontroller.cpp \
|
||||
$$PWD/project/project.cpp \
|
||||
$$PWD/serializer/diagramreferenceserializer.cpp \
|
||||
$$PWD/serializer/diagramserializer.cpp \
|
||||
$$PWD/serializer/infrastructureserializer.cpp \
|
||||
$$PWD/serializer/modelserializer.cpp \
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "diagramreferenceserializer.h"
|
||||
|
||||
#include "infrastructureserializer.h"
|
||||
|
||||
#include "qmt/project/project.h"
|
||||
#include "qmt/model/mdiagram.h"
|
||||
|
||||
#include "qark/qxmloutarchive.h"
|
||||
#include "qark/qxmlinarchive.h"
|
||||
#include "qark/serialize.h"
|
||||
|
||||
#include "qmt/infrastructure/ioexceptions.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
|
||||
namespace qark {
|
||||
|
||||
using namespace qmt;
|
||||
|
||||
QARK_REGISTER_TYPE_NAME(DiagramReferenceSerializer::Reference, "DiagramReferenceSerializer--Reference")
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive &archive, DiagramReferenceSerializer::Reference &reference)
|
||||
{
|
||||
archive || qark::tag(QStringLiteral("diagram-reference"), reference)
|
||||
|| qark::attr(QStringLiteral("model"), reference._model_uid)
|
||||
|| qark::attr(QStringLiteral("diagram"), reference._diagram_uid)
|
||||
|| qark::end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace qmt {
|
||||
|
||||
DiagramReferenceSerializer::Reference::Reference()
|
||||
{
|
||||
}
|
||||
|
||||
DiagramReferenceSerializer::Reference::Reference(const Uid &model_uid, const Uid &diagram_uid)
|
||||
: _model_uid(model_uid),
|
||||
_diagram_uid(diagram_uid)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
DiagramReferenceSerializer::DiagramReferenceSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
DiagramReferenceSerializer::~DiagramReferenceSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
void DiagramReferenceSerializer::save(const QString &file_name, const DiagramReferenceSerializer::Reference &reference)
|
||||
{
|
||||
QFile file(file_name);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
throw FileCreationException(file_name);
|
||||
}
|
||||
QIODevice *xml_device = &file;
|
||||
QXmlStreamWriter writer(xml_device);
|
||||
write(reference, &writer);
|
||||
}
|
||||
|
||||
QByteArray DiagramReferenceSerializer::save(const Project *project, const MDiagram *diagram)
|
||||
{
|
||||
QByteArray buffer;
|
||||
|
||||
QXmlStreamWriter writer(&buffer);
|
||||
write(Reference(project->getUid(), diagram->getUid()), &writer);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
DiagramReferenceSerializer::Reference DiagramReferenceSerializer::load(const QString &file_name)
|
||||
{
|
||||
QFile file(file_name);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
throw FileNotFoundException(file_name);
|
||||
}
|
||||
QIODevice *xml_device = &file;
|
||||
QXmlStreamReader reader(xml_device);
|
||||
return read(&reader);
|
||||
}
|
||||
|
||||
DiagramReferenceSerializer::Reference DiagramReferenceSerializer::load(const QByteArray &contents)
|
||||
{
|
||||
QXmlStreamReader reader(contents);
|
||||
return read(&reader);
|
||||
}
|
||||
|
||||
void DiagramReferenceSerializer::write(const Reference &reference, QXmlStreamWriter *writer)
|
||||
{
|
||||
writer->setAutoFormatting(true);
|
||||
writer->setAutoFormattingIndent(2);
|
||||
|
||||
qark::QXmlOutArchive archive(*writer);
|
||||
archive.beginDocument();
|
||||
archive << qark::tag("qmt-diagram-reference");
|
||||
archive << reference;
|
||||
archive << qark::end();
|
||||
archive.endDocument();
|
||||
}
|
||||
|
||||
DiagramReferenceSerializer::Reference DiagramReferenceSerializer::read(QXmlStreamReader *stream_reader)
|
||||
{
|
||||
Reference reference;
|
||||
|
||||
qark::QXmlInArchive archive(*stream_reader);
|
||||
archive.beginDocument();
|
||||
archive >> qark::tag("qmt-diagram-reference");
|
||||
archive >> reference;
|
||||
archive >> qark::end;
|
||||
archive.endDocument();
|
||||
|
||||
return reference;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,12 +55,24 @@ void save(Archive &archive, const T &t)
|
||||
Access<Archive, T>::save(archive, t);
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
void save(Archive &archive, const T &t, const Parameters &)
|
||||
{
|
||||
save(archive, t);
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
void load(Archive &archive, T &t)
|
||||
{
|
||||
Access<Archive, T>::load(archive, t);
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
void load(Archive &archive, T &t, const Parameters &)
|
||||
{
|
||||
load(archive, t);
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
void serialize(Archive &archive, T &t)
|
||||
{
|
||||
@@ -92,30 +104,9 @@ void serialize_helper(Archive &archive, T &t)
|
||||
static inline void serialize(Archive &archive, TYPE &); \
|
||||
};
|
||||
|
||||
#if 0
|
||||
#define QARK_ACCESS_SPECIALIZE_LOAD_SAVE(INARCHIVE, OUTARCHIVE, TYPE) \
|
||||
template<> class Access<INARCHIVE, TYPE> { public: static inline void load(INARCHIVE &archive, TYPE &); void serialize(INARCHIVE &, TYPE &); }; \
|
||||
template<> class Access<OUTARCHIVE, TYPE> { public: static inline void save(OUTARCHIVE &archive, const TYPE &); void serialize(OUTARCHIVE &, TYPE &); }; \
|
||||
void Access<INARCHIVE, TYPE>::serialize(INARCHIVE &, TYPE &) { } \
|
||||
void Access<OUTARCHIVE, TYPE>::serialize(OUTARCHIVE &, TYPE &) { } \
|
||||
template class Access<INARCHIVE, TYPE>; \
|
||||
template class Access<OUTARCHIVE, TYPE>;
|
||||
#endif
|
||||
|
||||
#define QARK_ACCESS_SPECIALIZE(INARCHIVE, OUTARCHIVE, TYPE) \
|
||||
template class Access<INARCHIVE, TYPE>; \
|
||||
template class Access<OUTARCHIVE, TYPE>;
|
||||
|
||||
#if 0
|
||||
#define QARK_SPECIALIZE_SERIALIZE(INARCHIVE, OUTARCHIVE, TYPE) \
|
||||
QARK_ACCESS_SPECIALIZE(INARCHIVE, OUTARCHIVE, TYPE); \
|
||||
template void serialize<INARCHIVE, TYPE>(INARCHIVE &, TYPE &); \
|
||||
template void serialize<OUTARCHIVE, TYPE>(OUTARCHIVE &, TYPE &);
|
||||
|
||||
#define QARK_SPECIALIZE_LOAD_SAVE(INARCHIVE, OUTARCHIVE, TYPE) \
|
||||
template void load<INARCHIVE, TYPE>(INARCHIVE &, TYPE &); \
|
||||
template void save<OUTARCHIVE, TYPE>(OUTARCHIVE &, const TYPE &);
|
||||
#endif
|
||||
|
||||
|
||||
#endif // QARK_ACCESS_H
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
|
||||
#include "flag.h"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
|
||||
namespace qark {
|
||||
|
||||
class ArchiveBasics
|
||||
@@ -48,8 +52,40 @@ public:
|
||||
|
||||
bool takeFlag(const Flag &flag) { bool f = (_flags & flag.getMask()) != 0; _flags &= ~flag.getMask(); return f; }
|
||||
|
||||
bool hasUserData(const QString &key)
|
||||
{
|
||||
return _user_data.contains(key);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getUserData(const QString &key)
|
||||
{
|
||||
return _user_data.value(key).value<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getUserData(const QString &key, const T &default_value)
|
||||
{
|
||||
// gcc 4.8.2 fails to compile if the following 2 statements are written in one expression
|
||||
//return _user_data.value(key, data).value<T>();
|
||||
QVariant v = _user_data.value(key, default_value);
|
||||
return v.value<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void setUserData(const QString &key, const T &data)
|
||||
{
|
||||
_user_data.insert(key, data);
|
||||
}
|
||||
|
||||
void removeUserData(const QString &key)
|
||||
{
|
||||
_user_data.remove(key);
|
||||
}
|
||||
|
||||
private:
|
||||
Flag::mask_type _flags;
|
||||
QHash<QString, QVariant> _user_data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#ifndef QARK_ATTRIBUTE_H
|
||||
#define QARK_ATTRIBUTE_H
|
||||
|
||||
#include "parameters.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace qark {
|
||||
@@ -38,19 +40,29 @@ namespace qark {
|
||||
template<typename T>
|
||||
class Attr {
|
||||
public:
|
||||
explicit Attr(const QString &qualified_name, T *value)
|
||||
Attr(const QString &qualified_name, T *value)
|
||||
: _qualified_name(qualified_name),
|
||||
_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
Attr(const QString &qualified_name, T *value, const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_value(value),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
T *getValue() const { return _value; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
T *_value;
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -59,33 +71,56 @@ Attr<T * const> attr(const QString &qualified_name, T * const &value)
|
||||
return Attr<T * const>(qualified_name, &value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Attr<T * const> attr(const QString &qualified_name, T * const &value, const Parameters ¶meters)
|
||||
{
|
||||
return Attr<T * const>(qualified_name, &value, parameters);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Attr<T> attr(const QString &qualified_name, T &value)
|
||||
{
|
||||
return Attr<T>(qualified_name, &value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Attr<T> attr(const QString &qualified_name, T &value, const Parameters ¶meters)
|
||||
{
|
||||
return Attr<T>(qualified_name, &value, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T>
|
||||
class GetterAttr {
|
||||
public:
|
||||
explicit GetterAttr(const QString &qualified_name, const U &u, T (U::*getter)() const)
|
||||
GetterAttr(const QString &qualified_name, const U &u, T (U::*getter)() const)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_getter(getter)
|
||||
{
|
||||
}
|
||||
|
||||
GetterAttr(const QString &qualified_name, const U &u, T (U::*getter)() const, const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_getter(getter),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
const U &getObject() const { return _u; }
|
||||
|
||||
T (U::*getGetter() const)() const { return _getter; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
const U &_u;
|
||||
T (U::*_getter)() const;
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T>
|
||||
@@ -94,27 +129,44 @@ GetterAttr<U, T> attr(const QString &qualified_name, const U &u, T (U::*getter)(
|
||||
return GetterAttr<U, T>(qualified_name, u, getter);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
GetterAttr<U, T> attr(const QString &qualified_name, const U &u, T (U::*getter)() const, const Parameters ¶meters)
|
||||
{
|
||||
return GetterAttr<U, T>(qualified_name, u, getter, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T>
|
||||
class SetterAttr {
|
||||
public:
|
||||
explicit SetterAttr(const QString &qualified_name, U &u, void (U::*setter)(T))
|
||||
SetterAttr(const QString &qualified_name, U &u, void (U::*setter)(T))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_setter(setter)
|
||||
{
|
||||
}
|
||||
|
||||
SetterAttr(const QString &qualified_name, U &u, void (U::*setter)(T), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_setter(setter),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
|
||||
void (U::*getSetter() const)(T) { return _setter; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
void (U::*_setter)(T);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T>
|
||||
@@ -123,11 +175,17 @@ SetterAttr<U, T> attr(const QString &qualified_name, U &u, void (U::*setter)(T))
|
||||
return SetterAttr<U, T>(qualified_name, u, setter);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
SetterAttr<U, T> attr(const QString &qualified_name, U &u, void (U::*setter)(T), const Parameters ¶meters)
|
||||
{
|
||||
return SetterAttr<U, T>(qualified_name, u, setter, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
class GetterSetterAttr {
|
||||
public:
|
||||
explicit GetterSetterAttr(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V))
|
||||
GetterSetterAttr(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_getter(getter),
|
||||
@@ -135,6 +193,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
GetterSetterAttr(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_getter(getter),
|
||||
_setter(setter),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
@@ -143,11 +210,14 @@ public:
|
||||
|
||||
void (U::*getSetter() const)(V) { return _setter; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
T (U::*_getter)() const;
|
||||
void (U::*_setter)(V);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
@@ -156,27 +226,44 @@ GetterSetterAttr<U, T, V> attr(const QString &qualified_name, U &u, T (U::*gette
|
||||
return GetterSetterAttr<U, T, V>(qualified_name, u, getter, setter);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
GetterSetterAttr<U, T, V> attr(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V), const Parameters ¶meters)
|
||||
{
|
||||
return GetterSetterAttr<U, T, V>(qualified_name, u, getter, setter, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T>
|
||||
class GetFuncAttr {
|
||||
public:
|
||||
explicit GetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &))
|
||||
GetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_get_func(get_func)
|
||||
{
|
||||
}
|
||||
|
||||
GetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_get_func(get_func),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
|
||||
T (*getGetFunc() const)(const U &) { return _get_func; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
T (*_get_func)(const U &);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T>
|
||||
@@ -185,27 +272,44 @@ GetFuncAttr<U, T> attr(const QString &qualified_name, const U &u, T (*get_func)(
|
||||
return GetFuncAttr<U, T>(qualified_name, u, get_func);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
GetFuncAttr<U, T> attr(const QString &qualified_name, const U &u, T (*get_func)(const U &), const Parameters ¶meters)
|
||||
{
|
||||
return GetFuncAttr<U, T>(qualified_name, u, get_func, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T>
|
||||
class SetFuncAttr {
|
||||
public:
|
||||
explicit SetFuncAttr(const QString &qualified_name, U &u, void (*set_func)(U &, T))
|
||||
SetFuncAttr(const QString &qualified_name, U &u, void (*set_func)(U &, T))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_set_func(set_func)
|
||||
{
|
||||
}
|
||||
|
||||
SetFuncAttr(const QString &qualified_name, U &u, void (*set_func)(U &, T), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_set_func(set_func),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
|
||||
void (*getSetFunc() const)(U &, T) { return _set_func; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
void (*_set_func)(U &, T);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T>
|
||||
@@ -214,11 +318,17 @@ SetFuncAttr<U, T> attr(const QString &qualified_name, U &u, void (*set_func)(U &
|
||||
return SetFuncAttr<U, T>(qualified_name, u, set_func);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
SetFuncAttr<U, T> attr(const QString &qualified_name, U &u, void (*set_func)(U &, T), const Parameters ¶meters)
|
||||
{
|
||||
return SetFuncAttr<U, T>(qualified_name, u, set_func, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
class GetSetFuncAttr {
|
||||
public:
|
||||
explicit GetSetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V))
|
||||
GetSetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_get_func(get_func),
|
||||
@@ -226,6 +336,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
GetSetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_get_func(get_func),
|
||||
_set_func(set_func),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
@@ -234,11 +353,14 @@ public:
|
||||
|
||||
void (*getSetFunc() const)(U &, V) { return _set_func; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
T (*_get_func)(const U &);
|
||||
void (*_set_func)(U &, V);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
@@ -247,6 +369,12 @@ GetSetFuncAttr<U, T, V> attr(const QString &qualified_name, U &u, T (*get_func)(
|
||||
return GetSetFuncAttr<U, T, V>(qualified_name, u, get_func, set_func);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
GetSetFuncAttr<U, T, V> attr(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V), const Parameters ¶meters)
|
||||
{
|
||||
return GetSetFuncAttr<U, T, V>(qualified_name, u, get_func, set_func, parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // QARK_ATTRIBUTE_H
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#define QARK_BASECLASS_H
|
||||
|
||||
#include "typeregistry.h"
|
||||
#include "parameters.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
@@ -41,21 +42,31 @@ namespace qark {
|
||||
template<class BASE, class DERIVED>
|
||||
class Base {
|
||||
public:
|
||||
explicit Base(const QString &qualified_name, DERIVED &obj)
|
||||
Base(const QString &qualified_name, DERIVED &obj)
|
||||
: _qualified_name(qualified_name),
|
||||
_base(obj)
|
||||
{
|
||||
}
|
||||
|
||||
Base(const QString &qualified_name, DERIVED &obj, const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_base(obj),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
const BASE &getBase() const { return _base; }
|
||||
|
||||
BASE &getBase() { return _base; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
BASE &_base;
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class BASE, class DERIVED>
|
||||
@@ -64,18 +75,36 @@ Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED &obj)
|
||||
return Base<BASE, DERIVED>(qualified_name, obj);
|
||||
}
|
||||
|
||||
template<class BASE, class DERIVED>
|
||||
Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED &obj, const Parameters ¶meters)
|
||||
{
|
||||
return Base<BASE, DERIVED>(qualified_name, obj, parameters);
|
||||
}
|
||||
|
||||
template<class BASE, class DERIVED>
|
||||
Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED *&obj)
|
||||
{
|
||||
return Base<BASE, DERIVED>(qualified_name, *obj);
|
||||
}
|
||||
|
||||
template<class BASE, class DERIVED>
|
||||
Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED *&obj, const Parameters ¶meters)
|
||||
{
|
||||
return Base<BASE, DERIVED>(qualified_name, *obj, parameters);
|
||||
}
|
||||
|
||||
template<class BASE, class DERIVED>
|
||||
Base<BASE, DERIVED> base(DERIVED &obj)
|
||||
{
|
||||
return Base<BASE, DERIVED>(QString(QStringLiteral("base-%1")).arg(get_type_uid<BASE>()), obj);
|
||||
}
|
||||
|
||||
template<class BASE, class DERIVED>
|
||||
Base<BASE, DERIVED> base(DERIVED &obj, const Parameters ¶meters)
|
||||
{
|
||||
return Base<BASE, DERIVED>(QString(QStringLiteral("base-%1")).arg(get_type_uid<BASE>()), obj, parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // QARK_BASECLASS_H
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_FRIEND_ACCESS_H
|
||||
#define QMT_FRIEND_ACCESS_H
|
||||
#ifndef QARK_FRIEND_ACCESS_H
|
||||
#define QARK_FRIEND_ACCESS_H
|
||||
|
||||
#define QARK_FRIEND_ACCESS \
|
||||
template<class Archive, class T> \
|
||||
|
||||
@@ -28,59 +28,44 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DIAGRAMREFERENCESERIALIZER_H
|
||||
#define QMT_DIAGRAMREFERENCESERIALIZER_H
|
||||
#ifndef QARK_PARAMETER_H
|
||||
#define QARK_PARAMETER_H
|
||||
|
||||
#include "qmt/infrastructure/uid.h"
|
||||
#include "flag.h"
|
||||
|
||||
#include <QString>
|
||||
namespace qark {
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QXmlStreamReader;
|
||||
class QXmlStreamWriter;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class Project;
|
||||
class MDiagram;
|
||||
|
||||
|
||||
class QMT_EXPORT DiagramReferenceSerializer
|
||||
class Parameters
|
||||
{
|
||||
public:
|
||||
|
||||
struct Reference {
|
||||
Reference();
|
||||
Reference(const Uid &model_uid, const Uid &diagram_uid);
|
||||
|
||||
Uid _model_uid;
|
||||
Uid _diagram_uid;
|
||||
};
|
||||
|
||||
public:
|
||||
DiagramReferenceSerializer();
|
||||
|
||||
~DiagramReferenceSerializer();
|
||||
|
||||
public:
|
||||
|
||||
void save(const QString &file_name, const Reference &reference);
|
||||
Parameters()
|
||||
: _flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
QByteArray save(const Project *project, const MDiagram *diagram);
|
||||
Parameters(const Flag &flag)
|
||||
: _flags(flag.getMask())
|
||||
{
|
||||
}
|
||||
|
||||
Reference load(const QString &file_name);
|
||||
public:
|
||||
|
||||
Reference load(const QByteArray &contents);
|
||||
void setFlag(const Flag &flag) { _flags |= flag.getMask(); }
|
||||
|
||||
void clearFlag(const Flag &flag) { _flags &= ~flag.getMask(); }
|
||||
|
||||
bool hasFlag(const Flag &flag) const { return (_flags & flag.getMask()) != 0; }
|
||||
|
||||
bool takeFlag(const Flag &flag) { bool f = (_flags & flag.getMask()) != 0; _flags &= ~flag.getMask(); return f; }
|
||||
|
||||
private:
|
||||
|
||||
void write(const Reference &reference, QXmlStreamWriter *writer);
|
||||
|
||||
Reference read(QXmlStreamReader *stream_reader);
|
||||
Flag::mask_type _flags;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // QMT_DIAGRAMREFERENCESERIALIZER_H
|
||||
#endif // QARK_PARAMETER_H
|
||||
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
typedef QList<Node *> children_type;
|
||||
|
||||
public:
|
||||
virtual ~Node() { }
|
||||
virtual ~Node() { qDeleteAll(_children); }
|
||||
|
||||
const children_type &getChildren() const { return _children; }
|
||||
|
||||
@@ -83,8 +83,6 @@ private:
|
||||
|
||||
virtual void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
|
||||
|
||||
virtual void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
|
||||
|
||||
void append(Node *node) { _children.push_back(node); }
|
||||
|
||||
private:
|
||||
@@ -237,8 +235,6 @@ private:
|
||||
|
||||
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
|
||||
|
||||
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
|
||||
|
||||
Ref<T> &getReference() { return _ref; }
|
||||
|
||||
private:
|
||||
@@ -256,8 +252,6 @@ private:
|
||||
|
||||
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
|
||||
|
||||
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
|
||||
|
||||
SetterRef<U, T> &getReference() { return _ref; }
|
||||
|
||||
private:
|
||||
@@ -275,8 +269,6 @@ private:
|
||||
|
||||
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
|
||||
|
||||
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
|
||||
|
||||
GetterSetterRef<U, T, V> &getReference() { return _ref; }
|
||||
|
||||
private:
|
||||
@@ -294,8 +286,6 @@ private:
|
||||
|
||||
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
|
||||
|
||||
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
|
||||
|
||||
SetFuncRef<U, T> &getReference() { return _ref; }
|
||||
|
||||
private:
|
||||
@@ -313,35 +303,23 @@ private:
|
||||
|
||||
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
|
||||
|
||||
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
|
||||
|
||||
GetSetFuncRef<U, T, V> &getReference() { return _ref; }
|
||||
|
||||
private:
|
||||
GetSetFuncRef<U, T, V> _ref;
|
||||
};
|
||||
|
||||
struct ForwardReference {
|
||||
ForwardReference(Node *node, const impl::ObjectId &id) : _node(node), _id(id) { }
|
||||
Node *_node;
|
||||
impl::ObjectId _id;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
explicit QXmlInArchive(QXmlStreamReader &stream)
|
||||
: _stream(stream),
|
||||
_end_tag_was_read(false),
|
||||
_root_node(0),
|
||||
_current_ref_node(0)
|
||||
{
|
||||
}
|
||||
|
||||
~QXmlInArchive()
|
||||
{
|
||||
foreach(const ForwardReference &forward_ref, _forward_references) {
|
||||
forward_ref._node->acceptForwardRef(*this, forward_ref._id);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -387,9 +365,7 @@ public:
|
||||
void append(const Tag &tag)
|
||||
{
|
||||
TagNode *node = new TagNode(tag);
|
||||
if (_node_stack.empty()) {
|
||||
_root_node = node;
|
||||
} else {
|
||||
if (!_node_stack.empty()) {
|
||||
_node_stack.top()->append(node);
|
||||
}
|
||||
_node_stack.push(node);
|
||||
@@ -399,9 +375,7 @@ public:
|
||||
void append(const Object<T> &object)
|
||||
{
|
||||
ObjectNode<T> *node = new ObjectNode<T>(object);
|
||||
if (_node_stack.empty()) {
|
||||
_root_node = node;
|
||||
} else {
|
||||
if (!_node_stack.empty()) {
|
||||
_node_stack.top()->append(node);
|
||||
}
|
||||
_node_stack.push(node);
|
||||
@@ -409,13 +383,14 @@ public:
|
||||
|
||||
void append(const End &)
|
||||
{
|
||||
_node_stack.pop();
|
||||
Node *node = _node_stack.pop();
|
||||
if (_node_stack.empty()) {
|
||||
XmlTag xml_tag = readTag();
|
||||
if (xml_tag._tag_name != _root_node->getQualifiedName() || xml_tag._end_tag) {
|
||||
if (xml_tag._tag_name != node->getQualifiedName() || xml_tag._end_tag) {
|
||||
throw FileFormatException();
|
||||
}
|
||||
_root_node->accept(*this, xml_tag);
|
||||
node->accept(*this, xml_tag);
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,13 +562,8 @@ public:
|
||||
if (_loading_ref_map.hasObject(id)) {
|
||||
p = _loading_ref_map.getObject<T *>(id);
|
||||
} else {
|
||||
if (_current_ref_node == 0) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
_forward_references.append(ForwardReference(_current_ref_node, id));
|
||||
// node is eaten, also used as flag for forward references
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -634,11 +604,6 @@ private:
|
||||
throw FileFormatException();
|
||||
}
|
||||
|
||||
void visitForwardRef(Node *, const impl::ObjectId &)
|
||||
{
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
|
||||
void visit(TagNode *node, const XmlTag &)
|
||||
{
|
||||
readChildren(node);
|
||||
@@ -656,7 +621,7 @@ private:
|
||||
template<class T, class U>
|
||||
void visit(BaseNode<T, U> *node, const XmlTag &)
|
||||
{
|
||||
(*this) >> node->getBase().getBase();
|
||||
load(*this, node->getBase().getBase(), node->getBase().getParameters());
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getBase().getQualifiedName()) {
|
||||
throw FileFormatException();
|
||||
@@ -666,7 +631,7 @@ private:
|
||||
template<class T>
|
||||
void visit(AttrNode<T> *node, const XmlTag &)
|
||||
{
|
||||
(*this) >> *node->getAttribute().getValue();
|
||||
load(*this, *node->getAttribute().getValue(), node->getAttribute().getParameters());
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
throw FileFormatException();
|
||||
@@ -677,7 +642,7 @@ private:
|
||||
void visit(SetterAttrNode<U, T> *node, const XmlTag &)
|
||||
{
|
||||
T value;
|
||||
(*this) >> value;
|
||||
load(*this, value, node->getAttribute().getParameters());
|
||||
(node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value);
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
@@ -689,7 +654,7 @@ private:
|
||||
void visit(SetterAttrNode<U, const T &> *node, const XmlTag &)
|
||||
{
|
||||
T value;
|
||||
(*this) >> value;
|
||||
load(*this, value, node->getAttribute().getParameters());
|
||||
(node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value);
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
@@ -701,7 +666,7 @@ private:
|
||||
void visit(GetterSetterAttrNode<U, T, V> *node, const XmlTag &)
|
||||
{
|
||||
V value;
|
||||
(*this) >> value;
|
||||
load(*this, value, node->getAttribute().getParameters());
|
||||
(node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value);
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
@@ -713,7 +678,7 @@ private:
|
||||
void visit(GetterSetterAttrNode<U, T, const V &> *node, const XmlTag &)
|
||||
{
|
||||
V value;
|
||||
(*this) >> value;
|
||||
load(*this, value, node->getAttribute().getParameters());
|
||||
(node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value);
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
@@ -725,7 +690,7 @@ private:
|
||||
void visit(SetFuncAttrNode<U, T> *node, const XmlTag &)
|
||||
{
|
||||
T value;
|
||||
(*this) >> value;
|
||||
load(*this, value, node->getAttribute().getParameters());
|
||||
(node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value);
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
@@ -737,7 +702,7 @@ private:
|
||||
void visit(SetFuncAttrNode<U, const T &> *node, const XmlTag &)
|
||||
{
|
||||
T value;
|
||||
(*this) >> value;
|
||||
load(*this, value, node->getAttribute().getParameters());
|
||||
(node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value);
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
@@ -749,7 +714,7 @@ private:
|
||||
void visit(GetSetFuncAttrNode<U, T, V> *node, const XmlTag &)
|
||||
{
|
||||
V value;
|
||||
(*this) >> value;
|
||||
load(*this, value, node->getAttribute().getParameters());
|
||||
(node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value);
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
@@ -761,7 +726,7 @@ private:
|
||||
void visit(GetSetFuncAttrNode<U, T, const V &> *node, const XmlTag &)
|
||||
{
|
||||
V value;
|
||||
(*this) >> value;
|
||||
load(*this, value, node->getAttribute().getParameters());
|
||||
(node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value);
|
||||
XmlTag xml_tag = readTag();
|
||||
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
|
||||
@@ -774,8 +739,8 @@ private:
|
||||
{
|
||||
_current_ref_node = node;
|
||||
T value = T();
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
*node->getReference().getValue() = value;
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
@@ -785,23 +750,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void visitForwardRef(RefNode<T> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
T value = _loading_ref_map.getObject<T>(id);
|
||||
*(node->getReference().getValue()) = value;
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
void visit(SetterRefNode<U, T> *node, const XmlTag &)
|
||||
{
|
||||
_current_ref_node = node;
|
||||
T value;
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
@@ -816,8 +771,8 @@ private:
|
||||
{
|
||||
_current_ref_node = node;
|
||||
T value;
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
@@ -827,33 +782,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
void visitForwardRef(SetterRefNode<U, T> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
T value = _loading_ref_map.getObject<T>(id);
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
void visitForwardRef(SetterRefNode<U, T const &> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
T value = _loading_ref_map.getObject<T>(id);
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
void visit(GetterSetterRefNode<U, T, V> *node, const XmlTag &)
|
||||
{
|
||||
_current_ref_node = node;
|
||||
V value;
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
@@ -868,8 +803,8 @@ private:
|
||||
{
|
||||
_current_ref_node = node;
|
||||
V value;
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
@@ -879,34 +814,14 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
void visitForwardRef(GetterSetterRefNode<U, T, V> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
V value = _loading_ref_map.getObject<V>(id);
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
void visitForwardRef(GetterSetterRefNode<U, T, V const &> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
V value = _loading_ref_map.getObject<V>(id);
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
void visit(SetFuncRefNode<U, T> *node, const XmlTag &)
|
||||
{
|
||||
_current_ref_node = node;
|
||||
T value;
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
(node->getReference().getSetFunc())(node->getReference().getObject(), value);
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
XmlTag xml_tag = readTag();
|
||||
@@ -920,9 +835,9 @@ private:
|
||||
{
|
||||
_current_ref_node = node;
|
||||
T value;
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
(node->getReference().getSetFunc())(node->getReference().getObject(), value);
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
XmlTag xml_tag = readTag();
|
||||
@@ -931,34 +846,14 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
void visitForwardRef(SetFuncRefNode<U, T> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
T value = _loading_ref_map.getObject<T>(id);
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
void visitForwardRef(SetFuncRefNode<U, T const &> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
T value = _loading_ref_map.getObject<T>(id);
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
void visit(GetSetFuncRefNode<U, T, V> *node, const XmlTag &)
|
||||
{
|
||||
_current_ref_node = node;
|
||||
V value;
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
(node->getReference().getSetFunc())(node->getReference().getObject(), value);
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
XmlTag xml_tag = readTag();
|
||||
@@ -972,9 +867,9 @@ private:
|
||||
{
|
||||
_current_ref_node = node;
|
||||
V value;
|
||||
(*this) >> value;
|
||||
if (_current_ref_node != 0) { // ref node was not eaten by forward reference
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
load(*this, value, node->getReference().getParameters());
|
||||
if (_current_ref_node != 0) { // ref node was not consumed by forward reference
|
||||
(node->getReference().getSetFunc())(node->getReference().getObject(), value);
|
||||
_current_ref_node = 0;
|
||||
}
|
||||
XmlTag xml_tag = readTag();
|
||||
@@ -983,26 +878,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
void visitForwardRef(GetSetFuncRefNode<U, T, V> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
V value = _loading_ref_map.getObject<V>(id);
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
void visitForwardRef(GetSetFuncRefNode<U, T, V const &> *node, const impl::ObjectId &id)
|
||||
{
|
||||
if (!_loading_ref_map.hasObject(id)) {
|
||||
throw UnexpectedForwardReference();
|
||||
}
|
||||
V value = _loading_ref_map.getObject<V>(id);
|
||||
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
inline XmlTag readTag();
|
||||
@@ -1012,11 +887,9 @@ private:
|
||||
private:
|
||||
QXmlStreamReader &_stream;
|
||||
bool _end_tag_was_read;
|
||||
Node *_root_node;
|
||||
QStack<Node *> _node_stack;
|
||||
impl::LoadingRefMap _loading_ref_map;
|
||||
Node *_current_ref_node;
|
||||
QList<ForwardReference> _forward_references;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -49,6 +49,11 @@ class QXmlOutArchive :
|
||||
{
|
||||
public:
|
||||
|
||||
class UnsupportedForwardReference :
|
||||
public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
class DanglingReferences :
|
||||
public std::exception
|
||||
{
|
||||
@@ -58,6 +63,7 @@ public:
|
||||
static const bool out_archive = true;
|
||||
|
||||
public:
|
||||
|
||||
QXmlOutArchive(QXmlStreamWriter &stream)
|
||||
: _stream(stream),
|
||||
_next_pointer_is_reference(false)
|
||||
@@ -76,6 +82,9 @@ public:
|
||||
template<typename T>
|
||||
void write(T *p)
|
||||
{
|
||||
if (!_saving_ref_map.hasDefinedRef(p)) {
|
||||
throw UnsupportedForwardReference();
|
||||
}
|
||||
write(_saving_ref_map.getRef(p).get());
|
||||
}
|
||||
|
||||
@@ -132,7 +141,12 @@ public:
|
||||
void beginElement(const Object<T> &object)
|
||||
{
|
||||
_stream.writeStartElement(object.getQualifiedName());
|
||||
_stream.writeAttribute(QLatin1String("id"), QString::number(_saving_ref_map.getRef(object.getObject(), true).get()));
|
||||
// TODO implement key attribute
|
||||
// Currently qmodel files do not use references at all
|
||||
// so writing reference keys are not needed. If this
|
||||
// changes keys should be implemented as a generic
|
||||
// concept getting key from object (e.g. with a function
|
||||
// registered per type in typeregistry)
|
||||
}
|
||||
|
||||
void endElement(const End &)
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#ifndef QARK_REFERENCE_H
|
||||
#define QARK_REFERENCE_H
|
||||
|
||||
#include "parameters.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace qark {
|
||||
@@ -38,19 +40,29 @@ namespace qark {
|
||||
template<typename T>
|
||||
class Ref {
|
||||
public:
|
||||
explicit Ref(const QString &qualified_name, T *value)
|
||||
Ref(const QString &qualified_name, T *value)
|
||||
: _qualified_name(qualified_name),
|
||||
_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
Ref(const QString &qualified_name, T *value, const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_value(value),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
T *getValue() const { return _value; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
T *_value;
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -59,32 +71,56 @@ Ref<T * const> ref(const QString &qualified_name, T * const &value)
|
||||
return Ref<T * const>(qualified_name, &value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ref<T * const> ref(const QString &qualified_name, T * const &value, const Parameters ¶meters)
|
||||
{
|
||||
return Ref<T * const>(qualified_name, &value, parameters);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ref<T *> ref(const QString &qualified_name, T *&value)
|
||||
{
|
||||
return Ref<T *>(qualified_name, &value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ref<T *> ref(const QString &qualified_name, T *&value, const Parameters ¶meters)
|
||||
{
|
||||
return Ref<T *>(qualified_name, &value, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T>
|
||||
class GetterRef {
|
||||
public:
|
||||
explicit GetterRef(const QString &qualified_name, const U &u, T (U::*getter)() const)
|
||||
GetterRef(const QString &qualified_name, const U &u, T (U::*getter)() const)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_getter(getter)
|
||||
{
|
||||
}
|
||||
|
||||
GetterRef(const QString &qualified_name, const U &u, T (U::*getter)() const, const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_getter(getter),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
const U &getObject() const { return _u; }
|
||||
|
||||
T (U::*getGetter() const)() const { return _getter; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
const U &_u;
|
||||
T (U::*_getter)() const;
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T>
|
||||
@@ -93,27 +129,44 @@ GetterRef<U, T *> ref(const QString &qualified_name, const U &u, T *(U::*getter)
|
||||
return GetterRef<U, T *>(qualified_name, u, getter);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
GetterRef<U, T *> ref(const QString &qualified_name, const U &u, T *(U::*getter)() const, const Parameters ¶meters)
|
||||
{
|
||||
return GetterRef<U, T *>(qualified_name, u, getter, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T>
|
||||
class SetterRef {
|
||||
public:
|
||||
explicit SetterRef(const QString &qualified_name, U &u, void (U::*setter)(T))
|
||||
SetterRef(const QString &qualified_name, U &u, void (U::*setter)(T))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_setter(setter)
|
||||
{
|
||||
}
|
||||
|
||||
SetterRef(const QString &qualified_name, U &u, void (U::*setter)(T), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_setter(setter),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
|
||||
void (U::*getSetter() const)(T) { return _setter; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
void (U::*_setter)(T);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, class T>
|
||||
@@ -122,16 +175,29 @@ SetterRef<U, T *> ref(const QString &qualified_name, U &u, void (U::*setter)(T *
|
||||
return SetterRef<U, T *>(qualified_name, u, setter);
|
||||
}
|
||||
|
||||
template<class U, class T>
|
||||
SetterRef<U, T *> ref(const QString &qualified_name, U &u, void (U::*setter)(T *), const Parameters ¶meters)
|
||||
{
|
||||
return SetterRef<U, T *>(qualified_name, u, setter, parameters);
|
||||
}
|
||||
|
||||
template<class U, class T>
|
||||
SetterRef<U, T * const &> ref(const QString &qualified_name, U &u, void (U::*setter)(T * const &))
|
||||
{
|
||||
return SetterRef<U, T * const &>(qualified_name, u, setter);
|
||||
}
|
||||
|
||||
template<class U, class T>
|
||||
SetterRef<U, T * const &> ref(const QString &qualified_name, U &u, void (U::*setter)(T * const &), const Parameters ¶meters)
|
||||
{
|
||||
return SetterRef<U, T * const &>(qualified_name, u, setter, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
class GetterSetterRef {
|
||||
public:
|
||||
explicit GetterSetterRef(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V))
|
||||
GetterSetterRef(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_getter(getter),
|
||||
@@ -139,6 +205,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
GetterSetterRef(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_getter(getter),
|
||||
_setter(setter),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
@@ -147,11 +222,14 @@ public:
|
||||
|
||||
void (U::*getSetter() const)(V) { return _setter; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
T (U::*_getter)() const;
|
||||
void (U::*_setter)(V);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
@@ -160,32 +238,56 @@ GetterSetterRef<U, T *, V *> ref(const QString &qualified_name, U &u, T *(U::*ge
|
||||
return GetterSetterRef<U, T *, V *>(qualified_name, u, getter, setter);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
GetterSetterRef<U, T *, V *> ref(const QString &qualified_name, U &u, T *(U::*getter)() const, void (U::*setter)(V *), const Parameters ¶meters)
|
||||
{
|
||||
return GetterSetterRef<U, T *, V *>(qualified_name, u, getter, setter, parameters);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
GetterSetterRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(U::*getter)() const, void (U::*setter)(V * const &))
|
||||
{
|
||||
return GetterSetterRef<U, T *, V * const &>(qualified_name, u, getter, setter);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
GetterSetterRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(U::*getter)() const, void (U::*setter)(V * const &), const Parameters ¶meters)
|
||||
{
|
||||
return GetterSetterRef<U, T *, V * const &>(qualified_name, u, getter, setter, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T>
|
||||
class GetFuncRef {
|
||||
public:
|
||||
explicit GetFuncRef(const QString &qualified_name, const U &u, T (*get_func)(const U &))
|
||||
GetFuncRef(const QString &qualified_name, const U &u, T (*get_func)(const U &))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_get_func(get_func)
|
||||
{
|
||||
}
|
||||
|
||||
GetFuncRef(const QString &qualified_name, const U &u, T (*get_func)(const U &), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_get_func(get_func),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
const U &getObject() const { return _u; }
|
||||
|
||||
T (*getGetFunc() const)(const U &) { return _get_func; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
const U &_u;
|
||||
T (*_get_func)(const U &);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T>
|
||||
@@ -194,27 +296,44 @@ GetFuncRef<U, T *> ref(const QString &qualified_name, const U &u, T *(*get_func)
|
||||
return GetFuncRef<U, T *>(qualified_name, u, get_func);
|
||||
}
|
||||
|
||||
template<class U, typename T>
|
||||
GetFuncRef<U, T *> ref(const QString &qualified_name, const U &u, T *(*get_func)(const U &), const Parameters ¶meters)
|
||||
{
|
||||
return GetFuncRef<U, T *>(qualified_name, u, get_func, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T>
|
||||
class SetFuncRef {
|
||||
public:
|
||||
explicit SetFuncRef(const QString &qualified_name, U &u, void (*set_func)(U &, T))
|
||||
SetFuncRef(const QString &qualified_name, U &u, void (*set_func)(U &, T))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_set_func(set_func)
|
||||
{
|
||||
}
|
||||
|
||||
SetFuncRef(const QString &qualified_name, U &u, void (*set_func)(U &, T), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_set_func(set_func),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
|
||||
void (*getSetFunc() const)(U &, T) { return _set_func; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
void (*_set_func)(U &, T);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, class T>
|
||||
@@ -223,16 +342,29 @@ SetFuncRef<U, T *> ref(const QString &qualified_name, U &u, void (*set_func)(U &
|
||||
return SetFuncRef<U, T *>(qualified_name, u, set_func);
|
||||
}
|
||||
|
||||
template<class U, class T>
|
||||
SetFuncRef<U, T *> ref(const QString &qualified_name, U &u, void (*set_func)(U &, T *), const Parameters ¶meters)
|
||||
{
|
||||
return SetFuncRef<U, T *>(qualified_name, u, set_func, parameters);
|
||||
}
|
||||
|
||||
template<class U, class T>
|
||||
SetFuncRef<U, T * const &> ref(const QString &qualified_name, U &u, void (*set_func)(U &, T * const &))
|
||||
{
|
||||
return SetFuncRef<U, T * const &>(qualified_name, u, set_func);
|
||||
}
|
||||
|
||||
template<class U, class T>
|
||||
SetFuncRef<U, T * const &> ref(const QString &qualified_name, U &u, void (*set_func)(U &, T * const &), const Parameters ¶meters)
|
||||
{
|
||||
return SetFuncRef<U, T * const &>(qualified_name, u, set_func, parameters);
|
||||
}
|
||||
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
class GetSetFuncRef {
|
||||
public:
|
||||
explicit GetSetFuncRef(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V))
|
||||
GetSetFuncRef(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V))
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_get_func(get_func),
|
||||
@@ -240,6 +372,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
GetSetFuncRef(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V), const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_u(u),
|
||||
_get_func(get_func),
|
||||
_set_func(set_func),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
U &getObject() const { return _u; }
|
||||
@@ -248,11 +389,14 @@ public:
|
||||
|
||||
void (*getSetFunc() const)(U &, V) { return _set_func; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
U &_u;
|
||||
T (*_get_func)(const U &);
|
||||
void (*_set_func)(U &, V);
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
@@ -261,12 +405,24 @@ GetSetFuncRef<U, T *, V *> ref(const QString &qualified_name, U &u, T *(*get_fun
|
||||
return GetSetFuncRef<U, T *, V *>(qualified_name, u, get_func, set_func);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
GetSetFuncRef<U, T *, V *> ref(const QString &qualified_name, U &u, T *(*get_func)(const U &), void (*set_func)(U &, V *), const Parameters ¶meters)
|
||||
{
|
||||
return GetSetFuncRef<U, T *, V *>(qualified_name, u, get_func, set_func, parameters);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
GetSetFuncRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(*get_func)(const U &), void (*set_func)(U &, V * const &))
|
||||
{
|
||||
return GetSetFuncRef<U, T *, V * const &>(qualified_name, u, get_func, set_func);
|
||||
}
|
||||
|
||||
template<class U, typename T, typename V>
|
||||
GetSetFuncRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(*get_func)(const U &), void (*set_func)(U &, V * const &), const Parameters ¶meters)
|
||||
{
|
||||
return GetSetFuncRef<U, T *, V * const &>(qualified_name, u, get_func, set_func, parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // QARK_REFERENCE_H
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "access.h"
|
||||
#include "typeregistry.h"
|
||||
|
||||
#include "serialize_pointer.h"
|
||||
#include "serialize_basic.h"
|
||||
#include "serialize_container.h"
|
||||
#include "serialize_enum.h"
|
||||
@@ -51,102 +52,27 @@ namespace qark {
|
||||
template<class Archive, class T>
|
||||
inline Archive &operator<<(Archive &archive, const T &t)
|
||||
{
|
||||
save(archive, t);
|
||||
save(archive, t, Parameters());
|
||||
return archive;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline Archive &operator>>(Archive &archive, T &t)
|
||||
{
|
||||
load(archive, t);
|
||||
load(archive, t, Parameters());
|
||||
return archive;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, T &t)
|
||||
{
|
||||
save(archive, (const T &) t);
|
||||
return archive;
|
||||
return archive << t;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive &archive, T &t)
|
||||
{
|
||||
load(archive, t);
|
||||
return archive;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline Archive &operator<<(Archive &archive, T *p)
|
||||
{
|
||||
if (p) {
|
||||
if (archive.isReference(p)) {
|
||||
archive.beginPointer();
|
||||
archive.write(p);
|
||||
archive.endPointer();
|
||||
} else {
|
||||
if (typeid(*p) == typeid(T)) {
|
||||
archive.beginInstance();
|
||||
registry::save_pointer<Archive, T, T>(archive, p);
|
||||
archive.endInstance();
|
||||
} else {
|
||||
archive.beginInstance(get_type_uid(*p));
|
||||
//typename registry::TypeRegistry<Archive, typename qark::non_const<T>::type>::type_info type_data
|
||||
// = get_type_info<Archive, typename qark::non_const<T>::type>(*p);
|
||||
typename registry::TypeRegistry<Archive, T>::type_info type_data = get_type_info<Archive, T>(*p);
|
||||
if (type_data.save_func == 0) {
|
||||
throw unregistered_type();
|
||||
} else {
|
||||
type_data.save_func(archive, p);
|
||||
}
|
||||
archive.endInstance();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
archive.beginNullPointer();
|
||||
archive.endNullPointer();
|
||||
}
|
||||
return archive;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline Archive &operator>>(Archive &archive, T *&p)
|
||||
{
|
||||
typename Archive::ReferenceTag ref_tag = archive.readReferenceTag();
|
||||
switch (ref_tag.kind) {
|
||||
case Archive::NULLPOINTER:
|
||||
p = 0;
|
||||
break;
|
||||
case Archive::POINTER:
|
||||
archive.read(p);
|
||||
break;
|
||||
case Archive::INSTANCE:
|
||||
if (ref_tag.type_name.isEmpty()) {
|
||||
registry::load_non_virtual_pointer<Archive,T>(archive, p);
|
||||
} else {
|
||||
typename registry::TypeRegistry<Archive, T>::type_info type_data = get_type_info<Archive, T>(ref_tag.type_name);
|
||||
if (type_data.load_func == 0) {
|
||||
throw unregistered_type();
|
||||
} else {
|
||||
type_data.load_func(archive, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
archive.readReferenceEndTag(ref_tag.kind);
|
||||
return archive;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, T *&p)
|
||||
{
|
||||
return archive << p;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive &archive, T *&p)
|
||||
{
|
||||
return archive >> p;
|
||||
return archive >> t;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
@@ -175,32 +101,6 @@ typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive
|
||||
return archive >> f;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline Archive &operator<<(Archive &archive, void (*f)(Archive &))
|
||||
{
|
||||
f(archive);
|
||||
return archive;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline Archive &operator>>(Archive &archive, void (*f)(Archive &))
|
||||
{
|
||||
f(archive);
|
||||
return archive;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, void (*f)(Archive &))
|
||||
{
|
||||
return archive << f;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive &archive, void (*f)(Archive &))
|
||||
{
|
||||
return archive >> f;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline Archive &operator<<(Archive &archive, const Tag &tag)
|
||||
{
|
||||
@@ -311,7 +211,7 @@ template<class Archive, typename T>
|
||||
Archive &operator<<(Archive &archive, const Attr<T> &attr)
|
||||
{
|
||||
archive.beginAttribute(attr);
|
||||
archive << *attr.getValue();
|
||||
save(archive, *attr.getValue(), attr.getParameters());
|
||||
archive.endAttribute(attr);
|
||||
return archive;
|
||||
}
|
||||
@@ -336,10 +236,23 @@ typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive
|
||||
}
|
||||
|
||||
template<class Archive, class U, typename T>
|
||||
Archive &operator<<(Archive &archive, const GetterAttr<U, T> &attr)
|
||||
typename std::enable_if<!std::is_abstract<U>::value, Archive &>::type
|
||||
operator<<(Archive &archive, const GetterAttr<U, T> &attr)
|
||||
{
|
||||
if (!((attr.getObject().*(attr.getGetter()))() == (U().*(attr.getGetter()))())) {
|
||||
archive.beginAttribute(attr);
|
||||
save(archive, (attr.getObject().*(attr.getGetter()))(), attr.getParameters());
|
||||
archive.endAttribute(attr);
|
||||
}
|
||||
return archive;
|
||||
}
|
||||
|
||||
template<class Archive, class U, typename T>
|
||||
typename std::enable_if<std::is_abstract<U>::value, Archive &>::type
|
||||
operator<<(Archive &archive, const GetterAttr<U, T> &attr)
|
||||
{
|
||||
archive.beginAttribute(attr);
|
||||
archive << (attr.getObject().*(attr.getGetter()))();
|
||||
save(archive, (attr.getObject().*(attr.getGetter()))(), attr.getParameters());
|
||||
archive.endAttribute(attr);
|
||||
return archive;
|
||||
}
|
||||
@@ -358,7 +271,7 @@ operator<<(Archive &archive, const GetterSetterAttr<U, T, V> &attr)
|
||||
{
|
||||
if (!((attr.getObject().*(attr.getGetter()))() == (U().*(attr.getGetter()))())) {
|
||||
archive.beginAttribute(attr);
|
||||
archive << (attr.getObject().*(attr.getGetter()))();
|
||||
save(archive, (attr.getObject().*(attr.getGetter()))(), attr.getParameters());
|
||||
archive.endAttribute(attr);
|
||||
}
|
||||
return archive;
|
||||
@@ -370,7 +283,7 @@ typename std::enable_if<std::is_abstract<U>::value, Archive &>::type
|
||||
operator<<(Archive &archive, const GetterSetterAttr<U, T, V> &attr)
|
||||
{
|
||||
archive.beginAttribute(attr);
|
||||
archive << (attr.getObject().*(attr.getGetter()))();
|
||||
save(archive, (attr.getObject().*(attr.getGetter()))(), attr.getParameters());
|
||||
archive.endAttribute(attr);
|
||||
return archive;
|
||||
}
|
||||
@@ -398,7 +311,7 @@ template<class Archive, class U, typename T>
|
||||
Archive &operator<<(Archive &archive, const GetFuncAttr<U, T> &attr)
|
||||
{
|
||||
archive.beginAttribute(attr);
|
||||
archive << ((*attr.getGetFunc())(attr.getObject()));
|
||||
save(archive, ((*attr.getGetFunc())(attr.getObject())), attr.getParameters());
|
||||
archive.endAttribute(attr);
|
||||
return archive;
|
||||
}
|
||||
@@ -414,7 +327,7 @@ template<class Archive, class U, typename T, typename V>
|
||||
Archive &operator<<(Archive &archive, const GetSetFuncAttr<U, T, V> &attr)
|
||||
{
|
||||
archive.beginAttribute(attr);
|
||||
archive << ((*attr.getGetFunc())(attr.getObject()));
|
||||
save(archive, ((*attr.getGetFunc())(attr.getObject())), attr.getParameters());
|
||||
archive.endAttribute(attr);
|
||||
return archive;
|
||||
}
|
||||
@@ -442,7 +355,7 @@ template<class Archive, typename T>
|
||||
Archive &operator<<(Archive &archive, const Ref<T *> &ref)
|
||||
{
|
||||
archive.beginReference(ref);
|
||||
archive << *ref.getValue();
|
||||
save(archive, *ref.getValue(), ref.getParameters());
|
||||
archive.endReference(ref);
|
||||
return archive;
|
||||
}
|
||||
@@ -451,7 +364,7 @@ template<class Archive, typename T>
|
||||
Archive &operator<<(Archive &archive, const Ref<T * const> &ref)
|
||||
{
|
||||
archive.beginReference(ref);
|
||||
archive << *ref.getValue();
|
||||
save(archive, *ref.getValue(), ref.getParameters());
|
||||
archive.endReference(ref);
|
||||
return archive;
|
||||
}
|
||||
@@ -467,7 +380,7 @@ template<class Archive, typename T>
|
||||
typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, const Ref<T *> &ref)
|
||||
{
|
||||
archive.beginReference(ref);
|
||||
archive << *ref.getValue();
|
||||
save(archive, *ref.getValue(), ref.getParameters());
|
||||
archive.endReference(ref);
|
||||
return archive;
|
||||
}
|
||||
@@ -482,7 +395,7 @@ template<class Archive, class U, typename T>
|
||||
Archive &operator<<(Archive &archive, const GetterRef<U, T> &ref)
|
||||
{
|
||||
archive.beginReference(ref);
|
||||
archive << (ref.getObject().*(ref.getGetter()))();
|
||||
save(archive, (ref.getObject().*(ref.getGetter()))(), ref.getParameters());
|
||||
archive.endReference(ref);
|
||||
return archive;
|
||||
}
|
||||
@@ -498,7 +411,7 @@ template<class Archive, class U, typename T, typename V>
|
||||
Archive &operator<<(Archive &archive, const GetterSetterRef<U, T, V> &ref)
|
||||
{
|
||||
archive.beginReference(ref);
|
||||
archive << (ref.getObject().*(ref.getGetter()))();
|
||||
save(archive, (ref.getObject().*(ref.getGetter()))(), ref.getParameters());
|
||||
archive.endReference(ref);
|
||||
return archive;
|
||||
}
|
||||
@@ -526,7 +439,7 @@ template<class Archive, class U, typename T>
|
||||
Archive &operator<<(Archive &archive, const GetFuncRef<U, T> &ref)
|
||||
{
|
||||
archive.beginReference(ref);
|
||||
archive << ref.getGetFunc()(ref.getObject());
|
||||
save(archive, ref.getGetFunc()(ref.getObject()), ref.getParameters());
|
||||
archive.endReference(ref);
|
||||
return archive;
|
||||
}
|
||||
@@ -542,7 +455,7 @@ template<class Archive, class U, typename T, typename V>
|
||||
Archive &operator<<(Archive &archive, const GetSetFuncRef<U, T, V> &ref)
|
||||
{
|
||||
archive.beginReference(ref);
|
||||
archive << ref.getGetFunc()(ref.getObject());
|
||||
save(archive, ref.getGetFunc()(ref.getObject()), ref.getParameters());
|
||||
archive.endReference(ref);
|
||||
return archive;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#ifndef QARK_SERIALIZE_BASIC_H
|
||||
#define QARK_SERIALIZE_BASIC_H
|
||||
|
||||
#include "parameters.h"
|
||||
#include "qstringparser/qstringparser.h"
|
||||
|
||||
#include <QString>
|
||||
@@ -42,12 +43,12 @@
|
||||
|
||||
#define QARK_BASIC_SAVELOAD(TYPE) \
|
||||
template<class Archive> \
|
||||
inline void save(Archive &archive, TYPE v) \
|
||||
inline void save(Archive &archive, TYPE v, const Parameters &) \
|
||||
{ \
|
||||
archive.write(v); \
|
||||
} \
|
||||
template<class Archive> \
|
||||
inline void load(Archive &archive, TYPE &v) \
|
||||
inline void load(Archive &archive, TYPE &v, const Parameters &) \
|
||||
{ \
|
||||
archive.read(&v); \
|
||||
}
|
||||
@@ -79,13 +80,13 @@ QARK_BASIC_SAVELOAD(QString)
|
||||
// QPointF
|
||||
|
||||
template<class Archive>
|
||||
inline void save(Archive &archive, const QPointF &point)
|
||||
inline void save(Archive &archive, const QPointF &point, const Parameters &)
|
||||
{
|
||||
archive.write(QString(QStringLiteral("x:%1;y:%2")).arg(point.x()).arg(point.y()));
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline void load(Archive &archive, QPointF &point)
|
||||
inline void load(Archive &archive, QPointF &point, const Parameters &)
|
||||
{
|
||||
QString s;
|
||||
archive.read(&s);
|
||||
@@ -98,13 +99,13 @@ inline void load(Archive &archive, QPointF &point)
|
||||
// QRectF
|
||||
|
||||
template<class Archive>
|
||||
inline void save(Archive &archive, const QRectF &rect)
|
||||
inline void save(Archive &archive, const QRectF &rect, const Parameters &)
|
||||
{
|
||||
archive.write(QString(QStringLiteral("x:%1;y:%2;w:%3;h:%4")).arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height()));
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline void load(Archive &archive, QRectF &point)
|
||||
inline void load(Archive &archive, QRectF &point, const Parameters &)
|
||||
{
|
||||
QString s;
|
||||
archive.read(&s);
|
||||
@@ -117,13 +118,13 @@ inline void load(Archive &archive, QRectF &point)
|
||||
// QDateTime
|
||||
|
||||
template<class Archive>
|
||||
inline void save(Archive &archive, const QDateTime &date_time)
|
||||
inline void save(Archive &archive, const QDateTime &date_time, const Parameters &)
|
||||
{
|
||||
archive << date_time.toMSecsSinceEpoch();
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline void load(Archive &archive, QDateTime &date_time)
|
||||
inline void load(Archive &archive, QDateTime &date_time, const Parameters &)
|
||||
{
|
||||
qint64 t;
|
||||
archive >> t;
|
||||
|
||||
@@ -31,31 +31,22 @@
|
||||
#ifndef QARK_SERIALIZE_CONTAINER_H
|
||||
#define QARK_SERIALIZE_CONTAINER_H
|
||||
|
||||
#include "flag.h"
|
||||
#include "parameters.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
|
||||
namespace qark {
|
||||
|
||||
namespace impl {
|
||||
static Flag container_item_ref_flag;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline void ref_item(Archive &archive)
|
||||
{
|
||||
archive.setFlag(impl::container_item_ref_flag);
|
||||
}
|
||||
static Flag ENFORCE_REFERENCED_ITEMS;
|
||||
|
||||
|
||||
// QList
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void save(Archive &archive, const QList<T> &list)
|
||||
inline void save(Archive &archive, const QList<T> &list, const Parameters &)
|
||||
{
|
||||
archive << tag("qlist");
|
||||
archive.clearFlag(impl::container_item_ref_flag);
|
||||
foreach (const T &t, list) {
|
||||
archive << attr(QStringLiteral("item"), t);
|
||||
}
|
||||
@@ -63,10 +54,10 @@ inline void save(Archive &archive, const QList<T> &list)
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void save(Archive &archive, const QList<T *> &list)
|
||||
inline void save(Archive &archive, const QList<T *> &list, const Parameters ¶meters)
|
||||
{
|
||||
archive << tag("qlist");
|
||||
if (archive.takeFlag(impl::container_item_ref_flag)) {
|
||||
if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
|
||||
foreach (const T *t, list) {
|
||||
archive << ref(QStringLiteral("item"), t);
|
||||
}
|
||||
@@ -79,7 +70,7 @@ inline void save(Archive &archive, const QList<T *> &list)
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void load(Archive &archive, QList<T> &list)
|
||||
inline void load(Archive &archive, QList<T> &list, const Parameters &)
|
||||
{
|
||||
archive >> tag(QStringLiteral("qlist"));
|
||||
archive >> attr<QList<T>, const T &>(QStringLiteral("item"), list, &QList<T>::append);
|
||||
@@ -87,10 +78,10 @@ inline void load(Archive &archive, QList<T> &list)
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void load(Archive &archive, QList<T *> &list)
|
||||
inline void load(Archive &archive, QList<T *> &list, const Parameters ¶meters)
|
||||
{
|
||||
archive >> tag(QStringLiteral("qlist"));
|
||||
if (archive.takeFlag(impl::container_item_ref_flag)) {
|
||||
if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
|
||||
// why does the following line not compile but the line below selects the correct function?
|
||||
//archive >> ref<QList<T *>, T * const &>("item", list, &QList<T *>::append);
|
||||
archive >> ref(QStringLiteral("item"), list, &QList<T *>::append);
|
||||
@@ -104,10 +95,9 @@ inline void load(Archive &archive, QList<T *> &list)
|
||||
// QSet
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void save(Archive &archive, const QSet<T> &set)
|
||||
inline void save(Archive &archive, const QSet<T> &set, const Parameters &)
|
||||
{
|
||||
archive << tag("qset");
|
||||
archive.clearFlag(impl::container_item_ref_flag);
|
||||
foreach (const T &t, set) {
|
||||
archive << attr(QStringLiteral("item"), t);
|
||||
}
|
||||
@@ -115,10 +105,10 @@ inline void save(Archive &archive, const QSet<T> &set)
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void save(Archive &archive, const QSet<T *> &set)
|
||||
inline void save(Archive &archive, const QSet<T *> &set, const Parameters ¶meters)
|
||||
{
|
||||
archive << tag("qset");
|
||||
if (archive.takeFlag(impl::container_item_ref_flag)) {
|
||||
if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
|
||||
foreach (const T *t, set) {
|
||||
archive << ref(QStringLiteral("item"), t);
|
||||
}
|
||||
@@ -140,7 +130,7 @@ void insertIntoSet(QSet<T> &set, const T &t) {
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void load(Archive &archive, QSet<T> &set)
|
||||
inline void load(Archive &archive, QSet<T> &set, const Parameters &)
|
||||
{
|
||||
archive >> tag(QStringLiteral("qset"));
|
||||
archive >> attr<QSet<T>, const T &>(QStringLiteral("item"), set, &impl::insertIntoSet<T>);
|
||||
@@ -148,10 +138,10 @@ inline void load(Archive &archive, QSet<T> &set)
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void load(Archive &archive, QSet<T *> &set)
|
||||
inline void load(Archive &archive, QSet<T *> &set, const Parameters ¶meters)
|
||||
{
|
||||
archive >> tag(QStringLiteral("qset"));
|
||||
if (archive.takeFlag(impl::container_item_ref_flag)) {
|
||||
if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
|
||||
archive >> ref(QStringLiteral("item"), set, &impl::insertIntoSet<T *>);
|
||||
} else {
|
||||
archive >> attr<QSet<T *>, T * const &>(QStringLiteral("item"), set, &impl::insertIntoSet<T *>);
|
||||
@@ -177,7 +167,7 @@ public:
|
||||
}
|
||||
|
||||
template<class Archive, class KEY, class VALUE>
|
||||
inline void save(Archive &archive, const impl::KeyValuePair<KEY, VALUE> &pair)
|
||||
inline void save(Archive &archive, const impl::KeyValuePair<KEY, VALUE> &pair, const Parameters &)
|
||||
{
|
||||
archive << tag(QStringLiteral("pair"))
|
||||
<< attr(QStringLiteral("key"), pair._key)
|
||||
@@ -186,7 +176,7 @@ inline void save(Archive &archive, const impl::KeyValuePair<KEY, VALUE> &pair)
|
||||
}
|
||||
|
||||
template<class Archive, class KEY, class VALUE>
|
||||
inline void load(Archive &archive, impl::KeyValuePair<KEY, VALUE> &pair)
|
||||
inline void load(Archive &archive, impl::KeyValuePair<KEY, VALUE> &pair, const Parameters &)
|
||||
{
|
||||
archive >> tag(QStringLiteral("pair"))
|
||||
>> attr(QStringLiteral("key"), pair._key)
|
||||
@@ -195,7 +185,7 @@ inline void load(Archive &archive, impl::KeyValuePair<KEY, VALUE> &pair)
|
||||
}
|
||||
|
||||
template<class Archive, class KEY, class VALUE>
|
||||
inline void save(Archive &archive, const QHash<KEY, VALUE> &hash)
|
||||
inline void save(Archive &archive, const QHash<KEY, VALUE> &hash, const Parameters &)
|
||||
{
|
||||
archive << tag(QStringLiteral("qhash"));
|
||||
for (typename QHash<KEY, VALUE>::const_iterator it = hash.begin(); it != hash.end(); ++it) {
|
||||
@@ -216,7 +206,7 @@ inline void keyValuePairInsert(QHash<KEY, VALUE> &hash, const KeyValuePair<KEY,
|
||||
}
|
||||
|
||||
template<class Archive, class KEY, class VALUE>
|
||||
inline void load(Archive &archive, QHash<KEY, VALUE> &hash)
|
||||
inline void load(Archive &archive, QHash<KEY, VALUE> &hash, const Parameters &)
|
||||
{
|
||||
archive >> tag(QStringLiteral("qhash"));
|
||||
archive >> attr(QStringLiteral("item"), hash, &impl::keyValuePairInsert<KEY, VALUE>);
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#ifndef QARK_SERIALIZE_ENUM_H
|
||||
#define QARK_SERIALIZE_ENUM_H
|
||||
|
||||
#include "parameters.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace qark {
|
||||
@@ -38,13 +40,13 @@ namespace qark {
|
||||
#if 0 // ambigous with default implementation in access.h
|
||||
|
||||
template<class Archive, typename T>
|
||||
inline typename std::enable_if<std::is_enum<T>::value, void>::type save(Archive &archive, const T &value)
|
||||
inline typename std::enable_if<std::is_enum<T>::value, void>::type save(Archive &archive, const T &value, const Parameters &)
|
||||
{
|
||||
archive.write((int) value);
|
||||
}
|
||||
|
||||
template<class Archive, typename T>
|
||||
inline typename std::enable_if<std::is_enum<T>::value, void>::type load(Archive &archive, T &value)
|
||||
inline typename std::enable_if<std::is_enum<T>::value, void>::type load(Archive &archive, T &value, const Parameters &)
|
||||
{
|
||||
int i = 0;
|
||||
archive.read(&i);
|
||||
@@ -55,12 +57,12 @@ inline typename std::enable_if<std::is_enum<T>::value, void>::type load(Archive
|
||||
|
||||
#define QARK_SERIALIZE_ENUM(ENUM) \
|
||||
template<class Archive> \
|
||||
inline void save(Archive &archive, const ENUM &e) \
|
||||
inline void save(Archive &archive, const ENUM &e, const Parameters &) \
|
||||
{ \
|
||||
archive.write((int) e); \
|
||||
} \
|
||||
template<class Archive> \
|
||||
inline void load(Archive &archive, ENUM &e) \
|
||||
inline void load(Archive &archive, ENUM &e, const Parameters &) \
|
||||
{ \
|
||||
int i = 0; \
|
||||
archive.read(&i); \
|
||||
@@ -68,13 +70,13 @@ inline typename std::enable_if<std::is_enum<T>::value, void>::type load(Archive
|
||||
}
|
||||
|
||||
template<class Archive, typename T>
|
||||
inline void save(Archive &archive, const QFlags<T> &flags)
|
||||
inline void save(Archive &archive, const QFlags<T> &flags, const Parameters &)
|
||||
{
|
||||
archive.write((typename QFlags<T>::Int) flags);
|
||||
}
|
||||
|
||||
template<class Archive, typename T>
|
||||
inline void load(Archive &archive, QFlags<T> &flags)
|
||||
inline void load(Archive &archive, QFlags<T> &flags, const Parameters &)
|
||||
{
|
||||
typename QFlags<T>::Int i = 0;
|
||||
archive.read(&i);
|
||||
|
||||
98
src/libs/3rdparty/modeling/qtserialization/inc/qark/serialize_pointer.h
vendored
Normal file
98
src/libs/3rdparty/modeling/qtserialization/inc/qark/serialize_pointer.h
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QARK_SERIALIZE_POINTER_H
|
||||
#define QARK_SERIALIZE_POINTER_H
|
||||
|
||||
#include "typeregistry.h"
|
||||
|
||||
namespace qark {
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void save(Archive &archive, T *p, const Parameters &)
|
||||
{
|
||||
if (p) {
|
||||
if (archive.isReference(p)) {
|
||||
archive.beginPointer();
|
||||
archive.write(p);
|
||||
archive.endPointer();
|
||||
} else {
|
||||
if (typeid(*p) == typeid(T)) {
|
||||
archive.beginInstance();
|
||||
registry::save_pointer<Archive, T, T>(archive, p);
|
||||
archive.endInstance();
|
||||
} else {
|
||||
archive.beginInstance(get_type_uid(*p));
|
||||
typename registry::TypeRegistry<Archive, T>::type_info type_data = get_type_info<Archive, T>(*p);
|
||||
if (type_data.save_func == 0) {
|
||||
throw unregistered_type();
|
||||
} else {
|
||||
type_data.save_func(archive, p);
|
||||
}
|
||||
archive.endInstance();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
archive.beginNullPointer();
|
||||
archive.endNullPointer();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
void load(Archive &archive, T *&p, const Parameters &)
|
||||
{
|
||||
typename Archive::ReferenceTag ref_tag = archive.readReferenceTag();
|
||||
switch (ref_tag.kind) {
|
||||
case Archive::NULLPOINTER:
|
||||
p = 0;
|
||||
break;
|
||||
case Archive::POINTER:
|
||||
archive.read(p);
|
||||
break;
|
||||
case Archive::INSTANCE:
|
||||
if (ref_tag.type_name.isEmpty()) {
|
||||
registry::load_non_virtual_pointer<Archive,T>(archive, p);
|
||||
} else {
|
||||
typename registry::TypeRegistry<Archive, T>::type_info type_data = get_type_info<Archive, T>(ref_tag.type_name);
|
||||
if (type_data.load_func == 0) {
|
||||
throw unregistered_type();
|
||||
} else {
|
||||
type_data.load_func(archive, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
archive.readReferenceEndTag(ref_tag.kind);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // QARK_SERIALIZE_POINTER_H
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#define QARK_TAG_H
|
||||
|
||||
#include "typeregistry.h"
|
||||
#include "parameters.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
@@ -45,10 +46,19 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
Tag(const QString &qualified_name, const Parameters ¶meters)
|
||||
: _qualified_name(qualified_name),
|
||||
_parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &getQualifiedName() const { return _qualified_name; }
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
QString _qualified_name;
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
|
||||
@@ -57,12 +67,18 @@ class Object :
|
||||
public Tag
|
||||
{
|
||||
public:
|
||||
explicit Object(const QString &qualified_name, T *object)
|
||||
Object(const QString &qualified_name, T *object)
|
||||
: Tag(qualified_name),
|
||||
_object(object)
|
||||
{
|
||||
}
|
||||
|
||||
Object(const QString &qualified_name, T *object, const Parameters ¶meters)
|
||||
: Tag(qualified_name, parameters),
|
||||
_object(object)
|
||||
{
|
||||
}
|
||||
|
||||
T *getObject() const { return _object; }
|
||||
|
||||
private:
|
||||
@@ -75,28 +91,61 @@ inline Tag tag(const QString &qualified_name)
|
||||
return Tag(qualified_name);
|
||||
}
|
||||
|
||||
inline Tag tag(const QString &qualified_name, const Parameters ¶meters)
|
||||
{
|
||||
return Tag(qualified_name, parameters);
|
||||
}
|
||||
|
||||
inline Tag tag(const char *qualified_name)
|
||||
{
|
||||
return Tag(QLatin1String(qualified_name));
|
||||
}
|
||||
|
||||
inline Tag tag(const char *qualified_name, const Parameters ¶meters)
|
||||
{
|
||||
return Tag(QLatin1String(qualified_name), parameters);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline Object<T> tag(T &object)
|
||||
{
|
||||
return Object<T>(get_type_uid<T>(), &object);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline Object<T> tag(T &object, const Parameters ¶meters)
|
||||
{
|
||||
return Object<T>(get_type_uid<T>(), &object, parameters);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline Object<T> tag(const QString &qualified_name, T &object)
|
||||
{
|
||||
return Object<T>(qualified_name, &object);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline Object<T> tag(const QString &qualified_name, T &object, const Parameters ¶meters)
|
||||
{
|
||||
return Object<T>(qualified_name, &object, parameters);
|
||||
}
|
||||
|
||||
|
||||
class End {
|
||||
public:
|
||||
explicit End() { }
|
||||
explicit End()
|
||||
{
|
||||
}
|
||||
|
||||
explicit End(const Parameters ¶meters)
|
||||
: _parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
Parameters getParameters() const { return _parameters; }
|
||||
|
||||
private:
|
||||
Parameters _parameters;
|
||||
};
|
||||
|
||||
inline End end()
|
||||
@@ -104,6 +153,10 @@ inline End end()
|
||||
return End();
|
||||
}
|
||||
|
||||
inline End end(const Parameters ¶meters)
|
||||
{
|
||||
return End(parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#ifndef QARK_TYPEREGISTRY_H
|
||||
#define QARK_TYPEREGISTRY_H
|
||||
|
||||
#include "parameters.h"
|
||||
|
||||
#include "qmt/infrastructure/qmtassert.h"
|
||||
|
||||
#include <exception>
|
||||
@@ -219,7 +221,7 @@ template<class Archive, class BASE, class DERIVED>
|
||||
Archive &save_pointer(Archive &ar, BASE * const &p)
|
||||
{
|
||||
DERIVED &t = dynamic_cast<DERIVED &>(*p);
|
||||
ar << t;
|
||||
save(ar, t, Parameters());
|
||||
return ar;
|
||||
}
|
||||
|
||||
@@ -227,7 +229,7 @@ template<class Archive, class BASE, class DERIVED>
|
||||
Archive &load_pointer(Archive &ar, BASE *&p)
|
||||
{
|
||||
DERIVED *t = new DERIVED();
|
||||
ar >> *t;
|
||||
load(ar, *t, Parameters());
|
||||
p = t;
|
||||
return ar;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ HEADERS += \
|
||||
$$PWD/inc/qark/baseclass.h \
|
||||
$$PWD/inc/qark/flag.h \
|
||||
$$PWD/inc/qark/friend_access.h \
|
||||
$$PWD/inc/qark/parameters.h \
|
||||
$$PWD/inc/qark/qxmlinarchive.h \
|
||||
$$PWD/inc/qark/qxmloutarchive.h \
|
||||
$$PWD/inc/qark/reference.h \
|
||||
@@ -13,6 +14,7 @@ HEADERS += \
|
||||
$$PWD/inc/qark/serialize_basic.h \
|
||||
$$PWD/inc/qark/serialize_container.h \
|
||||
$$PWD/inc/qark/serialize_enum.h \
|
||||
$$PWD/inc/qark/serialize_pointer.h \
|
||||
$$PWD/inc/qark/tag.h \
|
||||
$$PWD/inc/qark/typeregistry.h \
|
||||
$$PWD/inc/qark/impl/loadingrefmap.h \
|
||||
|
||||
@@ -45,7 +45,8 @@ SOURCES += $$PWD/ipcserverinterface.cpp \
|
||||
$$PWD/fixitcontainer.cpp \
|
||||
$$PWD/requestdiagnosticsmessage.cpp \
|
||||
$$PWD/registerunsavedfilesforeditormessage.cpp \
|
||||
$$PWD/unregisterunsavedfilesforeditormessage.cpp
|
||||
$$PWD/unregisterunsavedfilesforeditormessage.cpp \
|
||||
$$PWD/updatetranslationunitsforeditormessage.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/ipcserverinterface.h \
|
||||
@@ -85,6 +86,7 @@ HEADERS += \
|
||||
$$PWD/fixitcontainer.h \
|
||||
$$PWD/requestdiagnosticsmessage.h \
|
||||
$$PWD/registerunsavedfilesforeditormessage.h \
|
||||
$$PWD/unregisterunsavedfilesforeditormessage.h
|
||||
$$PWD/unregisterunsavedfilesforeditormessage.h \
|
||||
$$PWD/updatetranslationunitsforeditormessage.h
|
||||
|
||||
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#endif
|
||||
|
||||
namespace ClangBackEnd {
|
||||
CMBIPC_EXPORT void registerTypes();
|
||||
|
||||
enum class DiagnosticSeverity // one to one mapping of the clang enum numbers
|
||||
{
|
||||
|
||||
@@ -48,95 +48,53 @@
|
||||
#include "sourcerangecontainer.h"
|
||||
#include "translationunitdoesnotexistmessage.h"
|
||||
#include "unregisterunsavedfilesforeditormessage.h"
|
||||
#include "updatetranslationunitsforeditormessage.h"
|
||||
|
||||
#include <QDataStream>
|
||||
|
||||
template <typename T>
|
||||
static void registerMetaType()
|
||||
{
|
||||
qRegisterMetaType<T>();
|
||||
qRegisterMetaTypeStreamOperators<T>();
|
||||
QMetaType::registerComparators<T>();
|
||||
}
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
void Messages::registerMessages()
|
||||
{
|
||||
qRegisterMetaType<EndMessage>();
|
||||
qRegisterMetaTypeStreamOperators<EndMessage>();
|
||||
QMetaType::registerComparators<EndMessage>();
|
||||
// Messages
|
||||
registerMetaType<AliveMessage>();
|
||||
registerMetaType<EchoMessage>();
|
||||
registerMetaType<EndMessage>();
|
||||
|
||||
qRegisterMetaType<AliveMessage>();
|
||||
qRegisterMetaTypeStreamOperators<AliveMessage>();
|
||||
QMetaType::registerComparators<AliveMessage>();
|
||||
registerMetaType<RegisterTranslationUnitForEditorMessage>();
|
||||
registerMetaType<UpdateTranslationUnitsForEditorMessage>();
|
||||
registerMetaType<UnregisterTranslationUnitsForEditorMessage>();
|
||||
|
||||
qRegisterMetaType<EchoMessage>();
|
||||
qRegisterMetaTypeStreamOperators<EchoMessage>();
|
||||
registerMetaType<RegisterUnsavedFilesForEditorMessage>();
|
||||
registerMetaType<UnregisterUnsavedFilesForEditorMessage>();
|
||||
|
||||
qRegisterMetaType<RegisterTranslationUnitForEditorMessage>();
|
||||
qRegisterMetaTypeStreamOperators<RegisterTranslationUnitForEditorMessage>();
|
||||
QMetaType::registerComparators<RegisterTranslationUnitForEditorMessage>();
|
||||
registerMetaType<RegisterProjectPartsForEditorMessage>();
|
||||
registerMetaType<UnregisterProjectPartsForEditorMessage>();
|
||||
|
||||
qRegisterMetaType<FileContainer>();
|
||||
qRegisterMetaTypeStreamOperators<FileContainer>();
|
||||
QMetaType::registerComparators<FileContainer>();
|
||||
registerMetaType<RequestDiagnosticsMessage>();
|
||||
registerMetaType<DiagnosticsChangedMessage>();
|
||||
|
||||
qRegisterMetaType<UnregisterTranslationUnitsForEditorMessage>();
|
||||
qRegisterMetaTypeStreamOperators<UnregisterTranslationUnitsForEditorMessage>();
|
||||
QMetaType::registerComparators<UnregisterTranslationUnitsForEditorMessage>();
|
||||
registerMetaType<CompleteCodeMessage>();
|
||||
registerMetaType<CodeCompletedMessage>();
|
||||
registerMetaType<CodeCompletion>();
|
||||
|
||||
qRegisterMetaType<CompleteCodeMessage>();
|
||||
qRegisterMetaTypeStreamOperators<CompleteCodeMessage>();
|
||||
QMetaType::registerComparators<CompleteCodeMessage>();
|
||||
registerMetaType<TranslationUnitDoesNotExistMessage>();
|
||||
registerMetaType<ProjectPartsDoNotExistMessage>();
|
||||
|
||||
qRegisterMetaType<CodeCompletion>();
|
||||
qRegisterMetaTypeStreamOperators<CodeCompletion>();
|
||||
QMetaType::registerComparators<CodeCompletion>();
|
||||
|
||||
qRegisterMetaType<CodeCompletedMessage>();
|
||||
qRegisterMetaTypeStreamOperators<CodeCompletedMessage>();
|
||||
QMetaType::registerComparators<CodeCompletedMessage>();
|
||||
|
||||
qRegisterMetaType<RegisterProjectPartsForEditorMessage>();
|
||||
qRegisterMetaTypeStreamOperators<RegisterProjectPartsForEditorMessage>();
|
||||
QMetaType::registerComparators<RegisterProjectPartsForEditorMessage>();
|
||||
|
||||
qRegisterMetaType<ProjectPartContainer>();
|
||||
qRegisterMetaTypeStreamOperators<ProjectPartContainer>();
|
||||
QMetaType::registerComparators<ProjectPartContainer>();
|
||||
|
||||
qRegisterMetaType<UnregisterProjectPartsForEditorMessage>();
|
||||
qRegisterMetaTypeStreamOperators<UnregisterProjectPartsForEditorMessage>();
|
||||
QMetaType::registerComparators<UnregisterProjectPartsForEditorMessage>();
|
||||
|
||||
qRegisterMetaType<TranslationUnitDoesNotExistMessage>();
|
||||
qRegisterMetaTypeStreamOperators<TranslationUnitDoesNotExistMessage>();
|
||||
QMetaType::registerComparators<TranslationUnitDoesNotExistMessage>();
|
||||
|
||||
qRegisterMetaType<ProjectPartsDoNotExistMessage>();
|
||||
qRegisterMetaTypeStreamOperators<ProjectPartsDoNotExistMessage>();
|
||||
QMetaType::registerComparators<ProjectPartsDoNotExistMessage>();
|
||||
|
||||
qRegisterMetaType<DiagnosticsChangedMessage>();
|
||||
qRegisterMetaTypeStreamOperators<DiagnosticsChangedMessage>();
|
||||
QMetaType::registerComparators<DiagnosticsChangedMessage>();
|
||||
|
||||
qRegisterMetaType<DiagnosticContainer>();
|
||||
qRegisterMetaTypeStreamOperators<DiagnosticContainer>();
|
||||
QMetaType::registerComparators<DiagnosticContainer>();
|
||||
|
||||
qRegisterMetaType<SourceLocationContainer>();
|
||||
qRegisterMetaTypeStreamOperators<SourceLocationContainer>();
|
||||
QMetaType::registerComparators<SourceLocationContainer>();
|
||||
|
||||
qRegisterMetaType<SourceRangeContainer>();
|
||||
qRegisterMetaTypeStreamOperators<SourceRangeContainer>();
|
||||
QMetaType::registerComparators<SourceRangeContainer>();
|
||||
|
||||
qRegisterMetaType<RequestDiagnosticsMessage>();
|
||||
qRegisterMetaTypeStreamOperators<RequestDiagnosticsMessage>();
|
||||
QMetaType::registerComparators<RequestDiagnosticsMessage>();
|
||||
|
||||
qRegisterMetaType<RegisterUnsavedFilesForEditorMessage>();
|
||||
qRegisterMetaTypeStreamOperators<RegisterUnsavedFilesForEditorMessage>();
|
||||
QMetaType::registerComparators<RegisterUnsavedFilesForEditorMessage>();
|
||||
|
||||
qRegisterMetaType<UnregisterUnsavedFilesForEditorMessage>();
|
||||
qRegisterMetaTypeStreamOperators<UnregisterUnsavedFilesForEditorMessage>();
|
||||
QMetaType::registerComparators<UnregisterUnsavedFilesForEditorMessage>();
|
||||
// Containers
|
||||
registerMetaType<DiagnosticContainer>();
|
||||
registerMetaType<FileContainer>();
|
||||
registerMetaType<ProjectPartContainer>();
|
||||
registerMetaType<SourceLocationContainer>();
|
||||
registerMetaType<SourceRangeContainer>();
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace ClangBackEnd {
|
||||
|
||||
class IpcServerInterface;
|
||||
class RegisterTranslationUnitForEditorMessage;
|
||||
class UpdateTranslationUnitsForEditorMessage;
|
||||
class RegisterProjectPartsForEditorMessage;
|
||||
class UnregisterTranslationUnitsForEditorMessage;
|
||||
class UnregisterProjectPartsForEditorMessage;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "registerunsavedfilesforeditormessage.h"
|
||||
#include "requestdiagnosticsmessage.h"
|
||||
#include "unregisterunsavedfilesforeditormessage.h"
|
||||
#include "updatetranslationunitsforeditormessage.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QVariant>
|
||||
@@ -48,6 +49,7 @@ void IpcServerInterface::dispatch(const QVariant &message)
|
||||
{
|
||||
static const int endMessageType = QMetaType::type("ClangBackEnd::EndMessage");
|
||||
static const int registerTranslationUnitsForEditorMessageType = QMetaType::type("ClangBackEnd::RegisterTranslationUnitForEditorMessage");
|
||||
static const int updateTranslationUnitsForEditorMessageType = QMetaType::type("ClangBackEnd::UpdateTranslationUnitsForEditorMessage");
|
||||
static const int unregisterTranslationUnitsForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterTranslationUnitsForEditorMessage");
|
||||
static const int registerProjectPartsForEditorMessageType = QMetaType::type("ClangBackEnd::RegisterProjectPartsForEditorMessage");
|
||||
static const int unregisterProjectPartsForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterProjectPartsForEditorMessage");
|
||||
@@ -62,6 +64,8 @@ void IpcServerInterface::dispatch(const QVariant &message)
|
||||
end();
|
||||
else if (type == registerTranslationUnitsForEditorMessageType)
|
||||
registerTranslationUnitsForEditor(message.value<RegisterTranslationUnitForEditorMessage>());
|
||||
else if (type == updateTranslationUnitsForEditorMessageType)
|
||||
updateTranslationUnitsForEditor(message.value<UpdateTranslationUnitsForEditorMessage>());
|
||||
else if (type == unregisterTranslationUnitsForEditorMessageType)
|
||||
unregisterTranslationUnitsForEditor(message.value<UnregisterTranslationUnitsForEditorMessage>());
|
||||
else if (type == registerProjectPartsForEditorMessageType)
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
|
||||
virtual void end() = 0;
|
||||
virtual void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) = 0;
|
||||
virtual void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) = 0;
|
||||
virtual void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) = 0;
|
||||
virtual void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) = 0;
|
||||
virtual void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) = 0;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <registerunsavedfilesforeditormessage.h>
|
||||
#include <requestdiagnosticsmessage.h>
|
||||
#include <unregisterunsavedfilesforeditormessage.h>
|
||||
#include <updatetranslationunitsforeditormessage.h>
|
||||
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
@@ -78,6 +79,11 @@ void IpcServerProxy::registerTranslationUnitsForEditor(const RegisterTranslation
|
||||
writeMessageBlock.write(QVariant::fromValue(message));
|
||||
}
|
||||
|
||||
void IpcServerProxy::updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
writeMessageBlock.write(QVariant::fromValue(message));
|
||||
}
|
||||
|
||||
void IpcServerProxy::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
writeMessageBlock.write(QVariant::fromValue(message));
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
|
||||
void end() override;
|
||||
void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override;
|
||||
void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) override;
|
||||
void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override;
|
||||
void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) override;
|
||||
void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) override;
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://www.qt.io/licensing. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "updatetranslationunitsforeditormessage.h"
|
||||
|
||||
#include "container_common.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
UpdateTranslationUnitsForEditorMessage::UpdateTranslationUnitsForEditorMessage(const QVector<FileContainer> &fileContainers)
|
||||
: fileContainers_(fileContainers)
|
||||
{
|
||||
}
|
||||
|
||||
const QVector<FileContainer> &UpdateTranslationUnitsForEditorMessage::fileContainers() const
|
||||
{
|
||||
return fileContainers_;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const UpdateTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
out << message.fileContainers_;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, UpdateTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
in >> message.fileContainers_;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
bool operator==(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second)
|
||||
{
|
||||
return first.fileContainers_ == second.fileContainers_;
|
||||
}
|
||||
|
||||
bool operator<(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second)
|
||||
{
|
||||
return compareContainer(first.fileContainers_, second.fileContainers_);
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const UpdateTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
debug.nospace() << "UpdateTranslationUnitsForEditorMessage(";
|
||||
|
||||
for (const FileContainer &fileContainer : message.fileContainers())
|
||||
debug.nospace() << fileContainer<< ", ";
|
||||
|
||||
debug.nospace() << ")";
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
void PrintTo(const UpdateTranslationUnitsForEditorMessage &message, ::std::ostream* os)
|
||||
{
|
||||
*os << "UpdateTranslationUnitsForEditorMessage(";
|
||||
|
||||
for (const FileContainer &fileContainer : message.fileContainers())
|
||||
PrintTo(fileContainer, os);
|
||||
|
||||
*os << ")";
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://www.qt.io/licensing. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CLANGBACKEND_UPDATEFILEFOREDITOR_H
|
||||
#define CLANGBACKEND_UPDATEFILEFOREDITOR_H
|
||||
|
||||
#include "filecontainer.h"
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QVector>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class CMBIPC_EXPORT UpdateTranslationUnitsForEditorMessage
|
||||
{
|
||||
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const UpdateTranslationUnitsForEditorMessage &message);
|
||||
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, UpdateTranslationUnitsForEditorMessage &message);
|
||||
friend CMBIPC_EXPORT bool operator==(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second);
|
||||
friend CMBIPC_EXPORT bool operator<(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second);
|
||||
friend void PrintTo(const UpdateTranslationUnitsForEditorMessage &message, ::std::ostream* os);
|
||||
public:
|
||||
UpdateTranslationUnitsForEditorMessage() = default;
|
||||
UpdateTranslationUnitsForEditorMessage(const QVector<FileContainer> &fileContainers);
|
||||
|
||||
const QVector<FileContainer> &fileContainers() const;
|
||||
|
||||
private:
|
||||
QVector<FileContainer> fileContainers_;
|
||||
};
|
||||
|
||||
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const UpdateTranslationUnitsForEditorMessage &message);
|
||||
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, UpdateTranslationUnitsForEditorMessage &message);
|
||||
CMBIPC_EXPORT bool operator==(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second);
|
||||
CMBIPC_EXPORT bool operator<(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second);
|
||||
|
||||
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const UpdateTranslationUnitsForEditorMessage &message);
|
||||
void PrintTo(const UpdateTranslationUnitsForEditorMessage &message, ::std::ostream* os);
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
Q_DECLARE_METATYPE(ClangBackEnd::UpdateTranslationUnitsForEditorMessage)
|
||||
|
||||
#endif // CLANGBACKEND_UPDATEFILEFOREDITOR_H
|
||||
@@ -734,7 +734,7 @@ void Preprocessor::State::updateIncludeGuardState_helper(IncludeGuardStateHint h
|
||||
#endif // DEBUG_INCLUDE_GUARD_TRACKING
|
||||
}
|
||||
|
||||
const QString Preprocessor::configurationFileName = QLatin1String("<configuration>");
|
||||
QString Preprocessor::configurationFileName() { return QStringLiteral("<configuration>"); }
|
||||
|
||||
Preprocessor::Preprocessor(Client *client, Environment *env)
|
||||
: m_client(client)
|
||||
@@ -1978,7 +1978,7 @@ void Preprocessor::handleIfDefDirective(bool checkUndefined, PPToken *tk)
|
||||
|
||||
// the macro is a feature constraint(e.g. QT_NO_XXX)
|
||||
if (checkUndefined && macroName.startsWith("QT_NO_")) {
|
||||
if (macro->fileName() == configurationFileName) {
|
||||
if (macro->fileName() == configurationFileName()) {
|
||||
// and it' defined in a pro file (e.g. DEFINES += QT_NO_QOBJECT)
|
||||
|
||||
value = false; // take the branch
|
||||
|
||||
@@ -77,7 +77,7 @@ class CPLUSPLUS_EXPORT Preprocessor
|
||||
typedef Internal::Value Value;
|
||||
|
||||
public:
|
||||
static const QString configurationFileName;
|
||||
static QString configurationFileName();
|
||||
|
||||
public:
|
||||
Preprocessor(Client *client, Environment *env);
|
||||
|
||||
@@ -234,8 +234,6 @@ QtcLibrary {
|
||||
"project/project.h",
|
||||
"project_controller/projectcontroller.cpp",
|
||||
"project_controller/projectcontroller.h",
|
||||
"serializer/diagramreferenceserializer.cpp",
|
||||
"serializer/diagramreferenceserializer.h",
|
||||
"serializer/diagramserializer.cpp",
|
||||
"serializer/diagramserializer.h",
|
||||
"serializer/infrastructureserializer.cpp",
|
||||
@@ -314,6 +312,7 @@ QtcLibrary {
|
||||
"inc/qark/impl/loadingrefmap.h",
|
||||
"inc/qark/impl/objectid.h",
|
||||
"inc/qark/impl/savingrefmap.h",
|
||||
"inc/qark/parameters.h",
|
||||
"inc/qark/qxmlinarchive.h",
|
||||
"inc/qark/qxmloutarchive.h",
|
||||
"inc/qark/reference.h",
|
||||
@@ -321,6 +320,7 @@ QtcLibrary {
|
||||
"inc/qark/serialize_basic.h",
|
||||
"inc/qark/serialize_container.h",
|
||||
"inc/qark/serialize_enum.h",
|
||||
"inc/qark/serialize_pointer.h",
|
||||
"inc/qark/tag.h",
|
||||
"inc/qark/typeregistry.h",
|
||||
"src/flag.cpp",
|
||||
|
||||
@@ -481,7 +481,7 @@ bool operator <(const ImportKey &i1, const ImportKey &i2)
|
||||
return i1.compare(i2) < 0;
|
||||
}
|
||||
|
||||
const QString Export::LibraryTypeName = QLatin1String("%Library%");
|
||||
QString Export::libraryTypeName() { return QStringLiteral("%Library%"); }
|
||||
|
||||
Export::Export()
|
||||
: intrinsic(false)
|
||||
|
||||
@@ -131,10 +131,10 @@ bool operator <(const ImportKey &i1, const ImportKey &i2);
|
||||
class QMLJS_EXPORT Export
|
||||
{
|
||||
public:
|
||||
static const QString LibraryTypeName;
|
||||
static QString libraryTypeName();
|
||||
Export();
|
||||
Export(ImportKey exportName, QString pathRequired, bool intrinsic = false,
|
||||
const QString &typeName = LibraryTypeName);
|
||||
const QString &typeName = libraryTypeName());
|
||||
ImportKey exportName;
|
||||
QString pathRequired;
|
||||
QString typeName;
|
||||
@@ -211,9 +211,9 @@ public:
|
||||
void removeCoreImport(const QString &importId);
|
||||
|
||||
void addExport(const QString &importId, const ImportKey &importKey,
|
||||
const QString &requiredPath, const QString &typeName = Export::LibraryTypeName);
|
||||
const QString &requiredPath, const QString &typeName = Export::libraryTypeName());
|
||||
void removeExport(const QString &importId, const ImportKey &importKey,
|
||||
const QString &requiredPath, const QString &typeName = Export::LibraryTypeName);
|
||||
const QString &requiredPath, const QString &typeName = Export::libraryTypeName());
|
||||
|
||||
void iterateOnCoreImports(const ViewerContext &vContext,
|
||||
std::function<bool(const CoreImport &)> const &iterF) const;
|
||||
|
||||
@@ -273,7 +273,7 @@ void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
|
||||
imports->setImportFailed();
|
||||
if (info.ast()) {
|
||||
error(doc, info.ast()->fileNameToken,
|
||||
Link::tr("file or directory not found"));
|
||||
Link::tr("File or directory not found."));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -436,11 +436,11 @@ Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInf
|
||||
error(doc, locationFromRange(importInfo.ast()->firstSourceLocation(),
|
||||
importInfo.ast()->lastSourceLocation()),
|
||||
Link::tr(
|
||||
"QML module not found\n\n"
|
||||
"QML module not found.\n\n"
|
||||
"Import paths:\n"
|
||||
"%1\n\n"
|
||||
"For qmake projects, use the QML_IMPORT_PATH variable to add import paths.\n"
|
||||
"For qbs projects, declare and set a qmlImportPaths property in your product "
|
||||
"For Qbs projects, declare and set a qmlImportPaths property in your product "
|
||||
"to add import paths.\n"
|
||||
"For qmlproject projects, use the importPaths property to add import paths.").arg(
|
||||
importPaths.join(QLatin1Char('\n'))));
|
||||
|
||||
@@ -49,17 +49,17 @@ std::wstring StackFrame::fileName() const
|
||||
|
||||
void StackFrame::formatGDBMI(std::ostream &str, unsigned level) const
|
||||
{
|
||||
str << "frame={level=\"" << level << "\",addr=\"0x"
|
||||
str << "frame={level=\"" << level << "\",address=\"0x"
|
||||
<< std::hex << address << std::dec << '"';
|
||||
if (!function.empty()) {
|
||||
// Split into module/function
|
||||
const std::wstring::size_type exclPos = function.find('!');
|
||||
if (exclPos == std::wstring::npos) {
|
||||
str << ",func=\"" << gdbmiWStringFormat(function) << '"';
|
||||
str << ",function=\"" << gdbmiWStringFormat(function) << '"';
|
||||
} else {
|
||||
const std::wstring module = function.substr(0, exclPos);
|
||||
const std::wstring fn = function.substr(exclPos + 1, function.size() - exclPos - 1);
|
||||
str << ",func=\"" << gdbmiWStringFormat(fn)
|
||||
str << ",function=\"" << gdbmiWStringFormat(fn)
|
||||
<< "\",from=\"" << gdbmiWStringFormat(module) << '"';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +263,6 @@ struct TransformImpl {
|
||||
static C call(const SC &container, F function)
|
||||
{
|
||||
C result;
|
||||
result.reserve(container.size());
|
||||
std::transform(container.begin(), container.end(),
|
||||
inserter(result),
|
||||
function);
|
||||
@@ -337,6 +336,29 @@ auto transform(const SC &container, R (S::*p)() const)
|
||||
>::call(container, p);
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// filtered
|
||||
/////////////////
|
||||
template<typename C, typename F>
|
||||
Q_REQUIRED_RESULT
|
||||
C filtered(const C &container, F predicate)
|
||||
{
|
||||
C out;
|
||||
std::copy_if(container.begin(), container.end(),
|
||||
inserter(out), predicate);
|
||||
return out;
|
||||
}
|
||||
|
||||
template<typename C, typename R, typename S>
|
||||
Q_REQUIRED_RESULT
|
||||
C filtered(const C &container, R (S::*predicate)() const)
|
||||
{
|
||||
C out;
|
||||
std::copy_if(container.begin(), container.end(),
|
||||
inserter(out), std::mem_fn(predicate));
|
||||
return out;
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// sort
|
||||
/////////////////
|
||||
|
||||
@@ -92,46 +92,42 @@ public:
|
||||
virtual bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
FancyLineEdit *m_lineEdit;
|
||||
IconButton *m_iconbutton[2];
|
||||
HistoryCompleter *m_historyCompleter = 0;
|
||||
FancyLineEdit::ValidationFunction m_validationFunction = &FancyLineEdit::validateWithValidator;
|
||||
QString m_oldText;
|
||||
QPixmap m_pixmap[2];
|
||||
QMenu *m_menu[2];
|
||||
FancyLineEdit::State m_state = FancyLineEdit::Invalid;
|
||||
bool m_menuTabFocusTrigger[2];
|
||||
IconButton *m_iconbutton[2];
|
||||
bool m_iconEnabled[2];
|
||||
|
||||
HistoryCompleter *m_historyCompleter;
|
||||
FancyLineEdit::ValidationFunction m_validationFunction;
|
||||
bool m_isFiltering = false;
|
||||
bool m_firstChange = false;
|
||||
|
||||
bool m_isFiltering;
|
||||
QString m_lastFilterText;
|
||||
|
||||
const QColor m_okTextColor;
|
||||
QColor m_errorTextColor;
|
||||
FancyLineEdit::State m_state;
|
||||
QColor m_okTextColor;
|
||||
QColor m_errorTextColor = Qt::red;
|
||||
QString m_errorMessage;
|
||||
QString m_initialText;
|
||||
bool m_firstChange;
|
||||
};
|
||||
|
||||
|
||||
FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
|
||||
QObject(parent),
|
||||
m_lineEdit(parent),
|
||||
m_historyCompleter(0),
|
||||
m_validationFunction(FancyLineEdit::defaultValidationFunction()),
|
||||
m_isFiltering(false),
|
||||
m_okTextColor(FancyLineEdit::textColor(parent)),
|
||||
m_errorTextColor(Qt::red),
|
||||
m_state(FancyLineEdit::Invalid),
|
||||
m_firstChange(true)
|
||||
m_lineEdit(parent)
|
||||
{
|
||||
m_okTextColor = parent->palette().color(QPalette::Active, QPalette::Text);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
m_menu[i] = 0;
|
||||
m_menuTabFocusTrigger[i] = false;
|
||||
m_iconbutton[i] = new IconButton(parent);
|
||||
m_iconbutton[i]->installEventFilter(this);
|
||||
m_iconbutton[i]->hide();
|
||||
m_iconbutton[i]->setAutoHide(false);
|
||||
|
||||
m_menu[i] = 0;
|
||||
|
||||
m_menuTabFocusTrigger[i] = false;
|
||||
m_iconEnabled[i] = false;
|
||||
}
|
||||
}
|
||||
@@ -171,7 +167,7 @@ FancyLineEdit::FancyLineEdit(QWidget *parent) :
|
||||
|
||||
connect(d->m_iconbutton[Left], &QAbstractButton::clicked, this, &FancyLineEdit::iconClicked);
|
||||
connect(d->m_iconbutton[Right], &QAbstractButton::clicked, this, &FancyLineEdit::iconClicked);
|
||||
connect(this, &QLineEdit::textChanged, this, &FancyLineEdit::onTextChanged);
|
||||
connect(this, &QLineEdit::textChanged, this, &FancyLineEdit::validate);
|
||||
}
|
||||
|
||||
FancyLineEdit::~FancyLineEdit()
|
||||
@@ -406,18 +402,18 @@ QColor FancyLineEdit::errorColor() const
|
||||
void FancyLineEdit::setErrorColor(const QColor &c)
|
||||
{
|
||||
d->m_errorTextColor = c;
|
||||
validate();
|
||||
}
|
||||
|
||||
QColor FancyLineEdit::textColor(const QWidget *w)
|
||||
QColor FancyLineEdit::okColor() const
|
||||
{
|
||||
return w->palette().color(QPalette::Active, QPalette::Text);
|
||||
return d->m_okTextColor;
|
||||
}
|
||||
|
||||
void FancyLineEdit::setTextColor(QWidget *w, const QColor &c)
|
||||
void FancyLineEdit::setOkColor(const QColor &c)
|
||||
{
|
||||
QPalette palette = w->palette();
|
||||
palette.setColor(QPalette::Active, QPalette::Text, c);
|
||||
w->setPalette(palette);
|
||||
d->m_okTextColor = c;
|
||||
validate();
|
||||
}
|
||||
|
||||
void FancyLineEdit::setValidationFunction(const FancyLineEdit::ValidationFunction &fn)
|
||||
@@ -456,8 +452,10 @@ QString FancyLineEdit::errorMessage() const
|
||||
return d->m_errorMessage;
|
||||
}
|
||||
|
||||
void FancyLineEdit::onTextChanged(const QString &t)
|
||||
void FancyLineEdit::validate()
|
||||
{
|
||||
const QString t = text();
|
||||
|
||||
if (d->m_isFiltering){
|
||||
if (t != d->m_lastFilterText) {
|
||||
d->m_lastFilterText = t;
|
||||
@@ -478,7 +476,11 @@ void FancyLineEdit::onTextChanged(const QString &t)
|
||||
const bool validHasChanged = (d->m_state == Valid) != (newState == Valid);
|
||||
d->m_state = newState;
|
||||
d->m_firstChange = false;
|
||||
setTextColor(this, newState == Invalid ? d->m_errorTextColor : d->m_okTextColor);
|
||||
|
||||
QPalette p = palette();
|
||||
p.setColor(QPalette::Active, QPalette::Text, newState == Invalid ? d->m_errorTextColor : d->m_okTextColor);
|
||||
setPalette(p);
|
||||
|
||||
if (validHasChanged)
|
||||
emit validChanged(newState == Valid);
|
||||
}
|
||||
@@ -503,17 +505,11 @@ void FancyLineEdit::onTextChanged(const QString &t)
|
||||
handleChanged(t);
|
||||
}
|
||||
|
||||
void FancyLineEdit::triggerChanged()
|
||||
{
|
||||
onTextChanged(text());
|
||||
}
|
||||
|
||||
QString FancyLineEdit::fixInputString(const QString &string)
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// IconButton - helper class to represent a clickable icon
|
||||
//
|
||||
|
||||
@@ -84,6 +84,7 @@ class QTCREATOR_UTILS_EXPORT FancyLineEdit : public CompletingLineEdit
|
||||
// Validation.
|
||||
Q_PROPERTY(QString initialText READ initialText WRITE setInitialText DESIGNABLE true)
|
||||
Q_PROPERTY(QColor errorColor READ errorColor WRITE setErrorColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor okColor READ okColor WRITE setOkColor DESIGNABLE true)
|
||||
|
||||
public:
|
||||
enum Side {Left = 0, Right = 1};
|
||||
@@ -141,18 +142,17 @@ public:
|
||||
void setInitialText(const QString &);
|
||||
|
||||
QColor errorColor() const;
|
||||
void setErrorColor(const QColor &);
|
||||
void setErrorColor(const QColor &c);
|
||||
|
||||
// Trigger an update (after changing settings)
|
||||
void triggerChanged();
|
||||
|
||||
static QColor textColor(const QWidget *w);
|
||||
static void setTextColor(QWidget *w, const QColor &c);
|
||||
QColor okColor() const;
|
||||
void setOkColor(const QColor &c);
|
||||
|
||||
void setValidationFunction(const ValidationFunction &fn);
|
||||
static ValidationFunction defaultValidationFunction();
|
||||
void validate();
|
||||
void onEditingFinished();
|
||||
|
||||
protected slots:
|
||||
protected:
|
||||
// Custom behaviour can be added here.
|
||||
virtual void handleChanged(const QString &) {}
|
||||
|
||||
@@ -166,17 +166,14 @@ signals:
|
||||
void validChanged(bool validState);
|
||||
void validReturnPressed();
|
||||
|
||||
private slots:
|
||||
void iconClicked();
|
||||
void onTextChanged(const QString &);
|
||||
void onEditingFinished();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
virtual QString fixInputString(const QString &string);
|
||||
|
||||
private:
|
||||
void iconClicked();
|
||||
|
||||
static bool validateWithValidator(FancyLineEdit *edit, QString *errorMessage);
|
||||
// Unimplemented, to force the user to make a decision on
|
||||
// whether to use setHistoryCompleter() or setSpecialCompleter().
|
||||
|
||||
@@ -137,28 +137,28 @@ JsonValue *JsonValue::build(const QVariant &variant, JsonMemoryPool *pool)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const QString JsonSchema::kType(QLatin1String("type"));
|
||||
const QString JsonSchema::kProperties(QLatin1String("properties"));
|
||||
const QString JsonSchema::kPatternProperties(QLatin1String("patternProperties"));
|
||||
const QString JsonSchema::kAdditionalProperties(QLatin1String("additionalProperties"));
|
||||
const QString JsonSchema::kItems(QLatin1String("items"));
|
||||
const QString JsonSchema::kAdditionalItems(QLatin1String("additionalItems"));
|
||||
const QString JsonSchema::kRequired(QLatin1String("required"));
|
||||
const QString JsonSchema::kDependencies(QLatin1String("dependencies"));
|
||||
const QString JsonSchema::kMinimum(QLatin1String("minimum"));
|
||||
const QString JsonSchema::kMaximum(QLatin1String("maximum"));
|
||||
const QString JsonSchema::kExclusiveMinimum(QLatin1String("exclusiveMinimum"));
|
||||
const QString JsonSchema::kExclusiveMaximum(QLatin1String("exclusiveMaximum"));
|
||||
const QString JsonSchema::kMinItems(QLatin1String("minItems"));
|
||||
const QString JsonSchema::kMaxItems(QLatin1String("maxItems"));
|
||||
const QString JsonSchema::kUniqueItems(QLatin1String("uniqueItems"));
|
||||
const QString JsonSchema::kPattern(QLatin1String("pattern"));
|
||||
const QString JsonSchema::kMinLength(QLatin1String("minLength"));
|
||||
const QString JsonSchema::kMaxLength(QLatin1String("maxLength"));
|
||||
const QString JsonSchema::kTitle(QLatin1String("title"));
|
||||
const QString JsonSchema::kDescription(QLatin1String("description"));
|
||||
const QString JsonSchema::kExtends(QLatin1String("extends"));
|
||||
const QString JsonSchema::kRef(QLatin1String("$ref"));
|
||||
QString JsonSchema::kType() { return QStringLiteral("type"); }
|
||||
QString JsonSchema::kProperties() { return QStringLiteral("properties"); }
|
||||
QString JsonSchema::kPatternProperties() { return QStringLiteral("patternProperties"); }
|
||||
QString JsonSchema::kAdditionalProperties() { return QStringLiteral("additionalProperties"); }
|
||||
QString JsonSchema::kItems() { return QStringLiteral("items"); }
|
||||
QString JsonSchema::kAdditionalItems() { return QStringLiteral("additionalItems"); }
|
||||
QString JsonSchema::kRequired() { return QStringLiteral("required"); }
|
||||
QString JsonSchema::kDependencies() { return QStringLiteral("dependencies"); }
|
||||
QString JsonSchema::kMinimum() { return QStringLiteral("minimum"); }
|
||||
QString JsonSchema::kMaximum() { return QStringLiteral("maximum"); }
|
||||
QString JsonSchema::kExclusiveMinimum() { return QStringLiteral("exclusiveMinimum"); }
|
||||
QString JsonSchema::kExclusiveMaximum() { return QStringLiteral("exclusiveMaximum"); }
|
||||
QString JsonSchema::kMinItems() { return QStringLiteral("minItems"); }
|
||||
QString JsonSchema::kMaxItems() { return QStringLiteral("maxItems"); }
|
||||
QString JsonSchema::kUniqueItems() { return QStringLiteral("uniqueItems"); }
|
||||
QString JsonSchema::kPattern() { return QStringLiteral("pattern"); }
|
||||
QString JsonSchema::kMinLength() { return QStringLiteral("minLength"); }
|
||||
QString JsonSchema::kMaxLength() { return QStringLiteral("maxLength"); }
|
||||
QString JsonSchema::kTitle() { return QStringLiteral("title"); }
|
||||
QString JsonSchema::kDescription() { return QStringLiteral("description"); }
|
||||
QString JsonSchema::kExtends() { return QStringLiteral("extends"); }
|
||||
QString JsonSchema::kRef() { return QStringLiteral("$ref"); }
|
||||
|
||||
JsonSchema::JsonSchema(JsonObjectValue *rootObject, const JsonSchemaManager *manager)
|
||||
: m_manager(manager)
|
||||
@@ -169,11 +169,11 @@ JsonSchema::JsonSchema(JsonObjectValue *rootObject, const JsonSchemaManager *man
|
||||
bool JsonSchema::isTypeConstrained() const
|
||||
{
|
||||
// Simple types
|
||||
if (JsonStringValue *sv = getStringValue(kType, currentValue()))
|
||||
if (JsonStringValue *sv = getStringValue(kType(), currentValue()))
|
||||
return isCheckableType(sv->value());
|
||||
|
||||
// Union types
|
||||
if (JsonArrayValue *av = getArrayValue(kType, currentValue())) {
|
||||
if (JsonArrayValue *av = getArrayValue(kType(), currentValue())) {
|
||||
QTC_ASSERT(currentIndex() != -1, return false);
|
||||
QTC_ASSERT(av->elements().at(currentIndex())->kind() == JsonValue::String, return false);
|
||||
JsonStringValue *sv = av->elements().at(currentIndex())->toString();
|
||||
@@ -186,11 +186,11 @@ bool JsonSchema::isTypeConstrained() const
|
||||
bool JsonSchema::acceptsType(const QString &type) const
|
||||
{
|
||||
// Simple types
|
||||
if (JsonStringValue *sv = getStringValue(kType, currentValue()))
|
||||
if (JsonStringValue *sv = getStringValue(kType(), currentValue()))
|
||||
return typeMatches(sv->value(), type);
|
||||
|
||||
// Union types
|
||||
if (JsonArrayValue *av = getArrayValue(kType, currentValue())) {
|
||||
if (JsonArrayValue *av = getArrayValue(kType(), currentValue())) {
|
||||
QTC_ASSERT(currentIndex() != -1, return false);
|
||||
QTC_ASSERT(av->elements().at(currentIndex())->kind() == JsonValue::String, return false);
|
||||
JsonStringValue *sv = av->elements().at(currentIndex())->toString();
|
||||
@@ -204,13 +204,13 @@ QStringList JsonSchema::validTypes(JsonObjectValue *v)
|
||||
{
|
||||
QStringList all;
|
||||
|
||||
if (JsonStringValue *sv = getStringValue(kType, v))
|
||||
if (JsonStringValue *sv = getStringValue(kType(), v))
|
||||
all.append(sv->value());
|
||||
|
||||
if (JsonObjectValue *ov = getObjectValue(kType, v))
|
||||
if (JsonObjectValue *ov = getObjectValue(kType(), v))
|
||||
return validTypes(ov);
|
||||
|
||||
if (JsonArrayValue *av = getArrayValue(kType, v)) {
|
||||
if (JsonArrayValue *av = getArrayValue(kType(), v)) {
|
||||
foreach (JsonValue *v, av->elements()) {
|
||||
if (JsonStringValue *sv = v->toString())
|
||||
all.append(sv->value());
|
||||
@@ -252,14 +252,14 @@ QStringList JsonSchema::validTypes() const
|
||||
|
||||
bool JsonSchema::hasTypeSchema() const
|
||||
{
|
||||
return getObjectValue(kType, currentValue());
|
||||
return getObjectValue(kType(), currentValue());
|
||||
}
|
||||
|
||||
void JsonSchema::enterNestedTypeSchema()
|
||||
{
|
||||
QTC_ASSERT(hasTypeSchema(), return);
|
||||
|
||||
enter(getObjectValue(kType, currentValue()));
|
||||
enter(getObjectValue(kType(), currentValue()));
|
||||
}
|
||||
|
||||
QStringList JsonSchema::properties(JsonObjectValue *v) const
|
||||
@@ -268,7 +268,7 @@ QStringList JsonSchema::properties(JsonObjectValue *v) const
|
||||
|
||||
QStringList all;
|
||||
|
||||
if (JsonObjectValue *ov = getObjectValue(kProperties, v)) {
|
||||
if (JsonObjectValue *ov = getObjectValue(kProperties(), v)) {
|
||||
const MemberConstIterator cend = ov->members().constEnd();
|
||||
for (MemberConstIterator it = ov->members().constBegin(); it != cend; ++it)
|
||||
if (hasPropertySchema(it.key()))
|
||||
@@ -291,7 +291,7 @@ QStringList JsonSchema::properties() const
|
||||
JsonObjectValue *JsonSchema::propertySchema(const QString &property,
|
||||
JsonObjectValue *v) const
|
||||
{
|
||||
if (JsonObjectValue *ov = getObjectValue(kProperties, v)) {
|
||||
if (JsonObjectValue *ov = getObjectValue(kProperties(), v)) {
|
||||
JsonValue *member = ov->member(property);
|
||||
if (member && member->kind() == JsonValue::Object)
|
||||
return member->toObject();
|
||||
@@ -329,14 +329,14 @@ bool JsonSchema::hasItemSchema() const
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
|
||||
|
||||
return getObjectValue(kItems, currentValue());
|
||||
return getObjectValue(kItems(), currentValue());
|
||||
}
|
||||
|
||||
void JsonSchema::enterNestedItemSchema()
|
||||
{
|
||||
QTC_ASSERT(hasItemSchema(), return);
|
||||
|
||||
enter(getObjectValue(kItems, currentValue()));
|
||||
enter(getObjectValue(kItems(), currentValue()));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -350,14 +350,14 @@ bool JsonSchema::hasItemArraySchema() const
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
|
||||
|
||||
return getArrayValue(kItems, currentValue());
|
||||
return getArrayValue(kItems(), currentValue());
|
||||
}
|
||||
|
||||
int JsonSchema::itemArraySchemaSize() const
|
||||
{
|
||||
QTC_ASSERT(hasItemArraySchema(), return false);
|
||||
|
||||
return getArrayValue(kItems, currentValue())->size();
|
||||
return getArrayValue(kItems(), currentValue())->size();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -377,7 +377,7 @@ bool JsonSchema::maybeEnterNestedArraySchema(int index)
|
||||
QTC_ASSERT(itemArraySchemaSize(), return false);
|
||||
QTC_ASSERT(index >= 0 && index < itemArraySchemaSize(), return false);
|
||||
|
||||
JsonValue *v = getArrayValue(kItems, currentValue())->elements().at(index);
|
||||
JsonValue *v = getArrayValue(kItems(), currentValue())->elements().at(index);
|
||||
|
||||
return maybeEnter(v, Array, index);
|
||||
}
|
||||
@@ -391,12 +391,12 @@ bool JsonSchema::maybeEnterNestedArraySchema(int index)
|
||||
*/
|
||||
bool JsonSchema::hasUnionSchema() const
|
||||
{
|
||||
return getArrayValue(kType, currentValue());
|
||||
return getArrayValue(kType(), currentValue());
|
||||
}
|
||||
|
||||
int JsonSchema::unionSchemaSize() const
|
||||
{
|
||||
return getArrayValue(kType, currentValue())->size();
|
||||
return getArrayValue(kType(), currentValue())->size();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -416,7 +416,7 @@ bool JsonSchema::maybeEnterNestedUnionSchema(int index)
|
||||
QTC_ASSERT(unionSchemaSize(), return false);
|
||||
QTC_ASSERT(index >= 0 && index < unionSchemaSize(), return false);
|
||||
|
||||
JsonValue *v = getArrayValue(kType, currentValue())->elements().at(index);
|
||||
JsonValue *v = getArrayValue(kType(), currentValue())->elements().at(index);
|
||||
|
||||
return maybeEnter(v, Union, index);
|
||||
}
|
||||
@@ -430,7 +430,7 @@ void JsonSchema::leaveNestedSchema()
|
||||
|
||||
bool JsonSchema::required() const
|
||||
{
|
||||
if (JsonBooleanValue *bv = getBooleanValue(kRequired, currentValue()))
|
||||
if (JsonBooleanValue *bv = getBooleanValue(kRequired(), currentValue()))
|
||||
return bv->value();
|
||||
|
||||
return false;
|
||||
@@ -440,21 +440,21 @@ bool JsonSchema::hasMinimum() const
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
|
||||
|
||||
return getDoubleValue(kMinimum, currentValue());
|
||||
return getDoubleValue(kMinimum(), currentValue());
|
||||
}
|
||||
|
||||
double JsonSchema::minimum() const
|
||||
{
|
||||
QTC_ASSERT(hasMinimum(), return 0);
|
||||
|
||||
return getDoubleValue(kMinimum, currentValue())->value();
|
||||
return getDoubleValue(kMinimum(), currentValue())->value();
|
||||
}
|
||||
|
||||
bool JsonSchema::hasExclusiveMinimum()
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
|
||||
|
||||
if (JsonBooleanValue *bv = getBooleanValue(kExclusiveMinimum, currentValue()))
|
||||
if (JsonBooleanValue *bv = getBooleanValue(kExclusiveMinimum(), currentValue()))
|
||||
return bv->value();
|
||||
|
||||
return false;
|
||||
@@ -464,21 +464,21 @@ bool JsonSchema::hasMaximum() const
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
|
||||
|
||||
return getDoubleValue(kMaximum, currentValue());
|
||||
return getDoubleValue(kMaximum(), currentValue());
|
||||
}
|
||||
|
||||
double JsonSchema::maximum() const
|
||||
{
|
||||
QTC_ASSERT(hasMaximum(), return 0);
|
||||
|
||||
return getDoubleValue(kMaximum, currentValue())->value();
|
||||
return getDoubleValue(kMaximum(), currentValue())->value();
|
||||
}
|
||||
|
||||
bool JsonSchema::hasExclusiveMaximum()
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
|
||||
|
||||
if (JsonBooleanValue *bv = getBooleanValue(kExclusiveMaximum, currentValue()))
|
||||
if (JsonBooleanValue *bv = getBooleanValue(kExclusiveMaximum(), currentValue()))
|
||||
return bv->value();
|
||||
|
||||
return false;
|
||||
@@ -488,7 +488,7 @@ QString JsonSchema::pattern() const
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return QString());
|
||||
|
||||
if (JsonStringValue *sv = getStringValue(kPattern, currentValue()))
|
||||
if (JsonStringValue *sv = getStringValue(kPattern(), currentValue()))
|
||||
return sv->value();
|
||||
|
||||
return QString();
|
||||
@@ -498,7 +498,7 @@ int JsonSchema::minimumLength() const
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return -1);
|
||||
|
||||
if (JsonDoubleValue *dv = getDoubleValue(kMinLength, currentValue()))
|
||||
if (JsonDoubleValue *dv = getDoubleValue(kMinLength(), currentValue()))
|
||||
return dv->value();
|
||||
|
||||
return -1;
|
||||
@@ -508,7 +508,7 @@ int JsonSchema::maximumLength() const
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return -1);
|
||||
|
||||
if (JsonDoubleValue *dv = getDoubleValue(kMaxLength, currentValue()))
|
||||
if (JsonDoubleValue *dv = getDoubleValue(kMaxLength(), currentValue()))
|
||||
return dv->value();
|
||||
|
||||
return -1;
|
||||
@@ -518,7 +518,7 @@ bool JsonSchema::hasAdditionalItems() const
|
||||
{
|
||||
QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
|
||||
|
||||
return currentValue()->member(kAdditionalItems);
|
||||
return currentValue()->member(kAdditionalItems());
|
||||
}
|
||||
|
||||
bool JsonSchema::maybeSchemaName(const QString &s)
|
||||
@@ -600,7 +600,7 @@ void JsonSchema::leave()
|
||||
|
||||
JsonObjectValue *JsonSchema::resolveReference(JsonObjectValue *ov) const
|
||||
{
|
||||
if (JsonStringValue *sv = getStringValue(kRef, ov)) {
|
||||
if (JsonStringValue *sv = getStringValue(kRef(), ov)) {
|
||||
JsonSchema *referenced = m_manager->schemaByName(sv->value());
|
||||
if (referenced)
|
||||
return referenced->rootValue();
|
||||
@@ -611,7 +611,7 @@ JsonObjectValue *JsonSchema::resolveReference(JsonObjectValue *ov) const
|
||||
|
||||
JsonObjectValue *JsonSchema::resolveBase(JsonObjectValue *ov) const
|
||||
{
|
||||
if (JsonValue *v = ov->member(kExtends)) {
|
||||
if (JsonValue *v = ov->member(kExtends())) {
|
||||
if (v->kind() == JsonValue::String) {
|
||||
JsonSchema *schema = m_manager->schemaByName(v->toString()->value());
|
||||
if (schema)
|
||||
|
||||
@@ -355,28 +355,28 @@ private:
|
||||
|
||||
static bool maybeSchemaName(const QString &s);
|
||||
|
||||
static const QString kType;
|
||||
static const QString kProperties;
|
||||
static const QString kPatternProperties;
|
||||
static const QString kAdditionalProperties;
|
||||
static const QString kItems;
|
||||
static const QString kAdditionalItems;
|
||||
static const QString kRequired;
|
||||
static const QString kDependencies;
|
||||
static const QString kMinimum;
|
||||
static const QString kMaximum;
|
||||
static const QString kExclusiveMinimum;
|
||||
static const QString kExclusiveMaximum;
|
||||
static const QString kMinItems;
|
||||
static const QString kMaxItems;
|
||||
static const QString kUniqueItems;
|
||||
static const QString kPattern;
|
||||
static const QString kMinLength;
|
||||
static const QString kMaxLength;
|
||||
static const QString kTitle;
|
||||
static const QString kDescription;
|
||||
static const QString kExtends;
|
||||
static const QString kRef;
|
||||
static QString kType();
|
||||
static QString kProperties();
|
||||
static QString kPatternProperties();
|
||||
static QString kAdditionalProperties();
|
||||
static QString kItems();
|
||||
static QString kAdditionalItems();
|
||||
static QString kRequired();
|
||||
static QString kDependencies();
|
||||
static QString kMinimum();
|
||||
static QString kMaximum();
|
||||
static QString kExclusiveMinimum();
|
||||
static QString kExclusiveMaximum();
|
||||
static QString kMinItems();
|
||||
static QString kMaxItems();
|
||||
static QString kUniqueItems();
|
||||
static QString kPattern();
|
||||
static QString kMinLength();
|
||||
static QString kMaxLength();
|
||||
static QString kTitle();
|
||||
static QString kDescription();
|
||||
static QString kExtends();
|
||||
static QString kRef();
|
||||
|
||||
struct Context
|
||||
{
|
||||
|
||||
@@ -533,11 +533,6 @@ bool NewClassWidget::isValid(QString *error) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void NewClassWidget::triggerUpdateFileNames()
|
||||
{
|
||||
d->m_ui.classLineEdit->triggerChanged();
|
||||
}
|
||||
|
||||
void NewClassWidget::slotUpdateFileNames(const QString &baseName)
|
||||
{
|
||||
if (debugNewClassWidget)
|
||||
|
||||
@@ -155,10 +155,6 @@ public slots:
|
||||
*/
|
||||
void suggestClassNameFromBase();
|
||||
|
||||
public slots:
|
||||
/** Trigger an update (after changing settings) */
|
||||
void triggerUpdateFileNames();
|
||||
|
||||
private slots:
|
||||
void slotUpdateFileNames(const QString &t);
|
||||
void slotValidChanged();
|
||||
|
||||
@@ -336,6 +336,16 @@ void PathChooser::setFileName(const FileName &fn)
|
||||
d->m_lineEdit->setText(fn.toUserOutput());
|
||||
}
|
||||
|
||||
void PathChooser::setErrorColor(const QColor &errorColor)
|
||||
{
|
||||
d->m_lineEdit->setErrorColor(errorColor);
|
||||
}
|
||||
|
||||
void PathChooser::setOkColor(const QColor &okColor)
|
||||
{
|
||||
d->m_lineEdit->setOkColor(okColor);
|
||||
}
|
||||
|
||||
bool PathChooser::isReadOnly() const
|
||||
{
|
||||
return d->m_lineEdit->isReadOnly();
|
||||
@@ -453,7 +463,7 @@ QString PathChooser::errorMessage() const
|
||||
|
||||
void PathChooser::triggerChanged()
|
||||
{
|
||||
d->m_lineEdit->triggerChanged();
|
||||
d->m_lineEdit->validate();
|
||||
}
|
||||
|
||||
void PathChooser::setAboutToShowContextMenuHandler(PathChooser::AboutToShowContextMenuHandler handler)
|
||||
@@ -461,6 +471,16 @@ void PathChooser::setAboutToShowContextMenuHandler(PathChooser::AboutToShowConte
|
||||
s_aboutToShowContextMenuHandler = handler;
|
||||
}
|
||||
|
||||
QColor PathChooser::errorColor() const
|
||||
{
|
||||
return d->m_lineEdit->errorColor();
|
||||
}
|
||||
|
||||
QColor PathChooser::okColor() const
|
||||
{
|
||||
return d->m_lineEdit->okColor();
|
||||
}
|
||||
|
||||
FancyLineEdit::ValidationFunction PathChooser::defaultValidationFunction() const
|
||||
{
|
||||
return std::bind(&PathChooser::validatePath, this, std::placeholders::_1, std::placeholders::_2);
|
||||
@@ -616,7 +636,7 @@ void PathChooser::setExpectedKind(Kind expected)
|
||||
if (d->m_acceptingKind == expected)
|
||||
return;
|
||||
d->m_acceptingKind = expected;
|
||||
d->m_lineEdit->triggerChanged();
|
||||
d->m_lineEdit->validate();
|
||||
}
|
||||
|
||||
PathChooser::Kind PathChooser::expectedKind() const
|
||||
|
||||
@@ -62,6 +62,8 @@ class QTCREATOR_UTILS_EXPORT PathChooser : public QWidget
|
||||
// Designer does not know this type, so force designable to false:
|
||||
Q_PROPERTY(Utils::FileName fileName READ fileName WRITE setFileName DESIGNABLE false)
|
||||
Q_PROPERTY(Utils::FileName baseFileName READ baseFileName WRITE setBaseFileName DESIGNABLE false)
|
||||
Q_PROPERTY(QColor errorColor READ errorColor WRITE setErrorColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor okColor READ okColor WRITE setOkColor DESIGNABLE true)
|
||||
|
||||
public:
|
||||
static QString browseButtonLabel();
|
||||
@@ -145,6 +147,9 @@ public:
|
||||
using AboutToShowContextMenuHandler = std::function<void (Utils::PathChooser *, QMenu *)>;
|
||||
static void setAboutToShowContextMenuHandler(AboutToShowContextMenuHandler handler);
|
||||
|
||||
QColor errorColor() const;
|
||||
QColor okColor() const;
|
||||
|
||||
private:
|
||||
bool validatePath(FancyLineEdit *edit, QString *errorMessage) const;
|
||||
// Returns overridden title or the one from <title>
|
||||
@@ -165,6 +170,9 @@ public slots:
|
||||
void setPath(const QString &);
|
||||
void setFileName(const Utils::FileName &);
|
||||
|
||||
void setErrorColor(const QColor &errorColor);
|
||||
void setOkColor(const QColor &okColor);
|
||||
|
||||
private:
|
||||
PathChooserPrivate *d;
|
||||
static AboutToShowContextMenuHandler s_aboutToShowContextMenuHandler;
|
||||
|
||||
@@ -28,25 +28,17 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "customwizardpreprocessor.h"
|
||||
#ifdef WITH_TESTS
|
||||
# include "../projectexplorer.h"
|
||||
# include <QTest>
|
||||
#endif
|
||||
#include "templateengine.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include "qtcassert.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QStack>
|
||||
#include <QRegExp>
|
||||
#include <QDebug>
|
||||
#include <QJSEngine>
|
||||
#include <QStack>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
namespace ProjectExplorer {
|
||||
namespace Internal {
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
// Preprocessor: Conditional section type.
|
||||
enum PreprocessorSection {
|
||||
IfSection,
|
||||
@@ -58,7 +50,8 @@ enum PreprocessorSection {
|
||||
|
||||
// Preprocessor: Section stack entry containing nested '@if' section
|
||||
// state.
|
||||
struct PreprocessStackEntry {
|
||||
class PreprocessStackEntry {
|
||||
public:
|
||||
PreprocessStackEntry(PreprocessorSection section = OtherSection,
|
||||
bool parentEnabled = true,
|
||||
bool condition = false,
|
||||
@@ -70,11 +63,9 @@ struct PreprocessStackEntry {
|
||||
bool anyIfClauseMatched; // Determines if 'else' triggers
|
||||
};
|
||||
|
||||
PreprocessStackEntry::PreprocessStackEntry(PreprocessorSection s,
|
||||
bool p, bool c, bool a) :
|
||||
PreprocessStackEntry::PreprocessStackEntry(PreprocessorSection s, bool p, bool c, bool a) :
|
||||
section(s), parentEnabled(p), condition(c), anyIfClauseMatched(a)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
// Context for preprocessing.
|
||||
class PreprocessContext {
|
||||
@@ -102,13 +93,14 @@ PreprocessContext::PreprocessContext() :
|
||||
m_elsePattern(QLatin1String("^[\\s]*@[\\s]*else.*$")),
|
||||
m_endifPattern(QLatin1String("^[\\s]*@[\\s]*endif.*$"))
|
||||
{
|
||||
QTC_ASSERT(m_ifPattern.isValid() && m_elsifPattern.isValid()
|
||||
&& m_elsePattern.isValid() &&m_endifPattern.isValid(), return);
|
||||
QTC_CHECK(m_ifPattern.isValid() && m_elsifPattern.isValid()
|
||||
&& m_elsePattern.isValid() && m_endifPattern.isValid());
|
||||
}
|
||||
|
||||
void PreprocessContext::reset()
|
||||
{
|
||||
m_sectionStack.clear(); // Add a default, enabled section.
|
||||
m_sectionStack.clear();
|
||||
// Add a default, enabled section.
|
||||
m_sectionStack.push(PreprocessStackEntry(OtherSection, true, true));
|
||||
}
|
||||
|
||||
@@ -135,35 +127,6 @@ PreprocessorSection PreprocessContext::preprocessorLine(const QString &in,
|
||||
return OtherSection;
|
||||
}
|
||||
|
||||
// Evaluate an expression within an 'if'/'elsif' to a bool via QJSEngine
|
||||
bool evaluateBooleanJavaScriptExpression(QJSEngine &engine, const QString &expression, bool *result, QString *errorMessage)
|
||||
{
|
||||
errorMessage->clear();
|
||||
*result = false;
|
||||
const QJSValue value = engine.evaluate(expression);
|
||||
if (value.isError()) {
|
||||
*errorMessage = QString::fromLatin1("Error in \"%1\": %2").
|
||||
arg(expression, value.toString());
|
||||
return false;
|
||||
}
|
||||
// Try to convert to bool, be that an int or whatever.
|
||||
if (value.isBool()) {
|
||||
*result = value.toBool();
|
||||
return true;
|
||||
}
|
||||
if (value.isNumber()) {
|
||||
*result = !qFuzzyCompare(value.toNumber(), 0);
|
||||
return true;
|
||||
}
|
||||
if (value.isString()) {
|
||||
*result = !value.toString().isEmpty();
|
||||
return true;
|
||||
}
|
||||
*errorMessage = QString::fromLatin1("Cannot convert result of \"%1\" (\"%2\"to bool.").
|
||||
arg(expression, value.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline QString msgEmptyStack(int line)
|
||||
{
|
||||
return QString::fromLatin1("Unmatched '@endif' at line %1.").arg(line);
|
||||
@@ -184,6 +147,7 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM
|
||||
for (int l = 0; l < lineCount; l++) {
|
||||
// Check for element of the stack (be it dummy, else something is wrong).
|
||||
if (m_sectionStack.isEmpty()) {
|
||||
if (errorMessage)
|
||||
*errorMessage = msgEmptyStack(l);
|
||||
return false;
|
||||
}
|
||||
@@ -195,32 +159,33 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM
|
||||
case IfSection:
|
||||
// '@If': Push new section
|
||||
if (top.condition) {
|
||||
if (!evaluateBooleanJavaScriptExpression(m_scriptEngine, expression, &expressionValue, errorMessage)) {
|
||||
*errorMessage = QString::fromLatin1("Error in @if at %1: %2").
|
||||
arg(l + 1).arg(*errorMessage);
|
||||
if (!TemplateEngine::evaluateBooleanJavaScriptExpression(m_scriptEngine, expression,
|
||||
&expressionValue, errorMessage)) {
|
||||
if (errorMessage)
|
||||
*errorMessage = QString::fromLatin1("Error in @if at %1: %2")
|
||||
.arg(l + 1).arg(*errorMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (debug)
|
||||
qDebug("'%s' : expr='%s' -> %d", qPrintable(lines.at(l)), qPrintable(expression), expressionValue);
|
||||
m_sectionStack.push(PreprocessStackEntry(IfSection,
|
||||
top.condition, expressionValue, expressionValue));
|
||||
break;
|
||||
case ElsifSection: // '@elsif': Check condition.
|
||||
if (top.section != IfSection && top.section != ElsifSection) {
|
||||
*errorMessage = QString::fromLatin1("No preceding @if found for @elsif at %1").
|
||||
arg(l + 1);
|
||||
if (errorMessage)
|
||||
*errorMessage = QString::fromLatin1("No preceding @if found for @elsif at %1")
|
||||
.arg(l + 1);
|
||||
return false;
|
||||
}
|
||||
if (top.parentEnabled) {
|
||||
if (!evaluateBooleanJavaScriptExpression(m_scriptEngine, expression, &expressionValue, errorMessage)) {
|
||||
*errorMessage = QString::fromLatin1("Error in @elsif at %1: %2").
|
||||
arg(l + 1).arg(*errorMessage);
|
||||
if (!TemplateEngine::evaluateBooleanJavaScriptExpression(m_scriptEngine, expression,
|
||||
&expressionValue, errorMessage)) {
|
||||
if (errorMessage)
|
||||
*errorMessage = QString::fromLatin1("Error in @elsif at %1: %2")
|
||||
.arg(l + 1).arg(*errorMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (debug)
|
||||
qDebug("'%s' : expr='%s' -> %d", qPrintable(lines.at(l)), qPrintable(expression), expressionValue);
|
||||
top.section = ElsifSection;
|
||||
// ignore consecutive '@elsifs' once something matched
|
||||
if (top.anyIfClauseMatched) {
|
||||
@@ -232,13 +197,12 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM
|
||||
break;
|
||||
case ElseSection: // '@else': Check condition.
|
||||
if (top.section != IfSection && top.section != ElsifSection) {
|
||||
*errorMessage = QString::fromLatin1("No preceding @if/@elsif found for @else at %1").
|
||||
arg(l + 1);
|
||||
if (errorMessage)
|
||||
*errorMessage = QString::fromLatin1("No preceding @if/@elsif found for @else at %1")
|
||||
.arg(l + 1);
|
||||
return false;
|
||||
}
|
||||
expressionValue = top.parentEnabled && !top.anyIfClauseMatched;
|
||||
if (debug)
|
||||
qDebug("%s -> %d", qPrintable(lines.at(l)), expressionValue);
|
||||
top.section = ElseSection;
|
||||
top.condition = expressionValue;
|
||||
break;
|
||||
@@ -247,8 +211,9 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM
|
||||
break;
|
||||
case OtherSection: // Rest: Append according to current condition.
|
||||
if (top.condition) {
|
||||
out->append(lines.at(l));
|
||||
if (l != 0)
|
||||
out->append(newLine);
|
||||
out->append(lines.at(l));
|
||||
}
|
||||
break;
|
||||
} // switch section
|
||||
@@ -257,97 +222,96 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Implements a custom wizard preprocessor based on JavaScript expressions.
|
||||
} // namespace Internal
|
||||
|
||||
Preprocesses a string using a simple syntax:
|
||||
\code
|
||||
Text
|
||||
@if <JavaScript-expression>
|
||||
Bla...
|
||||
@elsif <JavaScript-expression2>
|
||||
Blup
|
||||
@endif
|
||||
\endcode
|
||||
|
||||
The JavaScript-expressions must evaluate to integers or boolean, like
|
||||
\c '2 == 1 + 1', \c '"a" == "a"'. The variables of the custom wizard will be
|
||||
expanded before, so \c "%VAR%" should be used for strings and \c %VAR% for integers.
|
||||
|
||||
\sa ProjectExplorer::CustomWizard
|
||||
*/
|
||||
|
||||
bool customWizardPreprocess(const QString &in, QString *out, QString *errorMessage)
|
||||
bool TemplateEngine::preprocessText(const QString &in, QString *out, QString *errorMessage)
|
||||
{
|
||||
PreprocessContext context;
|
||||
Internal::PreprocessContext context;
|
||||
return context.process(in, out, errorMessage);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
#ifdef WITH_TESTS // Run qtcreator -test ProjectExplorer
|
||||
|
||||
void ProjectExplorerPlugin::testCustomWizardPreprocessor_data()
|
||||
QString TemplateEngine::processText(MacroExpander *expander, const QString &input,
|
||||
QString *errorMessage)
|
||||
{
|
||||
QTest::addColumn<QString>("input");
|
||||
QTest::addColumn<QString>("expectedOutput");
|
||||
QTest::addColumn<bool>("expectedSuccess");
|
||||
QTest::addColumn<QString>("expectedErrorMessage");
|
||||
QTest::newRow("if")
|
||||
<< QString::fromLatin1("@if 1\nline 1\n@elsif 0\nline 2\n@else\nline 3\n@endif\n")
|
||||
<< QString::fromLatin1("line 1")
|
||||
<< true << QString();
|
||||
QTest::newRow("elsif")
|
||||
<< QString::fromLatin1("@if 0\nline 1\n@elsif 1\nline 2\n@else\nline 3\n@endif\n")
|
||||
<< QString::fromLatin1("line 2")
|
||||
<< true << QString();
|
||||
QTest::newRow("else")
|
||||
<< QString::fromLatin1("@if 0\nline 1\n@elsif 0\nline 2\n@else\nline 3\n@endif\n")
|
||||
<< QString::fromLatin1("line 3")
|
||||
<< true << QString();
|
||||
QTest::newRow("nested-if")
|
||||
<< QString::fromLatin1("@if 1\n"
|
||||
" @if 1\nline 1\n@elsif 0\nline 2\n@else\nline 3\n@endif\n"
|
||||
"@else\n"
|
||||
" @if 1\nline 4\n@elsif 0\nline 5\n@else\nline 6\n@endif\n"
|
||||
"@endif\n")
|
||||
<< QString::fromLatin1("line 1")
|
||||
<< true << QString();
|
||||
QTest::newRow("nested-else")
|
||||
<< QString::fromLatin1("@if 0\n"
|
||||
" @if 1\nline 1\n@elsif 0\nline 2\n@else\nline 3\n@endif\n"
|
||||
"@else\n"
|
||||
" @if 1\nline 4\n@elsif 0\nline 5\n@else\nline 6\n@endif\n"
|
||||
"@endif\n")
|
||||
<< QString::fromLatin1("line 4")
|
||||
<< true << QString();
|
||||
QTest::newRow("twice-nested-if")
|
||||
<< QString::fromLatin1("@if 0\n"
|
||||
" @if 1\n"
|
||||
" @if 1\nline 1\n@else\nline 2\n@endif\n"
|
||||
" @endif\n"
|
||||
"@else\n"
|
||||
" @if 1\n"
|
||||
" @if 1\nline 3\n@else\nline 4\n@endif\n"
|
||||
" @endif\n"
|
||||
"@endif\n")
|
||||
<< QString::fromLatin1("line 3")
|
||||
<< true << QString();
|
||||
if (errorMessage)
|
||||
errorMessage->clear();
|
||||
|
||||
if (input.isEmpty())
|
||||
return input;
|
||||
|
||||
// Recursively expand macros:
|
||||
QString in = input;
|
||||
QString oldIn;
|
||||
for (int i = 0; i < 5 && in != oldIn; ++i) {
|
||||
oldIn = in;
|
||||
in = expander->expand(oldIn);
|
||||
}
|
||||
|
||||
void ProjectExplorerPlugin::testCustomWizardPreprocessor()
|
||||
{
|
||||
QFETCH(QString, input);
|
||||
QFETCH(QString, expectedOutput);
|
||||
QFETCH(bool, expectedSuccess);
|
||||
QFETCH(QString, expectedErrorMessage);
|
||||
QString out;
|
||||
if (!preprocessText(in, &out, errorMessage))
|
||||
return QString();
|
||||
|
||||
QString errorMessage;
|
||||
QString output;
|
||||
const bool success = Internal::customWizardPreprocess(input, &output, &errorMessage);
|
||||
QCOMPARE(success, expectedSuccess);
|
||||
QCOMPARE(output.trimmed(), expectedOutput.trimmed());
|
||||
QCOMPARE(errorMessage, expectedErrorMessage);
|
||||
// Expand \n, \t and handle line continuation:
|
||||
QString result;
|
||||
result.reserve(out.count());
|
||||
bool isEscaped = false;
|
||||
for (int i = 0; i < out.count(); ++i) {
|
||||
const QChar c = out.at(i);
|
||||
|
||||
if (isEscaped) {
|
||||
if (c == QLatin1Char('n'))
|
||||
result.append(QLatin1Char('\n'));
|
||||
else if (c == QLatin1Char('t'))
|
||||
result.append(QLatin1Char('\t'));
|
||||
else if (c != QLatin1Char('\n'))
|
||||
result.append(c);
|
||||
isEscaped = false;
|
||||
} else {
|
||||
if (c == QLatin1Char('\\'))
|
||||
isEscaped = true;
|
||||
else
|
||||
result.append(c);
|
||||
}
|
||||
#endif // WITH_TESTS
|
||||
} // namespace ProjectExplorer
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TemplateEngine::evaluateBooleanJavaScriptExpression(QJSEngine &engine,
|
||||
const QString &expression, bool *result,
|
||||
QString *errorMessage)
|
||||
{
|
||||
if (errorMessage)
|
||||
errorMessage->clear();
|
||||
if (result)
|
||||
*result = false;
|
||||
const QJSValue value = engine.evaluate(expression);
|
||||
if (value.isError()) {
|
||||
if (errorMessage)
|
||||
*errorMessage = QString::fromLatin1("Error in \"%1\": %2")
|
||||
.arg(expression, value.toString());
|
||||
return false;
|
||||
}
|
||||
// Try to convert to bool, be that an int or whatever.
|
||||
if (value.isBool()) {
|
||||
if (result)
|
||||
*result = value.toBool();
|
||||
return true;
|
||||
}
|
||||
if (value.isNumber()) {
|
||||
if (result)
|
||||
*result = !qFuzzyCompare(value.toNumber(), 0);
|
||||
return true;
|
||||
}
|
||||
if (value.isString()) {
|
||||
if (result)
|
||||
*result = !value.toString().isEmpty();
|
||||
return true;
|
||||
}
|
||||
if (errorMessage)
|
||||
*errorMessage = QString::fromLatin1("Cannot convert result of \"%1\" (\"%2\"to bool.")
|
||||
.arg(expression, value.toString());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
@@ -28,20 +28,30 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CUSTOMWIZARDPREPROCESSOR_H
|
||||
#define CUSTOMWIZARDPREPROCESSOR_H
|
||||
#ifndef TEMPLATEENGINE_H
|
||||
#define TEMPLATEENGINE_H
|
||||
|
||||
#include "utils_global.h"
|
||||
|
||||
#include "macroexpander.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QJSEngine)
|
||||
QT_FORWARD_DECLARE_CLASS(QJSEngine);
|
||||
|
||||
namespace ProjectExplorer {
|
||||
namespace Internal {
|
||||
namespace Utils {
|
||||
|
||||
bool customWizardPreprocess(const QString &in, QString *out, QString *errorMessage);
|
||||
/* Helper to evaluate an expression. */
|
||||
bool evaluateBooleanJavaScriptExpression(QJSEngine &engine, const QString &expression, bool *result, QString *errorMessage);
|
||||
} // namespace Internal
|
||||
} // namespace ProjectExplorer
|
||||
class QTCREATOR_UTILS_EXPORT TemplateEngine {
|
||||
public:
|
||||
static bool preprocessText(const QString &input, QString *output, QString *errorMessage);
|
||||
|
||||
#endif // CUSTOMWIZARDPREPROCESSOR_H
|
||||
static QString processText(MacroExpander *expander, const QString &input,
|
||||
QString *errorMessage);
|
||||
|
||||
static bool evaluateBooleanJavaScriptExpression(QJSEngine &engine, const QString &expression,
|
||||
bool *result, QString *errorMessage);
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
#endif // TEMPLATEENGINE_H
|
||||
@@ -4,7 +4,7 @@ dll {
|
||||
DEFINES += QTCREATOR_UTILS_STATIC_LIB
|
||||
}
|
||||
|
||||
QT += network
|
||||
QT += gui network qml
|
||||
|
||||
CONFIG += exceptions # used by portlist.cpp, textfileformat.cpp, and ssh/*
|
||||
|
||||
@@ -16,6 +16,7 @@ SOURCES += $$PWD/environment.cpp \
|
||||
$$PWD/shellcommandpage.cpp \
|
||||
$$PWD/settingsselector.cpp \
|
||||
$$PWD/stringutils.cpp \
|
||||
$$PWD/templateengine.cpp \
|
||||
$$PWD/textfieldcheckbox.cpp \
|
||||
$$PWD/textfieldcombobox.cpp \
|
||||
$$PWD/filesearch.cpp \
|
||||
@@ -108,6 +109,7 @@ HEADERS += \
|
||||
$$PWD/shellcommand.h \
|
||||
$$PWD/shellcommandpage.h \
|
||||
$$PWD/stringutils.h \
|
||||
$$PWD/templateengine.h \
|
||||
$$PWD/textfieldcheckbox.h \
|
||||
$$PWD/textfieldcombobox.h \
|
||||
$$PWD/filesearch.h \
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
QT += gui network
|
||||
|
||||
include(../../qtcreatorlibrary.pri)
|
||||
include(utils-lib.pri)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ QtcLibrary {
|
||||
cpp.frameworks: ["Foundation"]
|
||||
}
|
||||
|
||||
Depends { name: "Qt"; submodules: ["widgets", "network", "script", "concurrent"] }
|
||||
Depends { name: "Qt"; submodules: ["concurrent", "network", "qml", "widgets"] }
|
||||
Depends { name: "app_version_header" }
|
||||
|
||||
files: [
|
||||
@@ -189,6 +189,8 @@ QtcLibrary {
|
||||
"synchronousprocess.h",
|
||||
"tcpportsgatherer.cpp",
|
||||
"tcpportsgatherer.h",
|
||||
"templateengine.cpp",
|
||||
"templateengine.h",
|
||||
"textfieldcheckbox.cpp",
|
||||
"textfieldcheckbox.h",
|
||||
"textfieldcombobox.cpp",
|
||||
|
||||
@@ -70,15 +70,15 @@ bool AnalyzerAction::isRunnable(QString *reason) const
|
||||
return ProjectExplorerPlugin::canRun(SessionManager::startupProject(), m_runMode, reason);
|
||||
}
|
||||
|
||||
static bool buildTypeAccepted(ToolMode toolMode, BuildConfiguration::BuildType buildType)
|
||||
static bool buildTypeAccepted(QFlags<ToolMode> toolMode, BuildConfiguration::BuildType buildType)
|
||||
{
|
||||
if (toolMode == AnyMode)
|
||||
return true;
|
||||
if (buildType == BuildConfiguration::Unknown)
|
||||
return true;
|
||||
if (buildType == BuildConfiguration::Debug && toolMode == DebugMode)
|
||||
if (buildType == BuildConfiguration::Debug && (toolMode & DebugMode))
|
||||
return true;
|
||||
if (buildType == BuildConfiguration::Release && toolMode == ReleaseMode)
|
||||
if (buildType == BuildConfiguration::Release && (toolMode & ReleaseMode))
|
||||
return true;
|
||||
if (buildType == BuildConfiguration::Profile && (toolMode & ProfileMode))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -114,30 +114,53 @@ void AnalyzerAction::startTool()
|
||||
// Check the project for whether the build config is in the correct mode
|
||||
// if not, notify the user and urge him to use the correct mode.
|
||||
if (!buildTypeAccepted(m_toolMode, buildType)) {
|
||||
const QString currentMode = buildType == BuildConfiguration::Debug
|
||||
? AnalyzerManager::tr("Debug")
|
||||
: AnalyzerManager::tr("Release");
|
||||
|
||||
QString toolModeString;
|
||||
switch (m_toolMode) {
|
||||
case DebugMode:
|
||||
toolModeString = AnalyzerManager::tr("Debug");
|
||||
QString currentMode;
|
||||
switch (buildType) {
|
||||
case BuildConfiguration::Debug:
|
||||
currentMode = AnalyzerManager::tr("Debug");
|
||||
break;
|
||||
case ReleaseMode:
|
||||
toolModeString = AnalyzerManager::tr("Release");
|
||||
case BuildConfiguration::Profile:
|
||||
currentMode = AnalyzerManager::tr("Profile");
|
||||
break;
|
||||
case BuildConfiguration::Release:
|
||||
currentMode = AnalyzerManager::tr("Release");
|
||||
break;
|
||||
default:
|
||||
QTC_CHECK(false);
|
||||
}
|
||||
//const QString toolName = displayName();
|
||||
const QString toolName = AnalyzerManager::tr("Tool"); // FIXME
|
||||
|
||||
QString toolModeString;
|
||||
switch (m_toolMode) {
|
||||
case DebugMode:
|
||||
toolModeString = AnalyzerManager::tr("in Debug mode");
|
||||
break;
|
||||
case ProfileMode:
|
||||
toolModeString = AnalyzerManager::tr("in Profile mode");
|
||||
break;
|
||||
case ReleaseMode:
|
||||
toolModeString = AnalyzerManager::tr("in Release mode");
|
||||
break;
|
||||
case SymbolsMode:
|
||||
toolModeString = AnalyzerManager::tr("with debug symbols (Debug or Profile mode)");
|
||||
break;
|
||||
case OptimizedMode:
|
||||
toolModeString = AnalyzerManager::tr("on optimized code (Profile or Release mode)");
|
||||
break;
|
||||
default:
|
||||
QTC_CHECK(false);
|
||||
}
|
||||
const QString toolName = text(); // The action text is always the name of the tool
|
||||
const QString title = AnalyzerManager::tr("Run %1 in %2 Mode?").arg(toolName).arg(currentMode);
|
||||
const QString message = AnalyzerManager::tr("<html><head/><body><p>You are trying "
|
||||
"to run the tool \"%1\" on an application in %2 mode. "
|
||||
"The tool is designed to be used in %3 mode.</p><p>"
|
||||
"Debug and Release mode run-time characteristics differ "
|
||||
"significantly, analytical findings for one mode may or "
|
||||
"may not be relevant for the other.</p><p>"
|
||||
"The tool is designed to be used %3.</p><p>"
|
||||
"Run-time characteristics differ significantly between "
|
||||
"optimized and non-optimized binaries. Analytical "
|
||||
"findings for one mode may or may not be relevant for "
|
||||
"the other.</p><p>"
|
||||
"Running tools that need debug symbols on binaries that "
|
||||
"don't provide any may lead to missing function names "
|
||||
"or otherwise insufficient output.</p><p>"
|
||||
"Do you want to continue and run the tool in %2 mode?</p></body></html>")
|
||||
.arg(toolName).arg(currentMode).arg(toolModeString);
|
||||
if (Utils::CheckableMessageBox::doNotAskAgainQuestion(ICore::mainWindow(),
|
||||
|
||||
@@ -53,15 +53,20 @@ class AnalyzerRunControl;
|
||||
/**
|
||||
* The mode in which this tool should preferably be run
|
||||
*
|
||||
* The memcheck tool, for example, requires debug symbols, hence DebugMode
|
||||
* is preferred. On the other hand, callgrind should look at optimized code,
|
||||
* hence ReleaseMode.
|
||||
* Debugging tools which try to show stack traces as close as possible to what the source code
|
||||
* looks like will prefer SymbolsMode. Profiling tools which need optimized code for realistic
|
||||
* performance, but still want to show analytical output that depends on debug symbols, will prefer
|
||||
* ProfileMode.
|
||||
*/
|
||||
enum ToolMode {
|
||||
DebugMode,
|
||||
ReleaseMode,
|
||||
AnyMode
|
||||
DebugMode = 0x1,
|
||||
ProfileMode = 0x2,
|
||||
ReleaseMode = 0x4,
|
||||
SymbolsMode = DebugMode | ProfileMode,
|
||||
OptimizedMode = ProfileMode | ReleaseMode,
|
||||
AnyMode = DebugMode | ProfileMode | ReleaseMode
|
||||
};
|
||||
Q_DECLARE_FLAGS(ToolModes, ToolMode)
|
||||
|
||||
/**
|
||||
* This class represents an analyzation action, i.e. a tool that runs in a specific mode.
|
||||
@@ -84,7 +89,7 @@ public:
|
||||
|
||||
Core::Id toolId() const { return m_toolId; }
|
||||
void setToolId(Core::Id id) { m_toolId = id; }
|
||||
void setToolMode(ToolMode mode) { m_toolMode = mode; }
|
||||
void setToolMode(QFlags<ToolMode> mode) { m_toolMode = mode; }
|
||||
|
||||
Core::Id runMode() const { return m_runMode; }
|
||||
void setRunMode(Core::Id mode) { m_runMode = mode; }
|
||||
@@ -118,7 +123,7 @@ protected:
|
||||
Core::Id m_menuGroup;
|
||||
Core::Id m_actionId;
|
||||
Core::Id m_toolId;
|
||||
ToolMode m_toolMode;
|
||||
QFlags<ToolMode> m_toolMode;
|
||||
Core::Id m_runMode;
|
||||
WidgetCreator m_widgetCreator;
|
||||
RunControlCreator m_runControlCreator;
|
||||
|
||||
@@ -114,8 +114,9 @@ bool AndroidBuildApkStep::init()
|
||||
}
|
||||
|
||||
|
||||
if (bc->buildType() == ProjectExplorer::BuildConfiguration::Debug)
|
||||
emit addOutput(tr("Warning: Signing a debug package."), BuildStep::ErrorMessageOutput);
|
||||
if (bc->buildType() != ProjectExplorer::BuildConfiguration::Release)
|
||||
emit addOutput(tr("Warning: Signing a debug or profile package."),
|
||||
BuildStep::ErrorMessageOutput);
|
||||
}
|
||||
|
||||
QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
|
||||
|
||||
@@ -243,8 +243,9 @@ void AndroidBuildApkWidget::verboseOutputCheckBoxToggled(bool checked)
|
||||
|
||||
void AndroidBuildApkWidget::updateSigningWarning()
|
||||
{
|
||||
bool debug = m_step->buildConfiguration()->buildType() == ProjectExplorer::BuildConfiguration::Debug;
|
||||
if (m_step->signPackage() && debug) {
|
||||
bool nonRelease = m_step->buildConfiguration()->buildType()
|
||||
!= ProjectExplorer::BuildConfiguration::Release;
|
||||
if (m_step->signPackage() && nonRelease) {
|
||||
m_ui->signingDebugWarningIcon->setVisible(true);
|
||||
m_ui->signingDebugWarningLabel->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -258,8 +258,9 @@ AndroidToolChainFactory::AndroidToolChainFactory()
|
||||
setDisplayName(tr("Android GCC"));
|
||||
}
|
||||
|
||||
QList<ToolChain *> AndroidToolChainFactory::autoDetect()
|
||||
QList<ToolChain *> AndroidToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
||||
{
|
||||
Q_UNUSED(alreadyKnown);
|
||||
return createToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation());
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ class AndroidToolChainFactory : public ProjectExplorer::ToolChainFactory
|
||||
public:
|
||||
AndroidToolChainFactory();
|
||||
|
||||
QList<ProjectExplorer::ToolChain *> autoDetect() override;
|
||||
QList<ProjectExplorer::ToolChain *> autoDetect(const QList<ProjectExplorer::ToolChain *> &alreadyKnown) override;
|
||||
bool canRestore(const QVariantMap &data) override;
|
||||
ProjectExplorer::ToolChain *restore(const QVariantMap &data) override;
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <clangbackendipc/projectpartsdonotexistmessage.h>
|
||||
#include <clangbackendipc/translationunitdoesnotexistmessage.h>
|
||||
#include <clangbackendipc/unregisterunsavedfilesforeditormessage.h>
|
||||
#include <clangbackendipc/updatetranslationunitsforeditormessage.h>
|
||||
|
||||
#include <cplusplus/Icons.h>
|
||||
|
||||
@@ -194,6 +195,7 @@ public:
|
||||
|
||||
void end() override;
|
||||
void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override;
|
||||
void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override;
|
||||
void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override;
|
||||
void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override;
|
||||
void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override;
|
||||
@@ -218,6 +220,12 @@ void IpcSender::registerTranslationUnitsForEditor(const RegisterTranslationUnitF
|
||||
m_connection.serverProxy().registerTranslationUnitsForEditor(message);
|
||||
}
|
||||
|
||||
void IpcSender::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
QTC_CHECK(m_connection.isConnected());
|
||||
m_connection.serverProxy().updateTranslationUnitsForEditor(message);
|
||||
}
|
||||
|
||||
void IpcSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
QTC_CHECK(m_connection.isConnected());
|
||||
@@ -368,6 +376,16 @@ void IpcCommunicator::registerProjectsParts(const QList<CppTools::ProjectPart::P
|
||||
registerProjectPartsForEditor(projectPartContainers);
|
||||
}
|
||||
|
||||
void IpcCommunicator::registerTranslationUnit(TextEditor::TextDocument *document)
|
||||
{
|
||||
const QString filePath = document->filePath().toString();
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
|
||||
registerTranslationUnitsForEditor({{Utf8String(filePath),
|
||||
Utf8String(projectPartId),
|
||||
uint(document->document()->revision())}});
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath)
|
||||
{
|
||||
const auto document = CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
|
||||
@@ -388,34 +406,33 @@ CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
|
||||
return CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
|
||||
}
|
||||
|
||||
bool documentHasChanged(const QString &filePath, const QString &projectPartId)
|
||||
bool documentHasChanged(const QString &filePath)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document)
|
||||
return document->sendTracker(projectPartId).shouldSendRevision(document->revision());
|
||||
return document->sendTracker().shouldSendRevision(document->revision());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setLastSentDocumentRevision(const QString &filePath,
|
||||
const QString &projectPartId,
|
||||
uint revision)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document)
|
||||
document->sendTracker(projectPartId).setLastSentRevision(int(revision));
|
||||
document->sendTracker().setLastSentRevision(int(revision));
|
||||
}
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnit(const QString &filePath,
|
||||
void IpcCommunicator::registerTranslationUnit(const QString &filePath,
|
||||
const QByteArray &contents,
|
||||
uint documentRevision)
|
||||
{
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
|
||||
if (documentHasChanged(filePath, projectPartId)) {
|
||||
if (documentHasChanged(filePath)) {
|
||||
const bool hasUnsavedContent = true;
|
||||
|
||||
registerTranslationUnitsForEditor({{filePath,
|
||||
@@ -424,18 +441,30 @@ void IpcCommunicator::updateTranslationUnit(const QString &filePath,
|
||||
hasUnsavedContent,
|
||||
documentRevision}});
|
||||
|
||||
setLastSentDocumentRevision(filePath, projectPartId, documentRevision);
|
||||
setLastSentDocumentRevision(filePath, documentRevision);
|
||||
}
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnit(const QString &filePath,
|
||||
const QByteArray &contents,
|
||||
uint documentRevision)
|
||||
{
|
||||
const bool hasUnsavedContent = true;
|
||||
|
||||
updateTranslationUnitsForEditor({{filePath,
|
||||
Utf8String(),
|
||||
Utf8String::fromByteArray(contents),
|
||||
hasUnsavedContent,
|
||||
documentRevision}});
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision)
|
||||
{
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
const bool hasUnsavedContent = true;
|
||||
|
||||
// TODO: Send new only if changed
|
||||
registerUnsavedFilesForEditor({{filePath,
|
||||
projectPartId,
|
||||
Utf8String(),
|
||||
Utf8String::fromByteArray(contents),
|
||||
hasUnsavedContent,
|
||||
documentRevision}});
|
||||
@@ -446,27 +475,35 @@ void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer)
|
||||
if (m_sendMode == IgnoreSendRequests)
|
||||
return;
|
||||
|
||||
if (documentHasChanged(fileContainer.filePath(), fileContainer.projectPartId())) {
|
||||
registerTranslationUnitsForEditor({fileContainer});
|
||||
if (documentHasChanged(fileContainer.filePath())) {
|
||||
updateTranslationUnitsForEditor({fileContainer});
|
||||
|
||||
const RequestDiagnosticsMessage message(fileContainer);
|
||||
qCDebug(log) << ">>>" << message;
|
||||
m_ipcSender->requestDiagnostics(message);
|
||||
|
||||
setLastSentDocumentRevision(fileContainer.filePath(),
|
||||
fileContainer.projectPartId(),
|
||||
fileContainer.documentRevision());
|
||||
}
|
||||
}
|
||||
|
||||
void IpcCommunicator::requestDiagnostics(Core::IDocument *document)
|
||||
{
|
||||
const auto textDocument = qobject_cast<TextDocument*>(document);
|
||||
const auto filePath = textDocument->filePath().toString();
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
|
||||
requestDiagnostics(FileContainer(filePath,
|
||||
projectPartId,
|
||||
textDocument->document()->revision()));
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath, int position)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document) {
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
document->sendTracker(projectPartId).applyContentChange(position);
|
||||
}
|
||||
if (document)
|
||||
document->sendTracker().applyContentChange(position);
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document)
|
||||
@@ -540,6 +577,16 @@ void IpcCommunicator::registerTranslationUnitsForEditor(const FileContainers &fi
|
||||
m_ipcSender->registerTranslationUnitsForEditor(message);
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnitsForEditor(const IpcCommunicator::FileContainers &fileContainers)
|
||||
{
|
||||
if (m_sendMode == IgnoreSendRequests)
|
||||
return;
|
||||
|
||||
const UpdateTranslationUnitsForEditorMessage message(fileContainers);
|
||||
qCDebug(log) << ">>>" << message;
|
||||
m_ipcSender->updateTranslationUnitsForEditor(message);
|
||||
}
|
||||
|
||||
void IpcCommunicator::unregisterTranslationUnitsForEditor(const FileContainers &fileContainers)
|
||||
{
|
||||
if (m_sendMode == IgnoreSendRequests)
|
||||
|
||||
@@ -53,6 +53,7 @@ class DiagnosticsChangedMessage;
|
||||
|
||||
namespace TextEditor {
|
||||
class TextEditorWidget;
|
||||
class TextDocument;
|
||||
}
|
||||
|
||||
namespace ClangCodeModel {
|
||||
@@ -96,6 +97,7 @@ public:
|
||||
|
||||
virtual void end() = 0;
|
||||
virtual void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) = 0;
|
||||
virtual void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) = 0;
|
||||
virtual void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) = 0;
|
||||
virtual void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) = 0;
|
||||
virtual void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) = 0;
|
||||
@@ -118,6 +120,7 @@ public:
|
||||
IpcCommunicator();
|
||||
|
||||
void registerTranslationUnitsForEditor(const FileContainers &fileContainers);
|
||||
void updateTranslationUnitsForEditor(const FileContainers &fileContainers);
|
||||
void unregisterTranslationUnitsForEditor(const FileContainers &fileContainers);
|
||||
void registerProjectPartsForEditor(const ProjectPartContainers &projectPartContainers);
|
||||
void unregisterProjectPartsForEditor(const QStringList &projectPartIds);
|
||||
@@ -130,6 +133,8 @@ public:
|
||||
|
||||
void registerProjectsParts(const QList<CppTools::ProjectPart::Ptr> projectParts);
|
||||
|
||||
void registerTranslationUnit(TextEditor::TextDocument *document);
|
||||
void registerTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
||||
void updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document);
|
||||
void updateTranslationUnit(Core::IDocument *document);
|
||||
void updateUnsavedFile(Core::IDocument *document);
|
||||
@@ -138,6 +143,7 @@ public:
|
||||
void updateTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
||||
void updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
||||
void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer);
|
||||
void requestDiagnostics(Core::IDocument *document);
|
||||
void updateChangeContentStartPosition(const QString &filePath, int position);
|
||||
|
||||
public: // for tests
|
||||
|
||||
@@ -115,23 +115,14 @@ contains(DEFINES, CLANG_INDEXING) {
|
||||
FORMS += clangprojectsettingspropertiespage.ui
|
||||
|
||||
equals(TEST, 1) {
|
||||
RESOURCES += \
|
||||
test/clang_tests_database.qrc
|
||||
|
||||
HEADERS += \
|
||||
test/clangcodecompletion_test.h
|
||||
|
||||
SOURCES += \
|
||||
test/clangcodecompletion_test.cpp
|
||||
|
||||
DISTFILES += \
|
||||
test/mysource.cpp \
|
||||
test/myheader.cpp \
|
||||
test/completionWithProject.cpp \
|
||||
test/memberCompletion.cpp \
|
||||
test/doxygenKeywordsCompletion.cpp \
|
||||
test/preprocessorKeywordsCompletion.cpp \
|
||||
test/includeDirectiveCompletion.cpp
|
||||
RESOURCES += test/data/clangtestdata.qrc
|
||||
OTHER_FILES += $$files(test/data/*)
|
||||
}
|
||||
|
||||
macx {
|
||||
|
||||
@@ -104,7 +104,7 @@ QtcPlugin {
|
||||
condition: project.testsEnabled
|
||||
prefix: "test/"
|
||||
files: [
|
||||
"clang_tests_database.qrc",
|
||||
"data/clangtestdata.qrc",
|
||||
"clangcodecompletion_test.cpp",
|
||||
"clangcodecompletion_test.h",
|
||||
]
|
||||
@@ -112,20 +112,10 @@ QtcPlugin {
|
||||
|
||||
Group {
|
||||
name: "Test resources"
|
||||
prefix: "test/"
|
||||
prefix: "test/data/"
|
||||
fileTags: "none"
|
||||
files: [
|
||||
"mysource.cpp",
|
||||
"myheader.h",
|
||||
"completionWithProject.cpp",
|
||||
"memberCompletion.cpp",
|
||||
"doxygenKeywordsCompletion.cpp",
|
||||
"preprocessorKeywordsCompletion.cpp",
|
||||
"includeDirectiveCompletion.cpp",
|
||||
"objc_messages_1.mm",
|
||||
"objc_messages_2.mm",
|
||||
"objc_messages_3.mm",
|
||||
]
|
||||
files: [ "*" ]
|
||||
excludeFiles: "clangtestdata.qrc"
|
||||
}
|
||||
|
||||
files: [
|
||||
|
||||
@@ -670,15 +670,14 @@ ClangCompletionAssistProcessor::unsavedFileContent(const QByteArray &customFileC
|
||||
return info;
|
||||
}
|
||||
|
||||
void ClangCompletionAssistProcessor::sendFileContent(const QString &projectPartId,
|
||||
const QByteArray &customFileContent)
|
||||
void ClangCompletionAssistProcessor::sendFileContent(const QByteArray &customFileContent)
|
||||
{
|
||||
// TODO: Revert custom modification after the completions
|
||||
const UnsavedFileContentInfo info = unsavedFileContent(customFileContent);
|
||||
|
||||
IpcCommunicator &ipcCommunicator = m_interface->ipcCommunicator();
|
||||
ipcCommunicator.registerTranslationUnitsForEditor({{m_interface->fileName(),
|
||||
projectPartId,
|
||||
ipcCommunicator.updateTranslationUnitsForEditor({{m_interface->fileName(),
|
||||
Utf8String(),
|
||||
Utf8String::fromByteArray(info.unsavedContent),
|
||||
info.isDocumentModified,
|
||||
uint(m_interface->textDocument()->revision())}});
|
||||
@@ -690,14 +689,13 @@ CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
|
||||
}
|
||||
|
||||
bool shouldSendDocumentForCompletion(const QString &filePath,
|
||||
const QString &projectPartId,
|
||||
int completionPosition)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document) {
|
||||
auto &sendTracker = document->sendTracker(projectPartId);
|
||||
return sendTracker.shouldSendRevisionWithCompletionPosition(document->revision(),
|
||||
auto &sendTracker = document->sendTracker();
|
||||
return sendTracker.shouldSendRevisionWithCompletionPosition(int(document->revision()),
|
||||
completionPosition);
|
||||
}
|
||||
|
||||
@@ -705,14 +703,13 @@ bool shouldSendDocumentForCompletion(const QString &filePath,
|
||||
}
|
||||
|
||||
void setLastCompletionPositionAndDocumentRevision(const QString &filePath,
|
||||
const QString &projectPartId,
|
||||
int completionPosition)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document) {
|
||||
document->sendTracker(projectPartId).setLastCompletionPosition(completionPosition);
|
||||
document->sendTracker(projectPartId).setLastSentRevision(document->revision());
|
||||
document->sendTracker().setLastCompletionPosition(completionPosition);
|
||||
document->sendTracker().setLastSentRevision(document->revision());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,13 +734,13 @@ void ClangCompletionAssistProcessor::sendCompletionRequest(int position,
|
||||
++column;
|
||||
|
||||
const QString filePath = m_interface->fileName();
|
||||
const QString projectPartId = projectPartIdForEditorDocument(filePath);
|
||||
|
||||
if (shouldSendDocumentForCompletion(filePath, projectPartId, position)) {
|
||||
sendFileContent(projectPartId, customFileContent);
|
||||
setLastCompletionPositionAndDocumentRevision(filePath, projectPartId, position);
|
||||
if (shouldSendDocumentForCompletion(filePath, position)) {
|
||||
sendFileContent(customFileContent);
|
||||
setLastCompletionPositionAndDocumentRevision(filePath, position);
|
||||
}
|
||||
|
||||
const QString projectPartId = projectPartIdForEditorDocument(filePath);
|
||||
m_interface->ipcCommunicator().completeCode(this,
|
||||
filePath,
|
||||
uint(line),
|
||||
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
};
|
||||
UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const;
|
||||
|
||||
void sendFileContent(const QString &projectPartId, const QByteArray &customFileContent);
|
||||
void sendFileContent(const QByteArray &customFileContent);
|
||||
void sendCompletionRequest(int position, const QByteArray &customFileContent);
|
||||
|
||||
void handleAvailableCompletions(const CodeCompletions &completions);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user