Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \example itemviews/frozencolumn
++ \title Frozen Column Example
++ \examplecategory {User Interface Components}
++ \ingroup examples-itemviews
++ \brief This example demonstrates how to freeze a column within a QTableView.
++
++ \image frozencolumn-example.png
++ {Application showing a frozen column in a table}
++
++ We use Qt's model/view framework to implement a table with its first
++ column frozen. This technique can be applied to several columns or rows,
++ as long as they are on the edge of the table.
++
++ The model/view framework allows for one model to be displayed in different
++ ways using multiple views. For this example, we use two views on the same
++ model - two \l {QTableView}{table views} sharing one model. The frozen
++ column is a child of the main tableview, and we provide the desired visual
++ effect using an overlay technique which will be described step by step in
++ the coming sections.
++
++ \image frozencolumn-tableview.png
++ {The layout of the table view, headers, and scrollbars}
++
++ \section1 FreezeTableWidget Class Definition
++
++ The \c FreezeTableWidget class has a constructor and a destructor. Also, it
++ has two private members: the table view that we will use as an overlay, and
++ the shared model for both table views. Two slots are added to help keep the
++ section sizes in sync, as well as a function to readjust the frozen
++ column's geometry. In addition, we reimplement two functions:
++ \l{QAbstractItemView::}{resizeEvent()} and \l{QTableView::}{moveCursor()}.
++
++ \snippet itemviews/frozencolumn/freezetablewidget.h Widget definition
++
++ \note QAbstractItemView is \l{QTableView}'s ancestor.
++
++
++ \section1 FreezeTableWidget Class Implementation
++
++ The constructor takes \a model as an argument and creates a table view that
++ we will use to display the frozen column. Then, within the constructor, we
++ invoke the \c init() function to set up the frozen column. Finally, we
++ connect the \l{QHeaderView::sectionResized()} signals (for horizontal and
++ vertical headers) to the appropriate slots. This ensures that our frozen
++ column's sections are in sync with the headers. We also connect the
++ vertical scrollbars together so that the frozen column scrolls vertically
++ with the rest of our table.
++
++ \snippet itemviews/frozencolumn/freezetablewidget.cpp constructor
++
++
++ In the \c init() function, we ensure that the overlay table view
++ responsible for displaying the frozen column, is set up properly. This
++ means that this table view, \c frozenTableView, has to have the same model
++ as the main table view. However, the difference here is: \c frozenTableView's
++ only visible column is its first column; we hide the others using
++ \l{QTableView::}{setColumnHidden()}
++
++ \snippet itemviews/frozencolumn/freezetablewidget.cpp init part1
++
++
++ In terms of the frozen column's z-order, we stack it on top of the
++ viewport. This is achieved by calling \l{QWidget::}{stackUnder()} on the
++ viewport. For appearance's sake, we prevent the column from stealing focus
++ from the main tableview. Also, we make sure that both views share the same
++ selection model, so only one cell can be selected at a time. A few other
++ tweaks are done to make our application look good and behave consistently
++ with the main tableview. Note that we called \c updateFrozenTableGeometry()
++ to make the column occupy the correct spot.
++
++ \snippet itemviews/frozencolumn/freezetablewidget.cpp init part2
++
++ When you resize the frozen column, the same column on the main table view
++ must resize accordingly, to provide seamless integration. This is
++ accomplished by getting the new size of the column from the \c newSize
++ value from the \l{QHeaderView::}{sectionResized()} signal, emitted by both
++ the horizontal and vertical header.
++
++ \snippet itemviews/frozencolumn/freezetablewidget.cpp sections
++
++ Since the width of the frozen column is modified, we adjust the geometry of
++ the widget accordingly by invoking \c updateFrozenTableGeometry(). This
++ function is further explained below.
++
++ In our reimplementation of QTableView::resizeEvent(), we call
++ \c updateFrozenTableGeometry() after invoking the base class
++ implementation.
++
++ \snippet itemviews/frozencolumn/freezetablewidget.cpp resize
++
++ When navigating around the table with the keyboard, we need to ensure that
++ the current selection does not disappear behind the frozen column. To
++ synchronize this, we reimplement QTableView::moveCursor() and adjust the
++ scrollbar positions if needed, after calling the base class implementation.
++
++ \snippet itemviews/frozencolumn/freezetablewidget.cpp navigate
++
++ The frozen column's geometry calculation is based on the geometry of the
++ table underneath, so it always appears in the right place. Using the
++ QFrame::frameWidth() function helps to calculate this geometry correctly,
++ no matter which style is used. We rely on the geometry of the viewport and
++ headers to set the boundaries for the frozen column.
++
++ \snippet itemviews/frozencolumn/freezetablewidget.cpp geometry
++
++ */
++