1 /**********************************************************************
2 ** $ANH-Branch$:$ANH-Revision$ $ANH-Date$
3 ** $Id: qttableview.cpp,v 1.2 2002/03/09 03:13:15 jwalz Exp $
5 ** Implementation of QtTableView class
9 ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
11 ** This file contains a class moved out of the Qt GUI Toolkit API. It
12 ** may be used, distributed and modified without limitation.
14 **********************************************************************/
16 #include "qttableview.h"
18 #ifndef QT_NO_QTTABLEVIEW
19 #include <qscrollbar.h>
21 #include <qdrawutil.h>
24 enum ScrollBarDirtyFlags
{
38 #define HSBEXT horizontalScrollBar()->sizeHint().height()
39 #define VSBEXT verticalScrollBar()->sizeHint().width()
42 class QCornerSquare
: public QWidget
// internal class
45 QCornerSquare( QWidget
*, const char* = 0 );
46 void paintEvent( QPaintEvent
* );
49 QCornerSquare::QCornerSquare( QWidget
*parent
, const char *name
)
50 : QWidget( parent
, name
)
54 void QCornerSquare::paintEvent( QPaintEvent
* )
61 \class QtTableView qttableview.h
62 \brief The QtTableView class provides an abstract base for tables.
66 A table view consists of a number of abstract cells organized in rows
67 and columns, and a visible part called a view. The cells are identified
68 with a row index and a column index. The top-left cell is in row 0,
71 The behavior of the widget can be finely tuned using
72 setTableFlags(); a typical subclass will consist of little more than a
73 call to setTableFlags(), some table content manipulation and an
74 implementation of paintCell(). Subclasses that need cells with
75 variable width or height must reimplement cellHeight() and/or
76 cellWidth(). Use updateTableSize() to tell QtTableView when the
77 width or height has changed.
79 When you read this documentation, it is important to understand the
80 distinctions among the four pixel coordinate systems involved.
83 \i The \e cell coordinates. (0,0) is the top-left corner of a cell.
84 Cell coordinates are used by functions such as paintCell().
86 \i The \e table coordinates. (0,0) is the top-left corner of the cell at
87 row 0 and column 0. These coordinates are absolute; that is, they are
88 independent of what part of the table is visible at the moment. They are
89 used by functions such as setXOffset() or maxYOffset().
91 \i The \e widget coordinates. (0,0) is the top-left corner of the widget,
92 \e including the frame. They are used by functions such as repaint().
94 \i The \e view coordinates. (0,0) is the top-left corner of the view, \e
95 excluding the frame. This is the least-used coordinate system; it is used by
96 functions such as viewWidth(). \endlist
98 It is rather unfortunate that we have to use four different
99 coordinate systems, but there was no alternative to provide a flexible and
102 Note: The row,column indices are always given in that order,
103 i.e., first the vertical (row), then the horizontal (column). This is
104 the opposite order of all pixel operations, which take first the
105 horizontal (x) and then the vertical (y).
107 <img src=qtablevw-m.png> <img src=qtablevw-w.png>
109 \warning the functions setNumRows(), setNumCols(), setCellHeight(),
110 setCellWidth(), setTableFlags() and clearTableFlags() may cause
111 virtual functions such as cellWidth() and cellHeight() to be called,
112 even if autoUpdate() is FALSE. This may cause errors if relevant
113 state variables are not initialized.
115 \warning Experience has shown that use of this widget tends to cause
116 more bugs than expected and our analysis indicates that the widget's
117 very flexibility is the problem. If QScrollView or QListBox can
118 easily be made to do the job you need, we recommend subclassing
119 those widgets rather than QtTableView. In addition, QScrollView makes
120 it easy to have child widgets inside tables, which QtTableView
121 doesn't support at all.
124 \link guibooks.html#fowler GUI Design Handbook: Table\endlink
129 Constructs a table view. The \a parent, \a name and \f arguments
130 are passed to the QFrame constructor.
132 The \link setTableFlags() table flags\endlink are all cleared (set to 0).
133 Set \c Tbl_autoVScrollBar or \c Tbl_autoHScrollBar to get automatic scroll
134 bars and \c Tbl_clipCellPainting to get safe clipping.
136 The \link setCellHeight() cell height\endlink and \link setCellWidth()
137 cell width\endlink are set to 0.
139 Frame line shapes (QFrame::HLink and QFrame::VLine) are disallowed;
140 see QFrame::setFrameStyle().
142 Note that the \a f argument is \e not \link setTableFlags() table
143 flags \endlink but rather \link QWidget::QWidget() widget
148 QtTableView::QtTableView( QWidget
*parent
, const char *name
, WFlags f
)
149 : QFrame( parent
, name
, f
)
151 nRows
= nCols
= 0; // zero rows/cols
152 xCellOffs
= yCellOffs
= 0; // zero offset
153 xCellDelta
= yCellDelta
= 0; // zero cell offset
154 xOffs
= yOffs
= 0; // zero total pixel offset
155 cellH
= cellW
= 0; // user defined cell size
157 vScrollBar
= hScrollBar
= 0; // no scroll bars
160 eraseInPaint
= FALSE
;
162 verSnappingOff
= FALSE
;
164 horSnappingOff
= FALSE
;
165 coveringCornerSquare
= FALSE
;
170 Destroys the table view.
173 QtTableView::~QtTableView()
183 Reimplements QWidget::setBackgroundColor() for binary compatibility.
187 void QtTableView::setBackgroundColor( const QColor
&c
)
189 QWidget::setBackgroundColor( c
);
195 void QtTableView::setPalette( const QPalette
&p
)
197 QWidget::setPalette( p
);
203 void QtTableView::show()
205 showOrHideScrollBars();
211 \overload void QtTableView::repaint( bool erase )
212 Repaints the entire view.
216 Repaints the table view directly by calling paintEvent() directly
217 unless updates are disabled.
219 Erases the view area \a (x,y,w,h) if \a erase is TRUE. Parameters \a
220 (x,y) are in \e widget coordinates.
222 If \a w is negative, it is replaced with <code>width() - x</code>.
223 If \a h is negative, it is replaced with <code>height() - y</code>.
225 Doing a repaint() usually is faster than doing an update(), but
226 calling update() many times in a row will generate a single paint
229 At present, QtTableView is the only widget that reimplements \link
230 QWidget::repaint() repaint()\endlink. It does this because by
231 clearing and then repainting one cell at at time, it can make the
232 screen flicker less than it would otherwise. */
234 void QtTableView::repaint( int x
, int y
, int w
, int h
, bool erase
)
236 if ( !isVisible() || testWState(WState_BlockUpdates
) )
242 QRect
r( x
, y
, w
, h
);
244 return; // nothing to do
246 if ( erase
&& backgroundMode() != NoBackground
)
247 eraseInPaint
= TRUE
; // erase when painting
249 eraseInPaint
= FALSE
;
253 \overload void QtTableView::repaint( const QRect &r, bool erase )
254 Replaints rectangle \a r. If \a erase is TRUE draws the background
255 using the palette's background.
260 \fn int QtTableView::numRows() const
261 Returns the number of rows in the table.
262 \sa numCols(), setNumRows()
266 Sets the number of rows of the table to \a rows (must be non-negative).
267 Does not change topCell().
269 The table repaints itself automatically if autoUpdate() is set.
271 \sa numCols(), setNumCols(), numRows()
274 void QtTableView::setNumRows( int rows
)
277 #if defined(QT_CHECK_RANGE)
278 qWarning( "QtTableView::setNumRows: (%s) Negative argument %d.",
279 name( "unnamed" ), rows
);
286 if ( autoUpdate() && isVisible() ) {
287 int oldLastVisible
= lastRowVisible();
288 int oldTopCell
= topCell();
290 if ( autoUpdate() && isVisible() &&
291 ( oldLastVisible
!= lastRowVisible() || oldTopCell
!= topCell() ) )
292 repaint( oldTopCell
!= topCell() );
294 // Be more careful - if destructing, bad things might happen.
297 updateScrollBars( verRange
);
302 \fn int QtTableView::numCols() const
303 Returns the number of columns in the table.
304 \sa numRows(), setNumCols()
308 Sets the number of columns of the table to \a cols (must be non-negative).
309 Does not change leftCell().
311 The table repaints itself automatically if autoUpdate() is set.
313 \sa numCols(), numRows(), setNumRows()
316 void QtTableView::setNumCols( int cols
)
319 #if defined(QT_CHECK_RANGE)
320 qWarning( "QtTableView::setNumCols: (%s) Negative argument %d.",
321 name( "unnamed" ), cols
);
329 if ( autoUpdate() && isVisible() ) {
330 int maxCol
= lastColVisible();
331 if ( maxCol
>= oldCols
|| maxCol
>= nCols
)
334 updateScrollBars( horRange
);
340 \fn int QtTableView::topCell() const
341 Returns the index of the first row in the table that is visible in
342 the view. The index of the first row is 0.
343 \sa leftCell(), setTopCell()
347 Scrolls the table so that \a row becomes the top row.
348 The index of the very first row is 0.
349 \sa setYOffset(), setTopLeftCell(), setLeftCell()
352 void QtTableView::setTopCell( int row
)
354 setTopLeftCell( row
, -1 );
359 \fn int QtTableView::leftCell() const
360 Returns the index of the first column in the table that is visible in
361 the view. The index of the very leftmost column is 0.
362 \sa topCell(), setLeftCell()
366 Scrolls the table so that \a col becomes the leftmost
367 column. The index of the leftmost column is 0.
368 \sa setXOffset(), setTopLeftCell(), setTopCell()
371 void QtTableView::setLeftCell( int col
)
373 setTopLeftCell( -1, col
);
378 Scrolls the table so that the cell at row \a row and colum \a
379 col becomes the top-left cell in the view. The cell at the extreme
380 top left of the table is at position (0,0).
381 \sa setLeftCell(), setTopCell(), setOffset()
384 void QtTableView::setTopLeftCell( int row
, int col
)
392 if ( newX
> maxXOffset() )
397 newX
+= cellWidth( --col
); // optimize using current! ###
403 if ( newY
> maxYOffset() )
408 newY
+= cellHeight( --row
); // optimize using current! ###
411 setOffset( newX
, newY
);
416 \fn int QtTableView::xOffset() const
418 Returns the x coordinate in \e table coordinates of the pixel that is
419 currently on the left edge of the view.
421 \sa setXOffset(), yOffset(), leftCell() */
424 Scrolls the table so that \a x becomes the leftmost pixel in the view.
425 The \a x parameter is in \e table coordinates.
427 The interaction with \link setTableFlags() Tbl_snapToHGrid
430 \sa xOffset(), setYOffset(), setOffset(), setLeftCell()
433 void QtTableView::setXOffset( int x
)
435 setOffset( x
, yOffset() );
439 \fn int QtTableView::yOffset() const
441 Returns the y coordinate in \e table coordinates of the pixel that is
442 currently on the top edge of the view.
444 \sa setYOffset(), xOffset(), topCell()
449 Scrolls the table so that \a y becomes the top pixel in the view.
450 The \a y parameter is in \e table coordinates.
452 The interaction with \link setTableFlags() Tbl_snapToVGrid
455 \sa yOffset(), setXOffset(), setOffset(), setTopCell()
458 void QtTableView::setYOffset( int y
)
460 setOffset( xOffset(), y
);
464 Scrolls the table so that \a (x,y) becomes the top-left pixel
465 in the view. Parameters \a (x,y) are in \e table coordinates.
467 The interaction with \link setTableFlags() Tbl_snapTo*Grid \endlink
468 is tricky. If \a updateScrBars is TRUE, the scroll bars are
471 \sa xOffset(), yOffset(), setXOffset(), setYOffset(), setTopLeftCell()
474 void QtTableView::setOffset( int x
, int y
, bool updateScrBars
)
476 if ( (!testTableFlags(Tbl_snapToHGrid
) || xCellDelta
== 0) &&
477 (!testTableFlags(Tbl_snapToVGrid
) || yCellDelta
== 0) &&
478 (x
== xOffs
&& y
== yOffs
) )
487 if ( x
> maxXOffset() )
489 xCellOffs
= x
/ cellW
;
490 if ( !testTableFlags(Tbl_snapToHGrid
) ) {
491 xCellDelta
= (short)(x
% cellW
);
497 int xn
=0, xcd
=0, col
= 0;
498 while ( col
< nCols
-1 && x
>= xn
+(xcd
=cellWidth(col
)) ) {
503 if ( testTableFlags(Tbl_snapToHGrid
) ) {
507 xCellDelta
= (short)(x
-xn
);
511 if ( y
> maxYOffset() )
513 yCellOffs
= y
/ cellH
;
514 if ( !testTableFlags(Tbl_snapToVGrid
) ) {
515 yCellDelta
= (short)(y
% cellH
);
521 int yn
=0, yrd
=0, row
=0;
522 while ( row
< nRows
-1 && y
>= yn
+(yrd
=cellHeight(row
)) ) {
527 if ( testTableFlags(Tbl_snapToVGrid
) ) {
531 yCellDelta
= (short)(y
-yn
);
534 int dx
= (x
- xOffs
);
535 int dy
= (y
- yOffs
);
538 if ( autoUpdate() && isVisible() )
541 updateScrollBars( verValue
| horValue
);
546 \overload int QtTableView::cellWidth() const
548 Returns the column width in pixels. Returns 0 if the columns have
551 \sa setCellWidth(), cellHeight()
555 Returns the width of column \a col in pixels.
557 This function is virtual and must be reimplemented by subclasses that
558 have variable cell widths. Note that if the total table width
559 changes, updateTableSize() must be called.
561 \sa setCellWidth(), cellHeight(), totalWidth(), updateTableSize()
564 int QtTableView::cellWidth( int )
571 Sets the width in pixels of the table cells to \a cellWidth.
573 Setting it to 0 means that the column width is variable. When
574 set to 0 (this is the default) QtTableView calls the virtual function
575 cellWidth() to get the width.
577 \sa cellWidth(), setCellHeight(), totalWidth(), numCols()
580 void QtTableView::setCellWidth( int cellWidth
)
582 if ( cellW
== cellWidth
)
584 #if defined(QT_CHECK_RANGE)
585 if ( cellWidth
< 0 || cellWidth
> SHRT_MAX
) {
586 qWarning( "QtTableView::setCellWidth: (%s) Argument out of range (%d)",
587 name( "unnamed" ), cellWidth
);
591 cellW
= (short)cellWidth
;
593 updateScrollBars( horSteps
| horRange
);
594 if ( autoUpdate() && isVisible() )
600 \overload int QtTableView::cellHeight() const
602 Returns the row height, in pixels. Returns 0 if the rows have
605 \sa setCellHeight(), cellWidth()
610 Returns the height of row \a row in pixels.
612 This function is virtual and must be reimplemented by subclasses that
613 have variable cell heights. Note that if the total table height
614 changes, updateTableSize() must be called.
616 \sa setCellHeight(), cellWidth(), totalHeight()
619 int QtTableView::cellHeight( int )
625 Sets the height in pixels of the table cells to \a cellHeight.
627 Setting it to 0 means that the row height is variable. When set
628 to 0 (this is the default), QtTableView calls the virtual function
629 cellHeight() to get the height.
631 \sa cellHeight(), setCellWidth(), totalHeight(), numRows()
634 void QtTableView::setCellHeight( int cellHeight
)
636 if ( cellH
== cellHeight
)
638 #if defined(QT_CHECK_RANGE)
639 if ( cellHeight
< 0 || cellHeight
> SHRT_MAX
) {
640 qWarning( "QtTableView::setCellHeight: (%s) Argument out of range (%d)",
641 name( "unnamed" ), cellHeight
);
645 cellH
= (short)cellHeight
;
646 if ( autoUpdate() && isVisible() )
648 updateScrollBars( verSteps
| verRange
);
653 Returns the total width of the table in pixels.
655 This function is virtual and should be reimplemented by subclasses that
656 have variable cell widths and a non-trivial cellWidth() function, or a
657 large number of columns in the table.
659 The default implementation may be slow for very wide tables.
661 \sa cellWidth(), totalHeight() */
663 int QtTableView::totalWidth()
669 for( int i
= 0 ; i
< nCols
; i
++ )
670 tw
+= cellWidth( i
);
676 Returns the total height of the table in pixels.
678 This function is virtual and should be reimplemented by subclasses that
679 have variable cell heights and a non-trivial cellHeight() function, or a
680 large number of rows in the table.
682 The default implementation may be slow for very tall tables.
684 \sa cellHeight(), totalWidth()
687 int QtTableView::totalHeight()
693 for( int i
= 0 ; i
< nRows
; i
++ )
694 th
+= cellHeight( i
);
701 \fn uint QtTableView::tableFlags() const
703 Returns the union of the table flags that are currently set.
705 \sa setTableFlags(), clearTableFlags(), testTableFlags()
709 \fn bool QtTableView::testTableFlags( uint f ) const
711 Returns TRUE if any of the table flags in \a f are currently set,
714 \sa setTableFlags(), clearTableFlags(), tableFlags()
718 Sets the table flags to \a f.
720 If a flag setting changes the appearance of the table, the table is
721 repainted if - and only if - autoUpdate() is TRUE.
723 The table flags are mostly single bits, though there are some multibit
724 flags for convenience. Here is a complete list:
727 <dt> Tbl_vScrollBar <dd> - The table has a vertical scroll bar.
728 <dt> Tbl_hScrollBar <dd> - The table has a horizontal scroll bar.
729 <dt> Tbl_autoVScrollBar <dd> - The table has a vertical scroll bar if
730 - and only if - the table is taller than the view.
731 <dt> Tbl_autoHScrollBar <dd> The table has a horizontal scroll bar if
732 - and only if - the table is wider than the view.
733 <dt> Tbl_autoScrollBars <dd> - The union of the previous two flags.
734 <dt> Tbl_clipCellPainting <dd> - The table uses QPainter::setClipRect() to
735 make sure that paintCell() will not draw outside the cell
737 <dt> Tbl_cutCellsV <dd> - The table will never show part of a
738 cell at the bottom of the table; if there is not space for all of
739 a cell, the space is left blank.
740 <dt> Tbl_cutCellsH <dd> - The table will never show part of a
741 cell at the right side of the table; if there is not space for all of
742 a cell, the space is left blank.
743 <dt> Tbl_cutCells <dd> - The union of the previous two flags.
744 <dt> Tbl_scrollLastHCell <dd> - When the user scrolls horizontally,
745 let him/her scroll the last cell left until it is at the left
746 edge of the view. If this flag is not set, the user can only scroll
747 to the point where the last cell is completely visible.
748 <dt> Tbl_scrollLastVCell <dd> - When the user scrolls vertically, let
749 him/her scroll the last cell up until it is at the top edge of
750 the view. If this flag is not set, the user can only scroll to the
751 point where the last cell is completely visible.
752 <dt> Tbl_scrollLastCell <dd> - The union of the previous two flags.
753 <dt> Tbl_smoothHScrolling <dd> - The table scrolls as smoothly as
754 possible when the user scrolls horizontally. When this flag is not
755 set, scrolling is done one cell at a time.
756 <dt> Tbl_smoothVScrolling <dd> - The table scrolls as smoothly as
757 possible when scrolling vertically. When this flag is not set,
758 scrolling is done one cell at a time.
759 <dt> Tbl_smoothScrolling <dd> - The union of the previous two flags.
760 <dt> Tbl_snapToHGrid <dd> - Except when the user is actually scrolling,
761 the leftmost column shown snaps to the leftmost edge of the view.
762 <dt> Tbl_snapToVGrid <dd> - Except when the user is actually
763 scrolling, the top row snaps to the top edge of the view.
764 <dt> Tbl_snapToGrid <dd> - The union of the previous two flags.
767 You can specify more than one flag at a time using bitwise OR.
771 setTableFlags( Tbl_smoothScrolling | Tbl_autoScrollBars );
774 \warning The cutCells options (\c Tbl_cutCells, \c Tbl_cutCellsH and
775 Tbl_cutCellsV) may cause painting problems when scrollbars are
776 enabled. Do not combine cutCells and scrollbars.
779 \sa clearTableFlags(), testTableFlags(), tableFlags()
782 void QtTableView::setTableFlags( uint f
)
784 f
= (f
^ tFlags
) & f
; // clear flags already set
787 bool updateOn
= autoUpdate();
788 setAutoUpdate( FALSE
);
790 uint repaintMask
= Tbl_cutCellsV
| Tbl_cutCellsH
;
792 if ( f
& Tbl_vScrollBar
) {
793 setVerScrollBar( TRUE
);
795 if ( f
& Tbl_hScrollBar
) {
796 setHorScrollBar( TRUE
);
798 if ( f
& Tbl_autoVScrollBar
) {
799 updateScrollBars( verRange
);
801 if ( f
& Tbl_autoHScrollBar
) {
802 updateScrollBars( horRange
);
804 if ( f
& Tbl_scrollLastHCell
) {
805 updateScrollBars( horRange
);
807 if ( f
& Tbl_scrollLastVCell
) {
808 updateScrollBars( verRange
);
810 if ( f
& Tbl_snapToHGrid
) {
811 updateScrollBars( horRange
);
813 if ( f
& Tbl_snapToVGrid
) {
814 updateScrollBars( verRange
);
816 if ( f
& Tbl_snapToGrid
) { // Note: checks for 2 flags
817 if ( (f
& Tbl_snapToHGrid
) != 0 && xCellDelta
!= 0 || //have to scroll?
818 (f
& Tbl_snapToVGrid
) != 0 && yCellDelta
!= 0 ) {
819 snapToGrid( (f
& Tbl_snapToHGrid
) != 0, // do snapping
820 (f
& Tbl_snapToVGrid
) != 0 );
821 repaintMask
|= Tbl_snapToGrid
; // repaint table
826 setAutoUpdate( TRUE
);
828 if ( isVisible() && (f
& repaintMask
) )
835 Clears the \link setTableFlags() table flags\endlink that are set
838 Example (clears a single flag):
840 clearTableFlags( Tbl_snapToGrid );
843 The default argument clears all flags.
845 \sa setTableFlags(), testTableFlags(), tableFlags()
848 void QtTableView::clearTableFlags( uint f
)
850 f
= (f
^ ~tFlags
) & f
; // clear flags that are already 0
853 bool updateOn
= autoUpdate();
854 setAutoUpdate( FALSE
);
856 uint repaintMask
= Tbl_cutCellsV
| Tbl_cutCellsH
;
858 if ( f
& Tbl_vScrollBar
) {
859 setVerScrollBar( FALSE
);
861 if ( f
& Tbl_hScrollBar
) {
862 setHorScrollBar( FALSE
);
864 if ( f
& Tbl_scrollLastHCell
) {
865 int maxX
= maxXOffset();
866 if ( xOffs
> maxX
) {
867 setOffset( maxX
, yOffs
);
868 repaintMask
|= Tbl_scrollLastHCell
;
870 updateScrollBars( horRange
);
872 if ( f
& Tbl_scrollLastVCell
) {
873 int maxY
= maxYOffset();
874 if ( yOffs
> maxY
) {
875 setOffset( xOffs
, maxY
);
876 repaintMask
|= Tbl_scrollLastVCell
;
878 updateScrollBars( verRange
);
880 if ( f
& Tbl_smoothScrolling
) { // Note: checks for 2 flags
881 if ((f
& Tbl_smoothHScrolling
) != 0 && xCellDelta
!= 0 ||//must scroll?
882 (f
& Tbl_smoothVScrolling
) != 0 && yCellDelta
!= 0 ) {
883 snapToGrid( (f
& Tbl_smoothHScrolling
) != 0, // do snapping
884 (f
& Tbl_smoothVScrolling
) != 0 );
885 repaintMask
|= Tbl_smoothScrolling
; // repaint table
888 if ( f
& Tbl_snapToHGrid
) {
889 updateScrollBars( horRange
);
891 if ( f
& Tbl_snapToVGrid
) {
892 updateScrollBars( verRange
);
895 setAutoUpdate( TRUE
);
896 updateScrollBars(); // returns immediately if nothing to do
897 if ( isVisible() && (f
& repaintMask
) )
905 \fn bool QtTableView::autoUpdate() const
907 Returns TRUE if the view updates itself automatically whenever it
908 is changed in some way.
914 Sets the auto-update option of the table view to \a enable.
916 If \a enable is TRUE (this is the default), the view updates itself
917 automatically whenever it has changed in some way (for example, when a
918 \link setTableFlags() flag\endlink is changed).
920 If \a enable is FALSE, the view does NOT repaint itself or update
921 its internal state variables when it is changed. This can be
922 useful to avoid flicker during large changes and is singularly
923 useless otherwise. Disable auto-update, do the changes, re-enable
924 auto-update and call repaint().
926 \warning Do not leave the view in this state for a long time
927 (i.e., between events). If, for example, the user interacts with the
928 view when auto-update is off, strange things can happen.
930 Setting auto-update to TRUE does not repaint the view; you must call
931 repaint() to do this.
933 \sa autoUpdate(), repaint()
936 void QtTableView::setAutoUpdate( bool enable
)
938 if ( isUpdatesEnabled() == enable
)
940 setUpdatesEnabled( enable
);
942 showOrHideScrollBars();
949 Repaints the cell at row \a row, column \a col if it is inside the view.
951 If \a erase is TRUE, the relevant part of the view is cleared to the
952 background color/pixmap before the contents are repainted.
957 void QtTableView::updateCell( int row
, int col
, bool erase
)
960 if ( !colXPos( col
, &xPos
) )
962 if ( !rowYPos( row
, &yPos
) )
964 QRect uR
= QRect( xPos
, yPos
,
965 cellW
? cellW
: cellWidth(col
),
966 cellH
? cellH
: cellHeight(row
) );
967 repaint( uR
.intersect(viewRect()), erase
);
972 \fn QRect QtTableView::cellUpdateRect() const
974 This function should be called only from the paintCell() function in
975 subclasses. It returns the portion of a cell that actually needs to be
976 updated in \e cell coordinates. This is useful only for non-trivial
982 Returns the rectangle that is the actual table, excluding any
983 frame, in \e widget coordinates.
986 QRect
QtTableView::viewRect() const
988 return QRect( frameWidth(), frameWidth(), viewWidth(), viewHeight() );
993 Returns the index of the last (bottom) row in the view.
994 The index of the first row is 0.
996 If no rows are visible it returns -1. This can happen if the
997 view is too small for the first row and Tbl_cutCellsV is set.
1002 int QtTableView::lastRowVisible() const
1005 int row
= findRawRow( maxViewY(), &cellMaxY
);
1006 if ( row
== -1 || row
>= nRows
) { // maxViewY() past end?
1007 row
= nRows
- 1; // yes: return last row
1009 if ( testTableFlags(Tbl_cutCellsV
) && cellMaxY
> maxViewY() ) {
1010 if ( row
== yCellOffs
) // cut by right margin?
1011 return -1; // yes, nothing in the view
1013 row
= row
- 1; // cut by margin, one back
1020 Returns the index of the last (right) column in the view.
1021 The index of the first column is 0.
1023 If no columns are visible it returns -1. This can happen if the
1024 view is too narrow for the first column and Tbl_cutCellsH is set.
1026 \sa lastRowVisible()
1029 int QtTableView::lastColVisible() const
1032 int col
= findRawCol( maxViewX(), &cellMaxX
);
1033 if ( col
== -1 || col
>= nCols
) { // maxViewX() past end?
1034 col
= nCols
- 1; // yes: return last col
1036 if ( testTableFlags(Tbl_cutCellsH
) && cellMaxX
> maxViewX() ) {
1037 if ( col
== xCellOffs
) // cut by bottom margin?
1038 return -1; // yes, nothing in the view
1040 col
= col
- 1; // cell by margin, one back
1047 Returns TRUE if \a row is at least partially visible.
1051 bool QtTableView::rowIsVisible( int row
) const
1053 return rowYPos( row
, 0 );
1057 Returns TRUE if \a col is at least partially visible.
1061 bool QtTableView::colIsVisible( int col
) const
1063 return colXPos( col
, 0 );
1069 Called when both scroll bars are active at the same time. Covers the
1070 bottom left corner between the two scroll bars with an empty widget.
1073 void QtTableView::coverCornerSquare( bool enable
)
1075 coveringCornerSquare
= enable
;
1076 if ( !cornerSquare
&& enable
) {
1077 cornerSquare
= new QCornerSquare( this );
1078 Q_CHECK_PTR( cornerSquare
);
1079 cornerSquare
->setGeometry( maxViewX() + frameWidth() + 1,
1080 maxViewY() + frameWidth() + 1,
1084 if ( autoUpdate() && cornerSquare
) {
1086 cornerSquare
->show();
1088 cornerSquare
->hide();
1095 Scroll the view to a position such that:
1097 If \a horizontal is TRUE, the leftmost column shown fits snugly
1098 with the left edge of the view.
1100 If \a vertical is TRUE, the top row shown fits snugly with the top
1103 You can achieve the same effect automatically by setting any of the
1104 \link setTableFlags() Tbl_snapTo*Grid \endlink table flags.
1107 void QtTableView::snapToGrid( bool horizontal
, bool vertical
)
1111 if ( horizontal
&& xCellDelta
!= 0 ) {
1112 int w
= cellW
? cellW
: cellWidth( xCellOffs
);
1113 if ( xCellDelta
>= w
/2 )
1114 newXCell
= xCellOffs
+ 1;
1116 newXCell
= xCellOffs
;
1118 if ( vertical
&& yCellDelta
!= 0 ) {
1119 int h
= cellH
? cellH
: cellHeight( yCellOffs
);
1120 if ( yCellDelta
>= h
/2 )
1121 newYCell
= yCellOffs
+ 1;
1123 newYCell
= yCellOffs
;
1125 setTopLeftCell( newYCell
, newXCell
); //row,column
1130 This internal slot is connected to the horizontal scroll bar's
1131 QScrollBar::valueChanged() signal.
1133 Moves the table horizontally to offset \a val without updating the
1137 void QtTableView::horSbValue( int val
)
1141 if ( horSnappingOff
) {
1142 horSnappingOff
= FALSE
;
1143 tFlags
|= Tbl_snapToHGrid
;
1146 setOffset( val
, yOffs
, FALSE
);
1151 This internal slot is connected to the horizontal scroll bar's
1152 QScrollBar::sliderMoved() signal.
1154 Scrolls the table smoothly horizontally even if \c Tbl_snapToHGrid is set.
1157 void QtTableView::horSbSliding( int val
)
1159 if ( testTableFlags(Tbl_snapToHGrid
) &&
1160 testTableFlags(Tbl_smoothHScrolling
) ) {
1161 tFlags
&= ~Tbl_snapToHGrid
; // turn off snapping while sliding
1162 setOffset( val
, yOffs
, FALSE
);
1163 tFlags
|= Tbl_snapToHGrid
; // turn on snapping again
1165 setOffset( val
, yOffs
, FALSE
);
1171 This internal slot is connected to the horizontal scroll bar's
1172 QScrollBar::sliderReleased() signal.
1175 void QtTableView::horSbSlidingDone( )
1177 if ( testTableFlags(Tbl_snapToHGrid
) &&
1178 testTableFlags(Tbl_smoothHScrolling
) )
1179 snapToGrid( TRUE
, FALSE
);
1184 This internal slot is connected to the vertical scroll bar's
1185 QScrollBar::valueChanged() signal.
1187 Moves the table vertically to offset \a val without updating the
1191 void QtTableView::verSbValue( int val
)
1195 if ( verSnappingOff
) {
1196 verSnappingOff
= FALSE
;
1197 tFlags
|= Tbl_snapToVGrid
;
1200 setOffset( xOffs
, val
, FALSE
);
1205 This internal slot is connected to the vertical scroll bar's
1206 QScrollBar::sliderMoved() signal.
1208 Scrolls the table smoothly vertically even if \c Tbl_snapToVGrid is set.
1211 void QtTableView::verSbSliding( int val
)
1213 if ( testTableFlags(Tbl_snapToVGrid
) &&
1214 testTableFlags(Tbl_smoothVScrolling
) ) {
1215 tFlags
&= ~Tbl_snapToVGrid
; // turn off snapping while sliding
1216 setOffset( xOffs
, val
, FALSE
);
1217 tFlags
|= Tbl_snapToVGrid
; // turn on snapping again
1219 setOffset( xOffs
, val
, FALSE
);
1225 This internal slot is connected to the vertical scroll bar's
1226 QScrollBar::sliderReleased() signal.
1229 void QtTableView::verSbSlidingDone( )
1231 if ( testTableFlags(Tbl_snapToVGrid
) &&
1232 testTableFlags(Tbl_smoothVScrolling
) )
1233 snapToGrid( FALSE
, TRUE
);
1238 This virtual function is called before painting of table cells
1239 is started. It can be reimplemented by subclasses that want to
1240 to set up the painter in a special way and that do not want to
1241 do so for each cell.
1244 void QtTableView::setupPainter( QPainter
* )
1249 \fn void QtTableView::paintCell( QPainter *p, int row, int col )
1251 This pure virtual function is called to paint the single cell at \a
1252 (row,col) using \a p, which is open when paintCell() is called and
1255 The coordinate system is \link QPainter::translate() translated \endlink
1256 so that the origin is at the top-left corner of the cell to be
1257 painted, i.e. \e cell coordinates. Do not scale or shear the coordinate
1258 system (or if you do, restore the transformation matrix before you
1261 The painter is not clipped by default and for maximum efficiency. For safety,
1262 call setTableFlags(Tbl_clipCellPainting) to enable clipping.
1264 \sa paintEvent(), setTableFlags() */
1268 Handles paint events, \a e, for the table view.
1270 Calls paintCell() for the cells that needs to be repainted.
1273 void QtTableView::paintEvent( QPaintEvent
*e
)
1275 QRect updateR
= e
->rect(); // update rectangle
1277 bool e
= eraseInPaint
;
1282 QPainter
paint( this );
1284 if ( !contentsRect().contains( updateR
, TRUE
) ) {// update frame ?
1285 drawFrame( &paint
);
1286 if ( updateR
.left() < frameWidth() ) //###
1287 updateR
.setLeft( frameWidth() );
1288 if ( updateR
.top() < frameWidth() )
1289 updateR
.setTop( frameWidth() );
1292 int maxWX
= maxViewX();
1293 int maxWY
= maxViewY();
1294 if ( updateR
.right() > maxWX
)
1295 updateR
.setRight( maxWX
);
1296 if ( updateR
.bottom() > maxWY
)
1297 updateR
.setBottom( maxWY
);
1299 setupPainter( &paint
); // prepare for painting table
1301 int firstRow
= findRow( updateR
.y() );
1302 int firstCol
= findCol( updateR
.x() );
1304 if ( !colXPos( firstCol
, &xStart
) || !rowYPos( firstRow
, &yStart
) ) {
1305 paint
.eraseRect( updateR
); // erase area outside cells but in view
1308 int maxX
= updateR
.right();
1309 int maxY
= updateR
.bottom();
1313 int xPos
= maxX
+1; // in case the while() is empty
1316 QRect winR
= viewRect();
1319 #ifndef QT_NO_TRANSFORMATIONS
1323 while ( yPos
<= maxY
&& row
< nRows
) {
1324 nextY
= yPos
+ (cellH
? cellH
: cellHeight( row
));
1325 if ( testTableFlags( Tbl_cutCellsV
) && nextY
> ( maxWY
+ 1 ) )
1329 while ( xPos
<= maxX
&& col
< nCols
) {
1330 nextX
= xPos
+ (cellW
? cellW
: cellWidth( col
));
1331 if ( testTableFlags( Tbl_cutCellsH
) && nextX
> ( maxWX
+ 1 ) )
1334 cellR
.setRect( xPos
, yPos
, cellW
? cellW
: cellWidth(col
),
1335 cellH
? cellH
: cellHeight(row
) );
1336 cellUR
= cellR
.intersect( updateR
);
1337 if ( cellUR
.isValid() ) {
1338 cellUpdateR
= cellUR
;
1339 cellUpdateR
.moveBy( -xPos
, -yPos
); // cell coordinates
1341 paint
.eraseRect( cellUR
);
1343 #ifndef QT_NO_TRANSFORMATIONS
1344 matrix
.translate( xPos
, yPos
);
1345 paint
.setWorldMatrix( matrix
);
1346 if ( testTableFlags(Tbl_clipCellPainting
) ||
1347 frameWidth() > 0 && !winR
.contains( cellR
) ) { //##arnt
1348 paint
.setClipRect( cellUR
);
1349 paintCell( &paint
, row
, col
);
1350 paint
.setClipping( FALSE
);
1352 paintCell( &paint
, row
, col
);
1355 paint
.setWorldMatrix( matrix
);
1357 paint
.translate( xPos
, yPos
);
1358 if ( testTableFlags(Tbl_clipCellPainting
) ||
1359 frameWidth() > 0 && !winR
.contains( cellR
) ) { //##arnt
1360 paint
.setClipRect( cellUR
);
1361 paintCell( &paint
, row
, col
);
1362 paint
.setClipping( FALSE
);
1364 paintCell( &paint
, row
, col
);
1366 paint
.translate( -xPos
, -yPos
);
1376 // while painting we have to erase any areas in the view that
1377 // are not covered by cells but are covered by the paint event
1378 // rectangle these must be erased. We know that xPos is the last
1379 // x pixel updated + 1 and that yPos is the last y pixel updated + 1.
1381 // Note that this needs to be done regardless whether we do
1382 // eraseInPaint or not. Reason: a subclass may implement
1383 // flicker-freeness and encourage the use of repaint(FALSE).
1384 // The subclass, however, cannot draw all pixels, just those
1385 // inside the cells. So QtTableView is reponsible for all pixels
1386 // outside the cells.
1388 QRect viewR
= viewRect();
1389 const QColorGroup g
= colorGroup();
1391 if ( xPos
<= maxX
) {
1394 r
.setBottom( yPos
<maxY
?yPos
:maxY
);
1395 if ( inherits( "QMultiLineEdit" ) )
1396 paint
.fillRect( r
.intersect( updateR
), g
.base() );
1398 paint
.eraseRect( r
.intersect( updateR
) );
1400 if ( yPos
<= maxY
) {
1403 if ( inherits( "QMultiLineEdit" ) )
1404 paint
.fillRect( r
.intersect( updateR
), g
.base() );
1406 paint
.eraseRect( r
.intersect( updateR
) );
1412 void QtTableView::resizeEvent( QResizeEvent
* )
1414 updateScrollBars( horValue
| verValue
| horSteps
| horGeometry
| horRange
|
1415 verSteps
| verGeometry
| verRange
);
1416 showOrHideScrollBars();
1418 int maxX
= QMIN( xOffs
, maxXOffset() ); // ### can be slow
1419 int maxY
= QMIN( yOffs
, maxYOffset() );
1420 setOffset( maxX
, maxY
);
1425 Redraws all visible cells in the table view.
1428 void QtTableView::updateView()
1430 repaint( viewRect() );
1434 Returns a pointer to the vertical scroll bar mainly so you can
1435 connect() to its signals. Note that the scroll bar works in pixel
1436 values; use findRow() to translate to cell numbers.
1439 QScrollBar
*QtTableView::verticalScrollBar() const
1441 QtTableView
*that
= (QtTableView
*)this; // semantic const
1442 if ( !vScrollBar
) {
1443 QScrollBar
*sb
= new QScrollBar( QScrollBar::Vertical
, that
);
1444 #ifndef QT_NO_CURSOR
1445 sb
->setCursor( arrowCursor
);
1447 sb
->resize( sb
->sizeHint() ); // height is irrelevant
1449 sb
->setTracking( FALSE
);
1450 sb
->setFocusPolicy( NoFocus
);
1451 connect( sb
, SIGNAL(valueChanged(int)),
1452 SLOT(verSbValue(int)));
1453 connect( sb
, SIGNAL(sliderMoved(int)),
1454 SLOT(verSbSliding(int)));
1455 connect( sb
, SIGNAL(sliderReleased()),
1456 SLOT(verSbSlidingDone()));
1458 that
->vScrollBar
= sb
;
1465 Returns a pointer to the horizontal scroll bar mainly so you can
1466 connect() to its signals. Note that the scroll bar works in pixel
1467 values; use findCol() to translate to cell numbers.
1470 QScrollBar
*QtTableView::horizontalScrollBar() const
1472 QtTableView
*that
= (QtTableView
*)this; // semantic const
1473 if ( !hScrollBar
) {
1474 QScrollBar
*sb
= new QScrollBar( QScrollBar::Horizontal
, that
);
1475 #ifndef QT_NO_CURSOR
1476 sb
->setCursor( arrowCursor
);
1478 sb
->resize( sb
->sizeHint() ); // width is irrelevant
1479 sb
->setFocusPolicy( NoFocus
);
1481 sb
->setTracking( FALSE
);
1482 connect( sb
, SIGNAL(valueChanged(int)),
1483 SLOT(horSbValue(int)));
1484 connect( sb
, SIGNAL(sliderMoved(int)),
1485 SLOT(horSbSliding(int)));
1486 connect( sb
, SIGNAL(sliderReleased()),
1487 SLOT(horSbSlidingDone()));
1489 that
->hScrollBar
= sb
;
1496 Enables or disables the horizontal scroll bar, as required by
1497 setAutoUpdate() and the \link setTableFlags() table flags\endlink.
1500 void QtTableView::setHorScrollBar( bool on
, bool update
)
1503 tFlags
|= Tbl_hScrollBar
;
1504 horizontalScrollBar(); // created
1506 updateScrollBars( horMask
| verMask
);
1508 sbDirty
= sbDirty
| (horMask
| verMask
);
1509 if ( testTableFlags( Tbl_vScrollBar
) )
1510 coverCornerSquare( TRUE
);
1512 sbDirty
= sbDirty
| horMask
;
1514 tFlags
&= ~Tbl_hScrollBar
;
1517 coverCornerSquare( FALSE
);
1518 bool hideScrollBar
= autoUpdate() && hScrollBar
->isVisible();
1519 if ( hideScrollBar
)
1522 updateScrollBars( verMask
);
1524 sbDirty
= sbDirty
| verMask
;
1525 if ( hideScrollBar
&& isVisible() )
1526 repaint( hScrollBar
->x(), hScrollBar
->y(),
1527 width() - hScrollBar
->x(), hScrollBar
->height() );
1535 Enables or disables the vertical scroll bar, as required by
1536 setAutoUpdate() and the \link setTableFlags() table flags\endlink.
1539 void QtTableView::setVerScrollBar( bool on
, bool update
)
1542 tFlags
|= Tbl_vScrollBar
;
1543 verticalScrollBar(); // created
1545 updateScrollBars( verMask
| horMask
);
1547 sbDirty
= sbDirty
| (horMask
| verMask
);
1548 if ( testTableFlags( Tbl_hScrollBar
) )
1549 coverCornerSquare( TRUE
);
1551 sbDirty
= sbDirty
| verMask
;
1553 tFlags
&= ~Tbl_vScrollBar
;
1556 coverCornerSquare( FALSE
);
1557 bool hideScrollBar
= autoUpdate() && vScrollBar
->isVisible();
1558 if ( hideScrollBar
)
1561 updateScrollBars( horMask
);
1563 sbDirty
= sbDirty
| horMask
;
1564 if ( hideScrollBar
&& isVisible() )
1565 repaint( vScrollBar
->x(), vScrollBar
->y(),
1566 vScrollBar
->width(), height() - vScrollBar
->y() );
1575 int QtTableView::findRawRow( int yPos
, int *cellMaxY
, int *cellMinY
,
1576 bool goOutsideView
) const
1581 if ( goOutsideView
|| yPos
>= minViewY() && yPos
<= maxViewY() ) {
1582 if ( yPos
< minViewY() ) {
1583 #if defined(QT_CHECK_RANGE)
1584 qWarning( "QtTableView::findRawRow: (%s) internal error: "
1585 "yPos < minViewY() && goOutsideView "
1586 "not supported. (%d,%d)",
1587 name( "unnamed" ), yPos
, yOffs
);
1591 if ( cellH
) { // uniform cell height
1592 r
= (yPos
- minViewY() + yCellDelta
)/cellH
; // cell offs from top
1594 *cellMaxY
= (r
+ 1)*cellH
+ minViewY() - yCellDelta
- 1;
1596 *cellMinY
= r
*cellH
+ minViewY() - yCellDelta
;
1597 r
+= yCellOffs
; // absolute cell index
1598 } else { // variable cell height
1599 QtTableView
*tw
= (QtTableView
*)this;
1601 int h
= minViewY() - yCellDelta
; //##arnt3
1603 Q_ASSERT( r
< nRows
);
1604 while ( r
< nRows
) {
1606 h
+= tw
->cellHeight( r
); // Start of next cell
1622 int QtTableView::findRawCol( int xPos
, int *cellMaxX
, int *cellMinX
,
1623 bool goOutsideView
) const
1628 if ( goOutsideView
|| xPos
>= minViewX() && xPos
<= maxViewX() ) {
1629 if ( xPos
< minViewX() ) {
1630 #if defined(QT_CHECK_RANGE)
1631 qWarning( "QtTableView::findRawCol: (%s) internal error: "
1632 "xPos < minViewX() && goOutsideView "
1633 "not supported. (%d,%d)",
1634 name( "unnamed" ), xPos
, xOffs
);
1638 if ( cellW
) { // uniform cell width
1639 c
= (xPos
- minViewX() + xCellDelta
)/cellW
; //cell offs from left
1641 *cellMaxX
= (c
+ 1)*cellW
+ minViewX() - xCellDelta
- 1;
1643 *cellMinX
= c
*cellW
+ minViewX() - xCellDelta
;
1644 c
+= xCellOffs
; // absolute cell index
1645 } else { // variable cell width
1646 QtTableView
*tw
= (QtTableView
*)this;
1648 int w
= minViewX() - xCellDelta
; //##arnt3
1650 Q_ASSERT( c
< nCols
);
1651 while ( c
< nCols
) {
1653 w
+= tw
->cellWidth( c
); // Start of next cell
1669 Returns the index of the row at position \a yPos, where \a yPos is in
1670 \e widget coordinates. Returns -1 if \a yPos is outside the valid
1673 \sa findCol(), rowYPos()
1676 int QtTableView::findRow( int yPos
) const
1679 int row
= findRawRow( yPos
, &cellMaxY
);
1680 if ( testTableFlags(Tbl_cutCellsV
) && cellMaxY
> maxViewY() )
1681 row
= - 1; // cell cut by bottom margin
1689 Returns the index of the column at position \a xPos, where \a xPos is
1690 in \e widget coordinates. Returns -1 if \a xPos is outside the valid
1693 \sa findRow(), colXPos()
1696 int QtTableView::findCol( int xPos
) const
1699 int col
= findRawCol( xPos
, &cellMaxX
);
1700 if ( testTableFlags(Tbl_cutCellsH
) && cellMaxX
> maxViewX() )
1701 col
= - 1; // cell cut by right margin
1709 Computes the position in the widget of row \a row.
1711 Returns TRUE and stores the result in \a *yPos (in \e widget
1712 coordinates) if the row is visible. Returns FALSE and does not modify
1713 \a *yPos if \a row is invisible or invalid.
1715 \sa colXPos(), findRow()
1718 bool QtTableView::rowYPos( int row
, int *yPos
) const
1721 if ( row
>= yCellOffs
) {
1723 int lastVisible
= lastRowVisible();
1724 if ( row
> lastVisible
|| lastVisible
== -1 )
1726 y
= (row
- yCellOffs
)*cellH
+ minViewY() - yCellDelta
;
1729 y
= minViewY() - yCellDelta
; // y of leftmost cell in view
1731 QtTableView
*tw
= (QtTableView
*)this;
1732 int maxY
= maxViewY();
1733 while ( r
< row
&& y
<= maxY
)
1734 y
+= tw
->cellHeight( r
++ );
1749 Computes the position in the widget of column \a col.
1751 Returns TRUE and stores the result in \a *xPos (in \e widget
1752 coordinates) if the column is visible. Returns FALSE and does not
1753 modify \a *xPos if \a col is invisible or invalid.
1755 \sa rowYPos(), findCol()
1758 bool QtTableView::colXPos( int col
, int *xPos
) const
1761 if ( col
>= xCellOffs
) {
1763 int lastVisible
= lastColVisible();
1764 if ( col
> lastVisible
|| lastVisible
== -1 )
1766 x
= (col
- xCellOffs
)*cellW
+ minViewX() - xCellDelta
;
1769 x
= minViewX() - xCellDelta
; // x of uppermost cell in view
1771 QtTableView
*tw
= (QtTableView
*)this;
1772 int maxX
= maxViewX();
1773 while ( c
< col
&& x
<= maxX
)
1774 x
+= tw
->cellWidth( c
++ );
1788 Moves the visible area of the table right by \a xPixels and
1789 down by \a yPixels pixels. Both may be negative.
1791 \warning You might find that QScrollView offers a higher-level of
1792 functionality than using QtTableView and this function.
1794 This function is \e not the same as QWidget::scroll(); in particular,
1795 the signs of \a xPixels and \a yPixels have the reverse semantics.
1797 \sa setXOffset(), setYOffset(), setOffset(), setTopCell(),
1801 void QtTableView::scroll( int xPixels
, int yPixels
)
1803 QWidget::scroll( -xPixels
, -yPixels
, contentsRect() );
1808 Returns the leftmost pixel of the table view in \e view
1809 coordinates. This excludes the frame and any header.
1811 \sa maxViewY(), viewWidth(), contentsRect()
1814 int QtTableView::minViewX() const
1816 return frameWidth();
1821 Returns the top pixel of the table view in \e view
1822 coordinates. This excludes the frame and any header.
1824 \sa maxViewX(), viewHeight(), contentsRect()
1827 int QtTableView::minViewY() const
1829 return frameWidth();
1834 Returns the rightmost pixel of the table view in \e view
1835 coordinates. This excludes the frame and any scroll bar, but
1836 includes blank pixels to the right of the visible table data.
1838 \sa maxViewY(), viewWidth(), contentsRect()
1841 int QtTableView::maxViewX() const
1843 return width() - 1 - frameWidth()
1844 - (tFlags
& Tbl_vScrollBar
? VSBEXT
1850 Returns the bottom pixel of the table view in \e view
1851 coordinates. This excludes the frame and any scroll bar, but
1852 includes blank pixels below the visible table data.
1854 \sa maxViewX(), viewHeight(), contentsRect()
1857 int QtTableView::maxViewY() const
1859 return height() - 1 - frameWidth()
1860 - (tFlags
& Tbl_hScrollBar
? HSBEXT
1866 Returns the width of the table view, as such, in \e view
1867 coordinates. This does not include any header, scroll bar or frame,
1868 but it does include background pixels to the right of the table data.
1870 \sa minViewX() maxViewX(), viewHeight(), contentsRect() viewRect()
1873 int QtTableView::viewWidth() const
1875 return maxViewX() - minViewX() + 1;
1880 Returns the height of the table view, as such, in \e view
1881 coordinates. This does not include any header, scroll bar or frame,
1882 but it does include background pixels below the table data.
1884 \sa minViewY() maxViewY() viewWidth() contentsRect() viewRect()
1887 int QtTableView::viewHeight() const
1889 return maxViewY() - minViewY() + 1;
1893 void QtTableView::doAutoScrollBars()
1895 int viewW
= width() - frameWidth() - minViewX();
1896 int viewH
= height() - frameWidth() - minViewY();
1897 bool vScrollOn
= testTableFlags(Tbl_vScrollBar
);
1898 bool hScrollOn
= testTableFlags(Tbl_hScrollBar
);
1903 if ( testTableFlags(Tbl_autoHScrollBar
) ) {
1908 while ( i
< nCols
&& w
<= viewW
)
1909 w
+= cellWidth( i
++ );
1917 if ( testTableFlags(Tbl_autoVScrollBar
) ) {
1922 while ( i
< nRows
&& h
<= viewH
)
1923 h
+= cellHeight( i
++ );
1932 if ( testTableFlags(Tbl_autoHScrollBar
) && vScrollOn
&& !hScrollOn
)
1933 if ( w
> viewW
- VSBEXT
)
1936 if ( testTableFlags(Tbl_autoVScrollBar
) && hScrollOn
&& !vScrollOn
)
1937 if ( h
> viewH
- HSBEXT
)
1940 setHorScrollBar( hScrollOn
, FALSE
);
1941 setVerScrollBar( vScrollOn
, FALSE
);
1947 \fn void QtTableView::updateScrollBars()
1949 Updates the scroll bars' contents and presence to match the table's
1950 state. Generally, you should not need to call this.
1956 Updates the scroll bars' contents and presence to match the table's
1962 void QtTableView::updateScrollBars( uint f
)
1964 sbDirty
= sbDirty
| f
;
1969 if ( testTableFlags(Tbl_autoHScrollBar
) && (sbDirty
& horRange
) ||
1970 testTableFlags(Tbl_autoVScrollBar
) && (sbDirty
& verRange
) )
1971 // if range change and auto
1972 doAutoScrollBars(); // turn scroll bars on/off if needed
1974 if ( !autoUpdate() ) {
1978 if ( yOffset() > 0 && testTableFlags( Tbl_autoVScrollBar
) &&
1979 !testTableFlags( Tbl_vScrollBar
) ) {
1982 if ( xOffset() > 0 && testTableFlags( Tbl_autoHScrollBar
) &&
1983 !testTableFlags( Tbl_hScrollBar
) ) {
1986 if ( !isVisible() ) {
1991 if ( testTableFlags(Tbl_hScrollBar
) && (sbDirty
& horMask
) != 0 ) {
1992 if ( sbDirty
& horGeometry
)
1993 hScrollBar
->setGeometry( 0,height() - HSBEXT
,
1994 viewWidth() + frameWidth()*2,
1997 if ( sbDirty
& horSteps
) {
1999 hScrollBar
->setSteps( QMIN(cellW
,viewWidth()/2), viewWidth() );
2001 hScrollBar
->setSteps( 16, viewWidth() );
2004 if ( sbDirty
& horRange
)
2005 hScrollBar
->setRange( 0, maxXOffset() );
2007 if ( sbDirty
& horValue
)
2008 hScrollBar
->setValue( xOffs
);
2010 // show scrollbar only when it has a sane geometry
2011 if ( !hScrollBar
->isVisible() )
2015 if ( testTableFlags(Tbl_vScrollBar
) && (sbDirty
& verMask
) != 0 ) {
2016 if ( sbDirty
& verGeometry
)
2017 vScrollBar
->setGeometry( width() - VSBEXT
, 0,
2019 viewHeight() + frameWidth()*2 );
2021 if ( sbDirty
& verSteps
) {
2023 vScrollBar
->setSteps( QMIN(cellH
,viewHeight()/2), viewHeight() );
2025 vScrollBar
->setSteps( 16, viewHeight() ); // fttb! ###
2028 if ( sbDirty
& verRange
)
2029 vScrollBar
->setRange( 0, maxYOffset() );
2031 if ( sbDirty
& verValue
)
2032 vScrollBar
->setValue( yOffs
);
2034 // show scrollbar only when it has a sane geometry
2035 if ( !vScrollBar
->isVisible() )
2038 if ( coveringCornerSquare
&&
2039 ( (sbDirty
& verGeometry
) || (sbDirty
& horGeometry
)) )
2040 cornerSquare
->move( maxViewX() + frameWidth() + 1,
2041 maxViewY() + frameWidth() + 1 );
2048 void QtTableView::updateFrameSize()
2050 int rw
= width() - ( testTableFlags(Tbl_vScrollBar
) ?
2052 int rh
= height() - ( testTableFlags(Tbl_hScrollBar
) ?
2059 if ( autoUpdate() ) {
2060 int fh
= frameRect().height();
2061 int fw
= frameRect().width();
2062 setFrameRect( QRect(0,0,rw
,rh
) );
2065 update( QMIN(fw
,rw
) - frameWidth() - 2, 0, frameWidth()+4, rh
);
2067 update( 0, QMIN(fh
,rh
) - frameWidth() - 2, rw
, frameWidth()+4 );
2073 Returns the maximum horizontal offset within the table of the
2074 view's left edge in \e table coordinates.
2076 This is used mainly to set the horizontal scroll bar's range.
2078 \sa maxColOffset(), maxYOffset(), totalWidth()
2081 int QtTableView::maxXOffset()
2083 int tw
= totalWidth();
2085 if ( testTableFlags(Tbl_scrollLastHCell
) ) {
2087 maxOffs
= tw
- ( cellW
? cellW
: cellWidth( nCols
- 1 ) );
2089 maxOffs
= tw
- viewWidth();
2091 if ( testTableFlags(Tbl_snapToHGrid
) ) {
2093 maxOffs
= tw
- (viewWidth()/cellW
)*cellW
;
2095 int goal
= tw
- viewWidth();
2097 int nextCol
= nCols
- 1;
2098 int nextCellWidth
= cellWidth( nextCol
);
2099 while( nextCol
> 0 && pos
> goal
+ nextCellWidth
) {
2100 pos
-= nextCellWidth
;
2101 nextCellWidth
= cellWidth( --nextCol
);
2103 if ( goal
+ nextCellWidth
== pos
)
2105 else if ( goal
< pos
)
2111 maxOffs
= tw
- viewWidth();
2114 return maxOffs
> 0 ? maxOffs
: 0;
2119 Returns the maximum vertical offset within the table of the
2120 view's top edge in \e table coordinates.
2122 This is used mainly to set the vertical scroll bar's range.
2124 \sa maxRowOffset(), maxXOffset(), totalHeight()
2127 int QtTableView::maxYOffset()
2129 int th
= totalHeight();
2131 if ( testTableFlags(Tbl_scrollLastVCell
) ) {
2133 maxOffs
= th
- ( cellH
? cellH
: cellHeight( nRows
- 1 ) );
2135 maxOffs
= th
- viewHeight();
2137 if ( testTableFlags(Tbl_snapToVGrid
) ) {
2139 maxOffs
= th
- (viewHeight()/cellH
)*cellH
;
2141 int goal
= th
- viewHeight();
2143 int nextRow
= nRows
- 1;
2144 int nextCellHeight
= cellHeight( nextRow
);
2145 while( nextRow
> 0 && pos
> goal
+ nextCellHeight
) {
2146 pos
-= nextCellHeight
;
2147 nextCellHeight
= cellHeight( --nextRow
);
2149 if ( goal
+ nextCellHeight
== pos
)
2151 else if ( goal
< pos
)
2157 maxOffs
= th
- viewHeight();
2160 return maxOffs
> 0 ? maxOffs
: 0;
2165 Returns the index of the last column, which may be at the left edge
2168 Depending on the \link setTableFlags() Tbl_scrollLastHCell\endlink flag,
2169 this may or may not be the last column.
2171 \sa maxXOffset(), maxRowOffset()
2174 int QtTableView::maxColOffset()
2176 int mx
= maxXOffset();
2181 while ( col
< nCols
&& mx
> (xcd
=cellWidth(col
)) ) {
2191 Returns the index of the last row, which may be at the top edge of
2194 Depending on the \link setTableFlags() Tbl_scrollLastVCell\endlink flag,
2195 this may or may not be the last row.
2197 \sa maxYOffset(), maxColOffset()
2200 int QtTableView::maxRowOffset()
2202 int my
= maxYOffset();
2207 while ( row
< nRows
&& my
> (ycd
=cellHeight(row
)) ) {
2216 void QtTableView::showOrHideScrollBars()
2218 if ( !autoUpdate() )
2221 if ( testTableFlags(Tbl_vScrollBar
) ) {
2222 if ( !vScrollBar
->isVisible() )
2223 sbDirty
= sbDirty
| verMask
;
2225 if ( vScrollBar
->isVisible() )
2230 if ( testTableFlags(Tbl_hScrollBar
) ) {
2231 if ( !hScrollBar
->isVisible() )
2232 sbDirty
= sbDirty
| horMask
;
2234 if ( hScrollBar
->isVisible() )
2238 if ( cornerSquare
) {
2239 if ( testTableFlags(Tbl_hScrollBar
) &&
2240 testTableFlags(Tbl_vScrollBar
) ) {
2241 if ( !cornerSquare
->isVisible() )
2242 cornerSquare
->show();
2244 if ( cornerSquare
->isVisible() )
2245 cornerSquare
->hide();
2252 Updates the scroll bars and internal state.
2254 Call this function when the table view's total size is changed;
2255 typically because the result of cellHeight() or cellWidth() have changed.
2257 This function does not repaint the widget.
2260 void QtTableView::updateTableSize()
2262 bool updateOn
= autoUpdate();
2263 setAutoUpdate( FALSE
);
2264 int xofs
= xOffset();
2265 xOffs
++; //so that setOffset will not return immediately
2266 setOffset(xofs
,yOffset(),FALSE
); //to calculate internal state correctly
2267 setAutoUpdate(updateOn
);
2269 updateScrollBars( horSteps
| horRange
|
2270 verSteps
| verRange
);
2271 showOrHideScrollBars();