Skip to content
Snippets Groups Projects
Commit ebc85f36 authored by Edward Brown's avatar Edward Brown
Browse files

Improved grammar in docs. Re #22263

parent 3c33141e
No related merge requests found
...@@ -8,7 +8,7 @@ The :code:`JobTreeView` component provides an MVP style view interface for a hie ...@@ -8,7 +8,7 @@ The :code:`JobTreeView` component provides an MVP style view interface for a hie
with a spreadsheet-like appearance for configuring and indicating the status of multiple (batch) with a spreadsheet-like appearance for configuring and indicating the status of multiple (batch)
reduction jobs. It is currently used to implement the tree component of the Batch Widget. reduction jobs. It is currently used to implement the tree component of the Batch Widget.
It is written in C++ and exposed to python through SIP leading to similar API's as shown by the It is written in C++ and exposed to python through SIP leading to similar APIs as shown by the
examples below. examples below.
.. literalinclude:: CodeExamples/init.py .. literalinclude:: CodeExamples/init.py
...@@ -23,17 +23,17 @@ Row Location ...@@ -23,17 +23,17 @@ Row Location
^^^^^^^^^^^^ ^^^^^^^^^^^^
A row location is the notion of an individual row's position within the table. Since the A row location is the notion of an individual row's position within the table. Since the
table is unlike a traditional spreadsheet in that it is hierarchical, the table is more like a table is hierarchical, unlike a traditional spreadsheet, the table is more like a
tree of rows where all non-leaf nodes can have any number of children. tree of rows where all non-leaf nodes can have any number of children.
In practice some interfaces, such as Reflectometry are likely to want to constrain the In practice some interfaces such as Reflectometry are likely to want to constrain the
number of children or depth of the tree, the batch widget has mechanisms for performing this. number of children or depth of the tree, the batch widget has mechanisms for performing this.
Currently a row location is represented as a path from the root node to the row node in question, Currently a row location is represented as a path from the root node to the row node in question,
this is actualised in the :code:`RowLocation` class which contains an ordered list of integers where this is actualised in the :code:`RowLocation` class which contains an ordered list of integers where
each element represents the index of the next node in the path relative to it's predecessor in the each element represents the index of the next node in the path relative to it's predecessor in the
path. An example table and corresponding tree structure, complete with their paths are illustrated in path. An example table and corresponding tree structure are illustrated in the diagram below
the diagram below. (complete with their paths).
.. image:: ../../images/row_location_path.svg .. image:: ../../images/row_location_path.svg
:align: center :align: center
...@@ -41,8 +41,8 @@ the diagram below. ...@@ -41,8 +41,8 @@ the diagram below.
Equality over :code:`RowLocation` objects is based on the equality of their paths. The other relational Equality over :code:`RowLocation` objects is based on the equality of their paths. The other relational
operators have a definition based on a lexicographical comparison such that sorting a range of operators have a definition based on a lexicographical comparison such that sorting a range of
:code:`RowLocation`\ s puts them in the same order as they would appear in the table. As demonstrated by :code:`RowLocation`\ s puts them in the same order as they would appear in the table. This is
the code below. demonstrated by the code below.
.. code-block:: c++ .. code-block:: c++
...@@ -81,7 +81,7 @@ index or all the cells for a particular row respectively. ...@@ -81,7 +81,7 @@ index or all the cells for a particular row respectively.
The :code:`Cell` class contains the per-cell view properties (such as the text it contains) in a The :code:`Cell` class contains the per-cell view properties (such as the text it contains) in a
view-implementation independent format. view-implementation independent format.
These cell objects intentionally have no link back to the view they originated from and so mutating These cell objects intentionally have no link back to the view they originated from, so mutating
them does not directly update the view. In order to update the cell or cells corresponding to a row, them does not directly update the view. In order to update the cell or cells corresponding to a row,
the methods :code:`setCellAt` or :code:`setCellsAt` should be used. This process is illustrated in the methods :code:`setCellAt` or :code:`setCellsAt` should be used. This process is illustrated in
the example code below. the example code below.
...@@ -92,15 +92,15 @@ the example code below. ...@@ -92,15 +92,15 @@ the example code below.
Subtrees Subtrees
^^^^^^^^ ^^^^^^^^
As previously illustrated the conceptual model for the API is a tree of tables. However As previously illustrated the conceptual model for the API is a tree of tables. Initially, this
initially this model presents some challenges when you think about how to represent a model presents some challenges when you think about how to represent a user's selection while
user's selection while preserving the tree structure. This is however necessary in order preserving the tree structure. This is however necessary in order to support presenters which wish
to support presenters which wish to have sensible behaviour for actions such as copy and to have sensible behaviour for actions such as copy and
paste. paste.
A subtree in this context refers to a set of one or more nodes within the tree where if the set has A subtree in this context refers to a set of one or more nodes within the tree where if the set has
a size greater than one, each node is directly connected to at least one other node in the set. a size greater than one, each node is directly connected to at least one other node in the set.
An example of a set of nodes which meets this constraint and a set of nodes which does not are An example of a set of nodes which meets this constraint and a set of nodes which do not are
outlined in blue in the diagram below. outlined in blue in the diagram below.
.. image:: ../../images/subtree.svg .. image:: ../../images/subtree.svg
...@@ -143,7 +143,7 @@ Filtering ...@@ -143,7 +143,7 @@ Filtering
^^^^^^^^^ ^^^^^^^^^
Is is possible to make the JobTreeView only show a subset of the nodes in the tree based on an Is is possible to make the JobTreeView only show a subset of the nodes in the tree based on an
arbitrary predicate over row locations which can of course be translated to their corresponding arbitrary predicate over row locations. These can be translated to their corresponding
node in the MVP model or their corresponding cells from the view. node in the MVP model or their corresponding cells from the view.
The header :code:`RowPredicate.h` defines the interface which must be implemented by implementations The header :code:`RowPredicate.h` defines the interface which must be implemented by implementations
...@@ -152,9 +152,8 @@ the currently active filter as demonstrated by the code below. ...@@ -152,9 +152,8 @@ the currently active filter as demonstrated by the code below.
.. literalinclude:: CodeExamples/filtering.py .. literalinclude:: CodeExamples/filtering.py
The method :code:`resetFilter` is used to unset the filter such that The method :code:`resetFilter` is used to unset the filter so that all items are shown again and
all items are shown again and the :code:`hasFilter` method is used to determine if the filter is the :code:`hasFilter` method is used to determine if the filter is currently set.
currently set.
Some actions performed on the :code:`JobTreeView` can trigger the filter to be reset automatically. Some actions performed on the :code:`JobTreeView` can trigger the filter to be reset automatically.
This necessitates the :code:`notifyFilterReset` method in :code:`JobTreeViewSubscriber` which is This necessitates the :code:`notifyFilterReset` method in :code:`JobTreeViewSubscriber` which is
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
Cell Based View Properties Cell Based View Properties
========================== ==========================
As described in :doc:`../API/JobTreeView` per-cell view properties can be retrieved as an As described in :doc:`../API/JobTreeView`, per-cell view properties can be retrieved as an
instance of the :code:`Cell` class. The mechanics behind this are implemented in instance of the :code:`Cell` class. The mechanics behind this are implemented in
:code:`CellStandardItem.h`. :code:`CellStandardItem.h`.
...@@ -12,8 +12,8 @@ Implementation ...@@ -12,8 +12,8 @@ Implementation
############## ##############
This header contains an enumeration of the per-cell attributes which are not members of This header contains an enumeration of the per-cell attributes which are not members of
:code:`QStandardItem`, this enumeration starts at :code:`Qt::UserRole + 1`. Qt has a built in :code:`QStandardItem`. This enumeration starts at :code:`Qt::UserRole + 1`. Qt has a built in
mechanism for extending the per-cell view attributes which is what we use here. mechanism for extending the per-item view attributes which we use here.
Two significant functions defined in this file are :code:`applyCellPropertiesToItem` and Two significant functions defined in this file are :code:`applyCellPropertiesToItem` and
:code:`extractCellPropertiesFromItem`. These functions are used to save the property values from the :code:`extractCellPropertiesFromItem`. These functions are used to save the property values from the
......
...@@ -5,7 +5,7 @@ Extract Subtrees ...@@ -5,7 +5,7 @@ Extract Subtrees
================ ================
The :code:`ExtractSubtrees` component converts a set of row cell contents and a set of row The :code:`ExtractSubtrees` component converts a set of row cell contents and a set of row
locations into a structured set of subtrees, this is better described by the illustration below. locations into a structured set of subtrees. This is better described by the illustration below.
.. image:: ../../images/extract_subtree.svg .. image:: ../../images/extract_subtree.svg
:align: center :align: center
...@@ -16,7 +16,7 @@ the minimal number of subtrees by grouping connected row locations together into ...@@ -16,7 +16,7 @@ the minimal number of subtrees by grouping connected row locations together into
single subtree. single subtree.
The algorithm used to perform this conversion makes a simplifying assumption that the roots of all The algorithm used to perform this conversion makes a simplifying assumption that the roots of all
subtrees in the result all share a common parent. If this assumption is untrue then the input set subtrees in the result share a common parent. If this assumption is untrue then the input set
is unsuitable and the algorithm will return an empty optional. is unsuitable and the algorithm will return an empty optional.
.. image:: ../../images/subtree_fail.svg .. image:: ../../images/subtree_fail.svg
......
...@@ -18,7 +18,7 @@ the minimal number of subtrees by grouping connected row locations together into ...@@ -18,7 +18,7 @@ the minimal number of subtrees by grouping connected row locations together into
single subtree. single subtree.
The algorithm used to perform this conversion makes a simplifying assumption that the roots of all The algorithm used to perform this conversion makes a simplifying assumption that the roots of all
subtrees in the result all share a common parent. If this assumption is untrue then the input set subtrees in the result share a common parent. If this assumption is untrue then the input set
is unsuitable and the algorithm will return an empty optional. is unsuitable and the algorithm will return an empty optional.
.. image:: ../../images/subtree_fail.svg .. image:: ../../images/subtree_fail.svg
......
...@@ -5,11 +5,11 @@ QtStandardItemTreeModelAdapter ...@@ -5,11 +5,11 @@ QtStandardItemTreeModelAdapter
============================== ==============================
The :code:`QtStandardItemTreeModelAdapter` is a wrapper around :code:`QStandardItemModel` The :code:`QtStandardItemTreeModelAdapter` is a wrapper around :code:`QStandardItemModel`
which helps to enforce the strong typing on :code:`QModelIndex`\ s and eliminates some of the which helps to enforce the strong typing on :code:`QModelIndex`\ s. It eliminates some of the
boilerplate required when working with the model in the :doc:`../API/JobTreeView`, aiming to prevent boilerplate required when working with the model in the :doc:`../API/JobTreeView`, aiming to prevent
:code:`JobTreeView` and higher level classes from working directly with :code:`QStandardItem`\ s. :code:`JobTreeView` and higher level classes from working directly with :code:`QStandardItem`\ s.
It's header also contains definitions for :code:`modelItemFromIndex` who's usage in it's raw Its header also contains definitions for :code:`modelItemFromIndex` whose usage in its raw
form is discouraged outside of the implementation of :code:`QtStandardItemTreeModelAdapter` form is discouraged outside of the implementation of :code:`QtStandardItemTreeModelAdapter`
but currently necessary in :code:`CellDelegate`. but currently necessary in :code:`CellDelegate`.
...@@ -17,5 +17,5 @@ but currently necessary in :code:`CellDelegate`. ...@@ -17,5 +17,5 @@ but currently necessary in :code:`CellDelegate`.
Usage Usage
############################# #############################
The :code:`QtStandardItemTreeModelAdapter` is currently used when performing model manipulations The :code:`QtStandardItemTreeModelAdapter` is used when performing model manipulations
in the :code:`JobTreeView`. in the :code:`JobTreeView`.
...@@ -5,7 +5,7 @@ Model Indices in Job Tree View ...@@ -5,7 +5,7 @@ Model Indices in Job Tree View
============================== ==============================
The :doc:`../API/JobTreeView` uses :code:`RowLocation` objects in it's API as an abstraction over The :doc:`../API/JobTreeView` uses :code:`RowLocation` objects in it's API as an abstraction over
:code:`QModelIndex`\ s which are used internally to access :code:`QStandardItem`\ s from the 'models' :code:`QModelIndex`\ s, which are used internally to access :code:`QStandardItem`\ s from the 'models'
provided by Qt. As such, code which simply uses the :code:`JobTreeView` does not need to know anything provided by Qt. As such, code which simply uses the :code:`JobTreeView` does not need to know anything
about :code:`QModelIndex`\ s. about :code:`QModelIndex`\ s.
...@@ -13,33 +13,33 @@ MVC Models ...@@ -13,33 +13,33 @@ MVC Models
^^^^^^^^^^ ^^^^^^^^^^
Sections of Qt such as :code:`QTreeView` are designed as an MVC framework rather than an MVP Sections of Qt such as :code:`QTreeView` are designed as an MVC framework rather than an MVP
framework, as such working with some sections of it's API becomes difficult when using MVP. Models in framework, so working with some sections of it's API becomes difficult when using MVP. Models in
MVC are directly accessible from the view which is free to read the data directly from it. In MVP MVC are directly accessible from the view which is free to read the data directly from it. In MVP
however, data access is marshalled through the presenter, models and presenters are not supposed to however, data access is marshalled through the presenter, and both models and presenters are not
be coupled to any particular view implementation. supposed to be coupled to any particular view implementation.
The Main Model The Main Model
-------------- --------------
The :code:`JobTreeView` solves this problem by keeping an internal instance of The :code:`JobTreeView` solves this problem by keeping an internal instance of
:code:`QStandardItemModel` a Qt 'model' which fulfils Qt's requirements for a 'model' and which acts :code:`QStandardItemModel`, a Qt 'model' which fulfils Qt's requirements for a 'model' and acts
as the view state. We refer to this instance as the 'main model'. as the view state. We refer to this instance as the 'main model'.
Filtered Model Filtered Model
-------------- --------------
To take advantage of the filtering functionality offered by the :code:`QTreeView`, the To take advantage of the filtering functionality offered by the :code:`QTreeView`, the
:code:`JobTreeView` also manages an instance of :code:`FilteredTreeModel`, a class derived from :code:`JobTreeView` also manages an instance of :code:`FilteredTreeModel`. This is a class derived from
:code:`QSortFilterProxyModel` which is a filtered version of the 'main model'. :code:`QSortFilterProxyModel` - a filtered version of the 'main model'.
Strongly Typed Indexes Strongly Typed Indexes
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
The :code:`QModelIndex`\ s into the filtered model cannot be used to directly access items in the The :code:`QModelIndex`\ s for the filtered model cannot be used to directly access items in the
main model. Likewise, the :code:`QModelIndex`\ s cannot be used to directly access items in the main model. Likewise, the :code:`QModelIndex`\ s for the main model cannot be used to directly
filtered model. Indexes must be explicitly converted between the two spaces. access items in the filtered model. Indexes must be explicitly converted between the two spaces.
To make this less bugprone, the header file :code:`StrictQModelIndices.h` defines two types, To make this less bug prone, the header file :code:`StrictQModelIndices.h` defines two types,
:code:`QModelIndexForMainModel` and :code:`QModelIndexForFilteredModel`. Functions which wish to :code:`QModelIndexForMainModel` and :code:`QModelIndexForFilteredModel`. Functions which wish to
constrain the indices they accept and/or return can now make that explicit and use the type system constrain the indices they accept and/or return can now make that explicit and use the type system
to catch errors. to catch errors.
...@@ -49,26 +49,26 @@ Converting Between Index Spaces ...@@ -49,26 +49,26 @@ Converting Between Index Spaces
The filtered model holds a subset of the items in the main model, therefore: The filtered model holds a subset of the items in the main model, therefore:
* Conversion from a valid index into the filtered model to a valid index into the main model should * Conversion from an index for the filtered model to an index for the main model should
always be successful. always be successful.
* Conversion from a valid index into the main model to a valid index into the main model could be * Conversion from an index for the main model to a valid index for the main model could be
unsuccessful. unsuccessful.
Given a :code:`QModelIndex`, in order to convert to a strongly typed variant you must know whether Given a :code:`QModelIndex`, in order to convert to a strongly typed variant you must know whether
it originated from the filtered model or the main model. Conversion to the appropriate it originated from the filtered model or the main model. Conversion to the appropriate
strongly typed variant is done via assertion using the functions :code:`fromMainModel` and strongly typed variant is done via assertion using the functions :code:`fromMainModel` and
:code:`fromFilteredModel` provided by :code:`StrictQModelIndices.h`. These functions attempt to :code:`fromFilteredModel` provided by :code:`StrictQModelIndices.h`. These functions attempt to
check the assertion by requiring a reference to the model you are claiming the index is from and check the assertion by requiring a reference to the model you are claiming the index is for and
comparing it with the pointer returned by calling :code:`.model()` on the model index. However this comparing it with the pointer returned by calling :code:`.model()` on the model index. However this
is only a heuristic since the index could refer to a cell which has since been removed from the is only a heuristic since the index could refer to a cell which has since been removed from the
filtered model due to a change of filter. filtered model due to a change of filter.
After the construction of the :code:`JobTreeView`, indices provided through :code:`QTreeView` APIs After the construction of the :code:`JobTreeView`, indices provided through :code:`QTreeView` APIs
are indices into the filtered model and must be mapped into the main model before being used to are indices for the filtered model and must be mapped to the main model before being used to
modify it. :code:`RowLocation`\ s on the other hand always correspond with indices into the main modify it. :code:`RowLocation`\ s on the other hand always correspond with indices for the main
model. model.
Asserting that an index is from one space or the other as described above is not the same as mapping Asserting that an index is for one space or the other as described above is not the same as mapping
from one space into the other. This is performed using the functions :code:`mapToMainModel` and from one space into the other. This is performed using the functions :code:`mapToMainModel` and
:code:`mapToFilteredModel` defined in :code:`JobTreeView` which internally call methods of the :code:`mapToFilteredModel` defined in :code:`JobTreeView` which internally call methods of the
filtered model. filtered model.
...@@ -77,6 +77,6 @@ Type Erasure ...@@ -77,6 +77,6 @@ Type Erasure
------------ ------------
Some functions are ambivalent to which model an index belongs to, a good example might be those in Some functions are ambivalent to which model an index belongs to, a good example might be those in
:code:`QtBasicNavigation.h`, in order to still be able to use these functions without requiring them :code:`QtBasicNavigation.h` - in order to still be able to use these functions without requiring them
all to be templates, the strict versions have a member function :code:`.untyped()` which returns the all to be templates, the strict versions have a member function :code:`.untyped()` which returns the
internal plain old :code:`QModelIndex`. internal plain old :code:`QModelIndex`.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment