1
/**********************************************************************
4
** Implementation of QtTableView class
8
** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
10
** This file contains a class moved out of the Qt GUI Toolkit API. It
11
** may be used, distributed and modified without limitation.
13
**********************************************************************/
15
#include "qttableview.h"
16
#ifndef QT_NO_QTTABLEVIEW
17
#include "qscrollbar.h"
19
#include "qdrawutil.h"
22
enum ScrollBarDirtyFlags {
36
#define HSBEXT horizontalScrollBar()->sizeHint().height()
37
#define VSBEXT verticalScrollBar()->sizeHint().width()
40
class QCornerSquare : public QWidget // internal class
43
QCornerSquare( QWidget *, const char* = 0 );
44
void paintEvent( QPaintEvent * );
47
QCornerSquare::QCornerSquare( QWidget *parent, const char *name )
48
: QWidget( parent, name )
52
void QCornerSquare::paintEvent( QPaintEvent * )
59
\class QtTableView qttableview.h
60
\brief The QtTableView class provides an abstract base for tables.
64
A table view consists of a number of abstract cells organized in rows
65
and columns, and a visible part called a view. The cells are identified
66
with a row index and a column index. The top-left cell is in row 0,
69
The behavior of the widget can be finely tuned using
70
setTableFlags(); a typical subclass will consist of little more than a
71
call to setTableFlags(), some table content manipulation and an
72
implementation of paintCell(). Subclasses that need cells with
73
variable width or height must reimplement cellHeight() and/or
74
cellWidth(). Use updateTableSize() to tell QtTableView when the
75
width or height has changed.
77
When you read this documentation, it is important to understand the
78
distinctions among the four pixel coordinate systems involved.
81
\i The \e cell coordinates. (0,0) is the top-left corner of a cell.
82
Cell coordinates are used by functions such as paintCell().
84
\i The \e table coordinates. (0,0) is the top-left corner of the cell at
85
row 0 and column 0. These coordinates are absolute; that is, they are
86
independent of what part of the table is visible at the moment. They are
87
used by functions such as setXOffset() or maxYOffset().
89
\i The \e widget coordinates. (0,0) is the top-left corner of the widget,
90
\e including the frame. They are used by functions such as repaint().
92
\i The \e view coordinates. (0,0) is the top-left corner of the view, \e
93
excluding the frame. This is the least-used coordinate system; it is used by
94
functions such as viewWidth(). \endlist
96
It is rather unfortunate that we have to use four different
97
coordinate systems, but there was no alternative to provide a flexible and
100
Note: The row,column indices are always given in that order,
101
i.e., first the vertical (row), then the horizontal (column). This is
102
the opposite order of all pixel operations, which take first the
103
horizontal (x) and then the vertical (y).
105
<img src=qtablevw-m.png> <img src=qtablevw-w.png>
107
\warning the functions setNumRows(), setNumCols(), setCellHeight(),
108
setCellWidth(), setTableFlags() and clearTableFlags() may cause
109
virtual functions such as cellWidth() and cellHeight() to be called,
110
even if autoUpdate() is FALSE. This may cause errors if relevant
111
state variables are not initialized.
113
\warning Experience has shown that use of this widget tends to cause
114
more bugs than expected and our analysis indicates that the widget's
115
very flexibility is the problem. If QScrollView or QListBox can
116
easily be made to do the job you need, we recommend subclassing
117
those widgets rather than QtTableView. In addition, QScrollView makes
118
it easy to have child widgets inside tables, which QtTableView
119
doesn't support at all.
122
\link guibooks.html#fowler GUI Design Handbook: Table\endlink
127
Constructs a table view. The \a parent, \a name and \f arguments
128
are passed to the QFrame constructor.
130
The \link setTableFlags() table flags\endlink are all cleared (set to 0).
131
Set \c Tbl_autoVScrollBar or \c Tbl_autoHScrollBar to get automatic scroll
132
bars and \c Tbl_clipCellPainting to get safe clipping.
134
The \link setCellHeight() cell height\endlink and \link setCellWidth()
135
cell width\endlink are set to 0.
137
Frame line shapes (QFrame::HLink and QFrame::VLine) are disallowed;
138
see QFrame::setFrameStyle().
140
Note that the \a f argument is \e not \link setTableFlags() table
141
flags \endlink but rather \link QWidget::QWidget() widget
146
QtTableView::QtTableView( QWidget *parent, const char *name, WFlags f )
147
: QFrame( parent, name, f )
149
nRows = nCols = 0; // zero rows/cols
150
xCellOffs = yCellOffs = 0; // zero offset
151
xCellDelta = yCellDelta = 0; // zero cell offset
152
xOffs = yOffs = 0; // zero total pixel offset
153
cellH = cellW = 0; // user defined cell size
155
vScrollBar = hScrollBar = 0; // no scroll bars
158
eraseInPaint = FALSE;
160
verSnappingOff = FALSE;
162
horSnappingOff = FALSE;
163
coveringCornerSquare = FALSE;
168
Destroys the table view.
171
QtTableView::~QtTableView()
181
Reimplements QWidget::setBackgroundColor() for binary compatibility.
185
void QtTableView::setBackgroundColor( const QColor &c )
187
QWidget::setBackgroundColor( c );
193
void QtTableView::setPalette( const QPalette &p )
195
QWidget::setPalette( p );
201
void QtTableView::show()
203
showOrHideScrollBars();
209
\overload void QtTableView::repaint( bool erase )
210
Repaints the entire view.
214
Repaints the table view directly by calling paintEvent() directly
215
unless updates are disabled.
217
Erases the view area \a (x,y,w,h) if \a erase is TRUE. Parameters \a
218
(x,y) are in \e widget coordinates.
220
If \a w is negative, it is replaced with <code>width() - x</code>.
221
If \a h is negative, it is replaced with <code>height() - y</code>.
223
Doing a repaint() usually is faster than doing an update(), but
224
calling update() many times in a row will generate a single paint
227
At present, QtTableView is the only widget that reimplements \link
228
QWidget::repaint() repaint()\endlink. It does this because by
229
clearing and then repainting one cell at at time, it can make the
230
screen flicker less than it would otherwise. */
232
void QtTableView::repaint( int x, int y, int w, int h, bool erase )
234
if ( !isVisible() || testWState(WState_BlockUpdates) )
240
QRect r( x, y, w, h );
242
return; // nothing to do
244
if ( erase && backgroundMode() != NoBackground )
245
eraseInPaint = TRUE; // erase when painting
247
eraseInPaint = FALSE;
251
\overload void QtTableView::repaint( const QRect &r, bool erase )
252
Replaints rectangle \a r. If \a erase is TRUE draws the background
253
using the palette's background.
258
\fn int QtTableView::numRows() const
259
Returns the number of rows in the table.
260
\sa numCols(), setNumRows()
264
Sets the number of rows of the table to \a rows (must be non-negative).
265
Does not change topCell().
267
The table repaints itself automatically if autoUpdate() is set.
269
\sa numCols(), setNumCols(), numRows()
272
void QtTableView::setNumRows( int rows )
275
#if defined(QT_CHECK_RANGE)
276
qWarning( "QtTableView::setNumRows: (%s) Negative argument %d.",
277
name( "unnamed" ), rows );
284
if ( autoUpdate() && isVisible() ) {
285
int oldLastVisible = lastRowVisible();
286
int oldTopCell = topCell();
288
if ( autoUpdate() && isVisible() &&
289
( oldLastVisible != lastRowVisible() || oldTopCell != topCell() ) )
290
repaint( oldTopCell != topCell() );
292
// Be more careful - if destructing, bad things might happen.
295
updateScrollBars( verRange );
300
\fn int QtTableView::numCols() const
301
Returns the number of columns in the table.
302
\sa numRows(), setNumCols()
306
Sets the number of columns of the table to \a cols (must be non-negative).
307
Does not change leftCell().
309
The table repaints itself automatically if autoUpdate() is set.
311
\sa numCols(), numRows(), setNumRows()
314
void QtTableView::setNumCols( int cols )
317
#if defined(QT_CHECK_RANGE)
318
qWarning( "QtTableView::setNumCols: (%s) Negative argument %d.",
319
name( "unnamed" ), cols );
327
if ( autoUpdate() && isVisible() ) {
328
int maxCol = lastColVisible();
329
if ( maxCol >= oldCols || maxCol >= nCols )
332
updateScrollBars( horRange );
338
\fn int QtTableView::topCell() const
339
Returns the index of the first row in the table that is visible in
340
the view. The index of the first row is 0.
341
\sa leftCell(), setTopCell()
345
Scrolls the table so that \a row becomes the top row.
346
The index of the very first row is 0.
347
\sa setYOffset(), setTopLeftCell(), setLeftCell()
350
void QtTableView::setTopCell( int row )
352
setTopLeftCell( row, -1 );
357
\fn int QtTableView::leftCell() const
358
Returns the index of the first column in the table that is visible in
359
the view. The index of the very leftmost column is 0.
360
\sa topCell(), setLeftCell()
364
Scrolls the table so that \a col becomes the leftmost
365
column. The index of the leftmost column is 0.
366
\sa setXOffset(), setTopLeftCell(), setTopCell()
369
void QtTableView::setLeftCell( int col )
371
setTopLeftCell( -1, col );
376
Scrolls the table so that the cell at row \a row and colum \a
377
col becomes the top-left cell in the view. The cell at the extreme
378
top left of the table is at position (0,0).
379
\sa setLeftCell(), setTopCell(), setOffset()
382
void QtTableView::setTopLeftCell( int row, int col )
390
if ( newX > maxXOffset() )
395
newX += cellWidth( --col ); // optimize using current! ###
401
if ( newY > maxYOffset() )
406
newY += cellHeight( --row ); // optimize using current! ###
409
setOffset( newX, newY );
414
\fn int QtTableView::xOffset() const
416
Returns the x coordinate in \e table coordinates of the pixel that is
417
currently on the left edge of the view.
419
\sa setXOffset(), yOffset(), leftCell() */
422
Scrolls the table so that \a x becomes the leftmost pixel in the view.
423
The \a x parameter is in \e table coordinates.
425
The interaction with \link setTableFlags() Tbl_snapToHGrid
428
\sa xOffset(), setYOffset(), setOffset(), setLeftCell()
431
void QtTableView::setXOffset( int x )
433
setOffset( x, yOffset() );
437
\fn int QtTableView::yOffset() const
439
Returns the y coordinate in \e table coordinates of the pixel that is
440
currently on the top edge of the view.
442
\sa setYOffset(), xOffset(), topCell()
447
Scrolls the table so that \a y becomes the top pixel in the view.
448
The \a y parameter is in \e table coordinates.
450
The interaction with \link setTableFlags() Tbl_snapToVGrid
453
\sa yOffset(), setXOffset(), setOffset(), setTopCell()
456
void QtTableView::setYOffset( int y )
458
setOffset( xOffset(), y );
462
Scrolls the table so that \a (x,y) becomes the top-left pixel
463
in the view. Parameters \a (x,y) are in \e table coordinates.
465
The interaction with \link setTableFlags() Tbl_snapTo*Grid \endlink
466
is tricky. If \a updateScrBars is TRUE, the scroll bars are
469
\sa xOffset(), yOffset(), setXOffset(), setYOffset(), setTopLeftCell()
472
void QtTableView::setOffset( int x, int y, bool updateScrBars )
474
if ( (!testTableFlags(Tbl_snapToHGrid) || xCellDelta == 0) &&
475
(!testTableFlags(Tbl_snapToVGrid) || yCellDelta == 0) &&
476
(x == xOffs && y == yOffs) )
485
if ( x > maxXOffset() )
487
xCellOffs = x / cellW;
488
if ( !testTableFlags(Tbl_snapToHGrid) ) {
489
xCellDelta = (short)(x % cellW);
495
int xn=0, xcd=0, col = 0;
496
while ( col < nCols-1 && x >= xn+(xcd=cellWidth(col)) ) {
501
if ( testTableFlags(Tbl_snapToHGrid) ) {
505
xCellDelta = (short)(x-xn);
509
if ( y > maxYOffset() )
511
yCellOffs = y / cellH;
512
if ( !testTableFlags(Tbl_snapToVGrid) ) {
513
yCellDelta = (short)(y % cellH);
519
int yn=0, yrd=0, row=0;
520
while ( row < nRows-1 && y >= yn+(yrd=cellHeight(row)) ) {
525
if ( testTableFlags(Tbl_snapToVGrid) ) {
529
yCellDelta = (short)(y-yn);
532
int dx = (x - xOffs);
533
int dy = (y - yOffs);
536
if ( autoUpdate() && isVisible() )
539
updateScrollBars( verValue | horValue );
544
\overload int QtTableView::cellWidth() const
546
Returns the column width in pixels. Returns 0 if the columns have
549
\sa setCellWidth(), cellHeight()
553
Returns the width of column \a col in pixels.
555
This function is virtual and must be reimplemented by subclasses that
556
have variable cell widths. Note that if the total table width
557
changes, updateTableSize() must be called.
559
\sa setCellWidth(), cellHeight(), totalWidth(), updateTableSize()
562
int QtTableView::cellWidth( int )
569
Sets the width in pixels of the table cells to \a cellWidth.
571
Setting it to 0 means that the column width is variable. When
572
set to 0 (this is the default) QtTableView calls the virtual function
573
cellWidth() to get the width.
575
\sa cellWidth(), setCellHeight(), totalWidth(), numCols()
578
void QtTableView::setCellWidth( int cellWidth )
580
if ( cellW == cellWidth )
582
#if defined(QT_CHECK_RANGE)
583
if ( cellWidth < 0 || cellWidth > SHRT_MAX ) {
584
qWarning( "QtTableView::setCellWidth: (%s) Argument out of range (%d)",
585
name( "unnamed" ), cellWidth );
589
cellW = (short)cellWidth;
591
updateScrollBars( horSteps | horRange );
592
if ( autoUpdate() && isVisible() )
598
\overload int QtTableView::cellHeight() const
600
Returns the row height, in pixels. Returns 0 if the rows have
603
\sa setCellHeight(), cellWidth()
608
Returns the height of row \a row in pixels.
610
This function is virtual and must be reimplemented by subclasses that
611
have variable cell heights. Note that if the total table height
612
changes, updateTableSize() must be called.
614
\sa setCellHeight(), cellWidth(), totalHeight()
617
int QtTableView::cellHeight( int )
623
Sets the height in pixels of the table cells to \a cellHeight.
625
Setting it to 0 means that the row height is variable. When set
626
to 0 (this is the default), QtTableView calls the virtual function
627
cellHeight() to get the height.
629
\sa cellHeight(), setCellWidth(), totalHeight(), numRows()
632
void QtTableView::setCellHeight( int cellHeight )
634
if ( cellH == cellHeight )
636
#if defined(QT_CHECK_RANGE)
637
if ( cellHeight < 0 || cellHeight > SHRT_MAX ) {
638
qWarning( "QtTableView::setCellHeight: (%s) Argument out of range (%d)",
639
name( "unnamed" ), cellHeight );
643
cellH = (short)cellHeight;
644
if ( autoUpdate() && isVisible() )
646
updateScrollBars( verSteps | verRange );
651
Returns the total width of the table in pixels.
653
This function is virtual and should be reimplemented by subclasses that
654
have variable cell widths and a non-trivial cellWidth() function, or a
655
large number of columns in the table.
657
The default implementation may be slow for very wide tables.
659
\sa cellWidth(), totalHeight() */
661
int QtTableView::totalWidth()
667
for( int i = 0 ; i < nCols ; i++ )
668
tw += cellWidth( i );
674
Returns the total height of the table in pixels.
676
This function is virtual and should be reimplemented by subclasses that
677
have variable cell heights and a non-trivial cellHeight() function, or a
678
large number of rows in the table.
680
The default implementation may be slow for very tall tables.
682
\sa cellHeight(), totalWidth()
685
int QtTableView::totalHeight()
691
for( int i = 0 ; i < nRows ; i++ )
692
th += cellHeight( i );
699
\fn uint QtTableView::tableFlags() const
701
Returns the union of the table flags that are currently set.
703
\sa setTableFlags(), clearTableFlags(), testTableFlags()
707
\fn bool QtTableView::testTableFlags( uint f ) const
709
Returns TRUE if any of the table flags in \a f are currently set,
712
\sa setTableFlags(), clearTableFlags(), tableFlags()
716
Sets the table flags to \a f.
718
If a flag setting changes the appearance of the table, the table is
719
repainted if - and only if - autoUpdate() is TRUE.
721
The table flags are mostly single bits, though there are some multibit
722
flags for convenience. Here is a complete list:
725
<dt> Tbl_vScrollBar <dd> - The table has a vertical scroll bar.
726
<dt> Tbl_hScrollBar <dd> - The table has a horizontal scroll bar.
727
<dt> Tbl_autoVScrollBar <dd> - The table has a vertical scroll bar if
728
- and only if - the table is taller than the view.
729
<dt> Tbl_autoHScrollBar <dd> The table has a horizontal scroll bar if
730
- and only if - the table is wider than the view.
731
<dt> Tbl_autoScrollBars <dd> - The union of the previous two flags.
732
<dt> Tbl_clipCellPainting <dd> - The table uses QPainter::setClipRect() to
733
make sure that paintCell() will not draw outside the cell
735
<dt> Tbl_cutCellsV <dd> - The table will never show part of a
736
cell at the bottom of the table; if there is not space for all of
737
a cell, the space is left blank.
738
<dt> Tbl_cutCellsH <dd> - The table will never show part of a
739
cell at the right side of the table; if there is not space for all of
740
a cell, the space is left blank.
741
<dt> Tbl_cutCells <dd> - The union of the previous two flags.
742
<dt> Tbl_scrollLastHCell <dd> - When the user scrolls horizontally,
743
let him/her scroll the last cell left until it is at the left
744
edge of the view. If this flag is not set, the user can only scroll
745
to the point where the last cell is completely visible.
746
<dt> Tbl_scrollLastVCell <dd> - When the user scrolls vertically, let
747
him/her scroll the last cell up until it is at the top edge of
748
the view. If this flag is not set, the user can only scroll to the
749
point where the last cell is completely visible.
750
<dt> Tbl_scrollLastCell <dd> - The union of the previous two flags.
751
<dt> Tbl_smoothHScrolling <dd> - The table scrolls as smoothly as
752
possible when the user scrolls horizontally. When this flag is not
753
set, scrolling is done one cell at a time.
754
<dt> Tbl_smoothVScrolling <dd> - The table scrolls as smoothly as
755
possible when scrolling vertically. When this flag is not set,
756
scrolling is done one cell at a time.
757
<dt> Tbl_smoothScrolling <dd> - The union of the previous two flags.
758
<dt> Tbl_snapToHGrid <dd> - Except when the user is actually scrolling,
759
the leftmost column shown snaps to the leftmost edge of the view.
760
<dt> Tbl_snapToVGrid <dd> - Except when the user is actually
761
scrolling, the top row snaps to the top edge of the view.
762
<dt> Tbl_snapToGrid <dd> - The union of the previous two flags.
765
You can specify more than one flag at a time using bitwise OR.
769
setTableFlags( Tbl_smoothScrolling | Tbl_autoScrollBars );
772
\warning The cutCells options (\c Tbl_cutCells, \c Tbl_cutCellsH and
773
Tbl_cutCellsV) may cause painting problems when scrollbars are
774
enabled. Do not combine cutCells and scrollbars.
777
\sa clearTableFlags(), testTableFlags(), tableFlags()
780
void QtTableView::setTableFlags( uint f )
782
f = (f ^ tFlags) & f; // clear flags already set
785
bool updateOn = autoUpdate();
786
setAutoUpdate( FALSE );
788
uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
790
if ( f & Tbl_vScrollBar ) {
791
setVerScrollBar( TRUE );
793
if ( f & Tbl_hScrollBar ) {
794
setHorScrollBar( TRUE );
796
if ( f & Tbl_autoVScrollBar ) {
797
updateScrollBars( verRange );
799
if ( f & Tbl_autoHScrollBar ) {
800
updateScrollBars( horRange );
802
if ( f & Tbl_scrollLastHCell ) {
803
updateScrollBars( horRange );
805
if ( f & Tbl_scrollLastVCell ) {
806
updateScrollBars( verRange );
808
if ( f & Tbl_snapToHGrid ) {
809
updateScrollBars( horRange );
811
if ( f & Tbl_snapToVGrid ) {
812
updateScrollBars( verRange );
814
if ( f & Tbl_snapToGrid ) { // Note: checks for 2 flags
815
if ( (f & Tbl_snapToHGrid) != 0 && xCellDelta != 0 || //have to scroll?
816
(f & Tbl_snapToVGrid) != 0 && yCellDelta != 0 ) {
817
snapToGrid( (f & Tbl_snapToHGrid) != 0, // do snapping
818
(f & Tbl_snapToVGrid) != 0 );
819
repaintMask |= Tbl_snapToGrid; // repaint table
824
setAutoUpdate( TRUE );
826
if ( isVisible() && (f & repaintMask) )
833
Clears the \link setTableFlags() table flags\endlink that are set
836
Example (clears a single flag):
838
clearTableFlags( Tbl_snapToGrid );
841
The default argument clears all flags.
843
\sa setTableFlags(), testTableFlags(), tableFlags()
846
void QtTableView::clearTableFlags( uint f )
848
f = (f ^ ~tFlags) & f; // clear flags that are already 0
851
bool updateOn = autoUpdate();
852
setAutoUpdate( FALSE );
854
uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
856
if ( f & Tbl_vScrollBar ) {
857
setVerScrollBar( FALSE );
859
if ( f & Tbl_hScrollBar ) {
860
setHorScrollBar( FALSE );
862
if ( f & Tbl_scrollLastHCell ) {
863
int maxX = maxXOffset();
864
if ( xOffs > maxX ) {
865
setOffset( maxX, yOffs );
866
repaintMask |= Tbl_scrollLastHCell;
868
updateScrollBars( horRange );
870
if ( f & Tbl_scrollLastVCell ) {
871
int maxY = maxYOffset();
872
if ( yOffs > maxY ) {
873
setOffset( xOffs, maxY );
874
repaintMask |= Tbl_scrollLastVCell;
876
updateScrollBars( verRange );
878
if ( f & Tbl_smoothScrolling ) { // Note: checks for 2 flags
879
if ((f & Tbl_smoothHScrolling) != 0 && xCellDelta != 0 ||//must scroll?
880
(f & Tbl_smoothVScrolling) != 0 && yCellDelta != 0 ) {
881
snapToGrid( (f & Tbl_smoothHScrolling) != 0, // do snapping
882
(f & Tbl_smoothVScrolling) != 0 );
883
repaintMask |= Tbl_smoothScrolling; // repaint table
886
if ( f & Tbl_snapToHGrid ) {
887
updateScrollBars( horRange );
889
if ( f & Tbl_snapToVGrid ) {
890
updateScrollBars( verRange );
893
setAutoUpdate( TRUE );
894
updateScrollBars(); // returns immediately if nothing to do
895
if ( isVisible() && (f & repaintMask) )
903
\fn bool QtTableView::autoUpdate() const
905
Returns TRUE if the view updates itself automatically whenever it
906
is changed in some way.
912
Sets the auto-update option of the table view to \a enable.
914
If \a enable is TRUE (this is the default), the view updates itself
915
automatically whenever it has changed in some way (for example, when a
916
\link setTableFlags() flag\endlink is changed).
918
If \a enable is FALSE, the view does NOT repaint itself or update
919
its internal state variables when it is changed. This can be
920
useful to avoid flicker during large changes and is singularly
921
useless otherwise. Disable auto-update, do the changes, re-enable
922
auto-update and call repaint().
924
\warning Do not leave the view in this state for a long time
925
(i.e., between events). If, for example, the user interacts with the
926
view when auto-update is off, strange things can happen.
928
Setting auto-update to TRUE does not repaint the view; you must call
929
repaint() to do this.
931
\sa autoUpdate(), repaint()
934
void QtTableView::setAutoUpdate( bool enable )
936
if ( isUpdatesEnabled() == enable )
938
setUpdatesEnabled( enable );
940
showOrHideScrollBars();
947
Repaints the cell at row \a row, column \a col if it is inside the view.
949
If \a erase is TRUE, the relevant part of the view is cleared to the
950
background color/pixmap before the contents are repainted.
955
void QtTableView::updateCell( int row, int col, bool erase )
958
if ( !colXPos( col, &xPos ) )
960
if ( !rowYPos( row, &yPos ) )
962
QRect uR = QRect( xPos, yPos,
963
cellW ? cellW : cellWidth(col),
964
cellH ? cellH : cellHeight(row) );
965
repaint( uR.intersect(viewRect()), erase );
970
\fn QRect QtTableView::cellUpdateRect() const
972
This function should be called only from the paintCell() function in
973
subclasses. It returns the portion of a cell that actually needs to be
974
updated in \e cell coordinates. This is useful only for non-trivial
980
Returns the rectangle that is the actual table, excluding any
981
frame, in \e widget coordinates.
984
QRect QtTableView::viewRect() const
986
return QRect( frameWidth(), frameWidth(), viewWidth(), viewHeight() );
991
Returns the index of the last (bottom) row in the view.
992
The index of the first row is 0.
994
If no rows are visible it returns -1. This can happen if the
995
view is too small for the first row and Tbl_cutCellsV is set.
1000
int QtTableView::lastRowVisible() const
1003
int row = findRawRow( maxViewY(), &cellMaxY );
1004
if ( row == -1 || row >= nRows ) { // maxViewY() past end?
1005
row = nRows - 1; // yes: return last row
1007
if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() ) {
1008
if ( row == yCellOffs ) // cut by right margin?
1009
return -1; // yes, nothing in the view
1011
row = row - 1; // cut by margin, one back
1018
Returns the index of the last (right) column in the view.
1019
The index of the first column is 0.
1021
If no columns are visible it returns -1. This can happen if the
1022
view is too narrow for the first column and Tbl_cutCellsH is set.
1024
\sa lastRowVisible()
1027
int QtTableView::lastColVisible() const
1030
int col = findRawCol( maxViewX(), &cellMaxX );
1031
if ( col == -1 || col >= nCols ) { // maxViewX() past end?
1032
col = nCols - 1; // yes: return last col
1034
if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() ) {
1035
if ( col == xCellOffs ) // cut by bottom margin?
1036
return -1; // yes, nothing in the view
1038
col = col - 1; // cell by margin, one back
1045
Returns TRUE if \a row is at least partially visible.
1049
bool QtTableView::rowIsVisible( int row ) const
1051
return rowYPos( row, 0 );
1055
Returns TRUE if \a col is at least partially visible.
1059
bool QtTableView::colIsVisible( int col ) const
1061
return colXPos( col, 0 );
1067
Called when both scroll bars are active at the same time. Covers the
1068
bottom left corner between the two scroll bars with an empty widget.
1071
void QtTableView::coverCornerSquare( bool enable )
1073
coveringCornerSquare = enable;
1074
if ( !cornerSquare && enable ) {
1075
cornerSquare = new QCornerSquare( this );
1076
Q_CHECK_PTR( cornerSquare );
1077
cornerSquare->setGeometry( maxViewX() + frameWidth() + 1,
1078
maxViewY() + frameWidth() + 1,
1082
if ( autoUpdate() && cornerSquare ) {
1084
cornerSquare->show();
1086
cornerSquare->hide();
1093
Scroll the view to a position such that:
1095
If \a horizontal is TRUE, the leftmost column shown fits snugly
1096
with the left edge of the view.
1098
If \a vertical is TRUE, the top row shown fits snugly with the top
1101
You can achieve the same effect automatically by setting any of the
1102
\link setTableFlags() Tbl_snapTo*Grid \endlink table flags.
1105
void QtTableView::snapToGrid( bool horizontal, bool vertical )
1109
if ( horizontal && xCellDelta != 0 ) {
1110
int w = cellW ? cellW : cellWidth( xCellOffs );
1111
if ( xCellDelta >= w/2 )
1112
newXCell = xCellOffs + 1;
1114
newXCell = xCellOffs;
1116
if ( vertical && yCellDelta != 0 ) {
1117
int h = cellH ? cellH : cellHeight( yCellOffs );
1118
if ( yCellDelta >= h/2 )
1119
newYCell = yCellOffs + 1;
1121
newYCell = yCellOffs;
1123
setTopLeftCell( newYCell, newXCell ); //row,column
1128
This internal slot is connected to the horizontal scroll bar's
1129
QScrollBar::valueChanged() signal.
1131
Moves the table horizontally to offset \a val without updating the
1135
void QtTableView::horSbValue( int val )
1139
if ( horSnappingOff ) {
1140
horSnappingOff = FALSE;
1141
tFlags |= Tbl_snapToHGrid;
1144
setOffset( val, yOffs, FALSE );
1149
This internal slot is connected to the horizontal scroll bar's
1150
QScrollBar::sliderMoved() signal.
1152
Scrolls the table smoothly horizontally even if \c Tbl_snapToHGrid is set.
1155
void QtTableView::horSbSliding( int val )
1157
if ( testTableFlags(Tbl_snapToHGrid) &&
1158
testTableFlags(Tbl_smoothHScrolling) ) {
1159
tFlags &= ~Tbl_snapToHGrid; // turn off snapping while sliding
1160
setOffset( val, yOffs, FALSE );
1161
tFlags |= Tbl_snapToHGrid; // turn on snapping again
1163
setOffset( val, yOffs, FALSE );
1169
This internal slot is connected to the horizontal scroll bar's
1170
QScrollBar::sliderReleased() signal.
1173
void QtTableView::horSbSlidingDone( )
1175
if ( testTableFlags(Tbl_snapToHGrid) &&
1176
testTableFlags(Tbl_smoothHScrolling) )
1177
snapToGrid( TRUE, FALSE );
1182
This internal slot is connected to the vertical scroll bar's
1183
QScrollBar::valueChanged() signal.
1185
Moves the table vertically to offset \a val without updating the
1189
void QtTableView::verSbValue( int val )
1193
if ( verSnappingOff ) {
1194
verSnappingOff = FALSE;
1195
tFlags |= Tbl_snapToVGrid;
1198
setOffset( xOffs, val, FALSE );
1203
This internal slot is connected to the vertical scroll bar's
1204
QScrollBar::sliderMoved() signal.
1206
Scrolls the table smoothly vertically even if \c Tbl_snapToVGrid is set.
1209
void QtTableView::verSbSliding( int val )
1211
if ( testTableFlags(Tbl_snapToVGrid) &&
1212
testTableFlags(Tbl_smoothVScrolling) ) {
1213
tFlags &= ~Tbl_snapToVGrid; // turn off snapping while sliding
1214
setOffset( xOffs, val, FALSE );
1215
tFlags |= Tbl_snapToVGrid; // turn on snapping again
1217
setOffset( xOffs, val, FALSE );
1223
This internal slot is connected to the vertical scroll bar's
1224
QScrollBar::sliderReleased() signal.
1227
void QtTableView::verSbSlidingDone( )
1229
if ( testTableFlags(Tbl_snapToVGrid) &&
1230
testTableFlags(Tbl_smoothVScrolling) )
1231
snapToGrid( FALSE, TRUE );
1236
This virtual function is called before painting of table cells
1237
is started. It can be reimplemented by subclasses that want to
1238
to set up the painter in a special way and that do not want to
1239
do so for each cell.
1242
void QtTableView::setupPainter( QPainter * )
1247
\fn void QtTableView::paintCell( QPainter *p, int row, int col )
1249
This pure virtual function is called to paint the single cell at \a
1250
(row,col) using \a p, which is open when paintCell() is called and
1253
The coordinate system is \link QPainter::translate() translated \endlink
1254
so that the origin is at the top-left corner of the cell to be
1255
painted, i.e. \e cell coordinates. Do not scale or shear the coordinate
1256
system (or if you do, restore the transformation matrix before you
1259
The painter is not clipped by default and for maximum efficiency. For safety,
1260
call setTableFlags(Tbl_clipCellPainting) to enable clipping.
1262
\sa paintEvent(), setTableFlags() */
1266
Handles paint events, \a e, for the table view.
1268
Calls paintCell() for the cells that needs to be repainted.
1271
void QtTableView::paintEvent( QPaintEvent *e )
1273
QRect updateR = e->rect(); // update rectangle
1275
bool e = eraseInPaint;
1280
QPainter paint( this );
1282
if ( !contentsRect().contains( updateR, TRUE ) ) {// update frame ?
1283
drawFrame( &paint );
1284
if ( updateR.left() < frameWidth() ) //###
1285
updateR.setLeft( frameWidth() );
1286
if ( updateR.top() < frameWidth() )
1287
updateR.setTop( frameWidth() );
1290
int maxWX = maxViewX();
1291
int maxWY = maxViewY();
1292
if ( updateR.right() > maxWX )
1293
updateR.setRight( maxWX );
1294
if ( updateR.bottom() > maxWY )
1295
updateR.setBottom( maxWY );
1297
setupPainter( &paint ); // prepare for painting table
1299
int firstRow = findRow( updateR.y() );
1300
int firstCol = findCol( updateR.x() );
1302
if ( !colXPos( firstCol, &xStart ) || !rowYPos( firstRow, &yStart ) ) {
1303
paint.eraseRect( updateR ); // erase area outside cells but in view
1306
int maxX = updateR.right();
1307
int maxY = updateR.bottom();
1311
int xPos = maxX+1; // in case the while() is empty
1314
QRect winR = viewRect();
1317
#ifndef QT_NO_TRANSFORMATIONS
1321
while ( yPos <= maxY && row < nRows ) {
1322
nextY = yPos + (cellH ? cellH : cellHeight( row ));
1323
if ( testTableFlags( Tbl_cutCellsV ) && nextY > ( maxWY + 1 ) )
1327
while ( xPos <= maxX && col < nCols ) {
1328
nextX = xPos + (cellW ? cellW : cellWidth( col ));
1329
if ( testTableFlags( Tbl_cutCellsH ) && nextX > ( maxWX + 1 ) )
1332
cellR.setRect( xPos, yPos, cellW ? cellW : cellWidth(col),
1333
cellH ? cellH : cellHeight(row) );
1334
cellUR = cellR.intersect( updateR );
1335
if ( cellUR.isValid() ) {
1336
cellUpdateR = cellUR;
1337
cellUpdateR.moveBy( -xPos, -yPos ); // cell coordinates
1339
paint.eraseRect( cellUR );
1341
#ifndef QT_NO_TRANSFORMATIONS
1342
matrix.translate( xPos, yPos );
1343
paint.setWorldMatrix( matrix );
1344
if ( testTableFlags(Tbl_clipCellPainting) ||
1345
frameWidth() > 0 && !winR.contains( cellR ) ) { //##arnt
1346
paint.setClipRect( cellUR );
1347
paintCell( &paint, row, col );
1348
paint.setClipping( FALSE );
1350
paintCell( &paint, row, col );
1353
paint.setWorldMatrix( matrix );
1355
paint.translate( xPos, yPos );
1356
if ( testTableFlags(Tbl_clipCellPainting) ||
1357
frameWidth() > 0 && !winR.contains( cellR ) ) { //##arnt
1358
paint.setClipRect( cellUR );
1359
paintCell( &paint, row, col );
1360
paint.setClipping( FALSE );
1362
paintCell( &paint, row, col );
1364
paint.translate( -xPos, -yPos );
1374
// while painting we have to erase any areas in the view that
1375
// are not covered by cells but are covered by the paint event
1376
// rectangle these must be erased. We know that xPos is the last
1377
// x pixel updated + 1 and that yPos is the last y pixel updated + 1.
1379
// Note that this needs to be done regardless whether we do
1380
// eraseInPaint or not. Reason: a subclass may implement
1381
// flicker-freeness and encourage the use of repaint(FALSE).
1382
// The subclass, however, cannot draw all pixels, just those
1383
// inside the cells. So QtTableView is reponsible for all pixels
1384
// outside the cells.
1386
QRect viewR = viewRect();
1387
const QColorGroup g = colorGroup();
1389
if ( xPos <= maxX ) {
1392
r.setBottom( yPos<maxY?yPos:maxY );
1393
if ( inherits( "QMultiLineEdit" ) )
1394
paint.fillRect( r.intersect( updateR ), g.base() );
1396
paint.eraseRect( r.intersect( updateR ) );
1398
if ( yPos <= maxY ) {
1401
if ( inherits( "QMultiLineEdit" ) )
1402
paint.fillRect( r.intersect( updateR ), g.base() );
1404
paint.eraseRect( r.intersect( updateR ) );
1410
void QtTableView::resizeEvent( QResizeEvent * )
1412
updateScrollBars( horValue | verValue | horSteps | horGeometry | horRange |
1413
verSteps | verGeometry | verRange );
1414
showOrHideScrollBars();
1416
int maxX = QMIN( xOffs, maxXOffset() ); // ### can be slow
1417
int maxY = QMIN( yOffs, maxYOffset() );
1418
setOffset( maxX, maxY );
1423
Redraws all visible cells in the table view.
1426
void QtTableView::updateView()
1428
repaint( viewRect() );
1432
Returns a pointer to the vertical scroll bar mainly so you can
1433
connect() to its signals. Note that the scroll bar works in pixel
1434
values; use findRow() to translate to cell numbers.
1437
QScrollBar *QtTableView::verticalScrollBar() const
1439
QtTableView *that = (QtTableView*)this; // semantic const
1440
if ( !vScrollBar ) {
1441
QScrollBar *sb = new QScrollBar( QScrollBar::Vertical, that );
1442
#ifndef QT_NO_CURSOR
1443
sb->setCursor( arrowCursor );
1445
sb->resize( sb->sizeHint() ); // height is irrelevant
1447
sb->setTracking( FALSE );
1448
sb->setFocusPolicy( NoFocus );
1449
connect( sb, SIGNAL(valueChanged(int)),
1450
SLOT(verSbValue(int)));
1451
connect( sb, SIGNAL(sliderMoved(int)),
1452
SLOT(verSbSliding(int)));
1453
connect( sb, SIGNAL(sliderReleased()),
1454
SLOT(verSbSlidingDone()));
1456
that->vScrollBar = sb;
1463
Returns a pointer to the horizontal scroll bar mainly so you can
1464
connect() to its signals. Note that the scroll bar works in pixel
1465
values; use findCol() to translate to cell numbers.
1468
QScrollBar *QtTableView::horizontalScrollBar() const
1470
QtTableView *that = (QtTableView*)this; // semantic const
1471
if ( !hScrollBar ) {
1472
QScrollBar *sb = new QScrollBar( QScrollBar::Horizontal, that );
1473
#ifndef QT_NO_CURSOR
1474
sb->setCursor( arrowCursor );
1476
sb->resize( sb->sizeHint() ); // width is irrelevant
1477
sb->setFocusPolicy( NoFocus );
1479
sb->setTracking( FALSE );
1480
connect( sb, SIGNAL(valueChanged(int)),
1481
SLOT(horSbValue(int)));
1482
connect( sb, SIGNAL(sliderMoved(int)),
1483
SLOT(horSbSliding(int)));
1484
connect( sb, SIGNAL(sliderReleased()),
1485
SLOT(horSbSlidingDone()));
1487
that->hScrollBar = sb;
1494
Enables or disables the horizontal scroll bar, as required by
1495
setAutoUpdate() and the \link setTableFlags() table flags\endlink.
1498
void QtTableView::setHorScrollBar( bool on, bool update )
1501
tFlags |= Tbl_hScrollBar;
1502
horizontalScrollBar(); // created
1504
updateScrollBars( horMask | verMask );
1506
sbDirty = sbDirty | (horMask | verMask);
1507
if ( testTableFlags( Tbl_vScrollBar ) )
1508
coverCornerSquare( TRUE );
1510
sbDirty = sbDirty | horMask;
1512
tFlags &= ~Tbl_hScrollBar;
1515
coverCornerSquare( FALSE );
1516
bool hideScrollBar = autoUpdate() && hScrollBar->isVisible();
1517
if ( hideScrollBar )
1520
updateScrollBars( verMask );
1522
sbDirty = sbDirty | verMask;
1523
if ( hideScrollBar && isVisible() )
1524
repaint( hScrollBar->x(), hScrollBar->y(),
1525
width() - hScrollBar->x(), hScrollBar->height() );
1533
Enables or disables the vertical scroll bar, as required by
1534
setAutoUpdate() and the \link setTableFlags() table flags\endlink.
1537
void QtTableView::setVerScrollBar( bool on, bool update )
1540
tFlags |= Tbl_vScrollBar;
1541
verticalScrollBar(); // created
1543
updateScrollBars( verMask | horMask );
1545
sbDirty = sbDirty | (horMask | verMask);
1546
if ( testTableFlags( Tbl_hScrollBar ) )
1547
coverCornerSquare( TRUE );
1549
sbDirty = sbDirty | verMask;
1551
tFlags &= ~Tbl_vScrollBar;
1554
coverCornerSquare( FALSE );
1555
bool hideScrollBar = autoUpdate() && vScrollBar->isVisible();
1556
if ( hideScrollBar )
1559
updateScrollBars( horMask );
1561
sbDirty = sbDirty | horMask;
1562
if ( hideScrollBar && isVisible() )
1563
repaint( vScrollBar->x(), vScrollBar->y(),
1564
vScrollBar->width(), height() - vScrollBar->y() );
1573
int QtTableView::findRawRow( int yPos, int *cellMaxY, int *cellMinY,
1574
bool goOutsideView ) const
1579
if ( goOutsideView || yPos >= minViewY() && yPos <= maxViewY() ) {
1580
if ( yPos < minViewY() ) {
1581
#if defined(QT_CHECK_RANGE)
1582
qWarning( "QtTableView::findRawRow: (%s) internal error: "
1583
"yPos < minViewY() && goOutsideView "
1584
"not supported. (%d,%d)",
1585
name( "unnamed" ), yPos, yOffs );
1589
if ( cellH ) { // uniform cell height
1590
r = (yPos - minViewY() + yCellDelta)/cellH; // cell offs from top
1592
*cellMaxY = (r + 1)*cellH + minViewY() - yCellDelta - 1;
1594
*cellMinY = r*cellH + minViewY() - yCellDelta;
1595
r += yCellOffs; // absolute cell index
1596
} else { // variable cell height
1597
QtTableView *tw = (QtTableView *)this;
1599
int h = minViewY() - yCellDelta; //##arnt3
1601
Q_ASSERT( r < nRows );
1602
while ( r < nRows ) {
1604
h += tw->cellHeight( r ); // Start of next cell
1620
int QtTableView::findRawCol( int xPos, int *cellMaxX, int *cellMinX ,
1621
bool goOutsideView ) const
1626
if ( goOutsideView || xPos >= minViewX() && xPos <= maxViewX() ) {
1627
if ( xPos < minViewX() ) {
1628
#if defined(QT_CHECK_RANGE)
1629
qWarning( "QtTableView::findRawCol: (%s) internal error: "
1630
"xPos < minViewX() && goOutsideView "
1631
"not supported. (%d,%d)",
1632
name( "unnamed" ), xPos, xOffs );
1636
if ( cellW ) { // uniform cell width
1637
c = (xPos - minViewX() + xCellDelta)/cellW; //cell offs from left
1639
*cellMaxX = (c + 1)*cellW + minViewX() - xCellDelta - 1;
1641
*cellMinX = c*cellW + minViewX() - xCellDelta;
1642
c += xCellOffs; // absolute cell index
1643
} else { // variable cell width
1644
QtTableView *tw = (QtTableView *)this;
1646
int w = minViewX() - xCellDelta; //##arnt3
1648
Q_ASSERT( c < nCols );
1649
while ( c < nCols ) {
1651
w += tw->cellWidth( c ); // Start of next cell
1667
Returns the index of the row at position \a yPos, where \a yPos is in
1668
\e widget coordinates. Returns -1 if \a yPos is outside the valid
1671
\sa findCol(), rowYPos()
1674
int QtTableView::findRow( int yPos ) const
1677
int row = findRawRow( yPos, &cellMaxY );
1678
if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() )
1679
row = - 1; // cell cut by bottom margin
1687
Returns the index of the column at position \a xPos, where \a xPos is
1688
in \e widget coordinates. Returns -1 if \a xPos is outside the valid
1691
\sa findRow(), colXPos()
1694
int QtTableView::findCol( int xPos ) const
1697
int col = findRawCol( xPos, &cellMaxX );
1698
if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() )
1699
col = - 1; // cell cut by right margin
1707
Computes the position in the widget of row \a row.
1709
Returns TRUE and stores the result in \a *yPos (in \e widget
1710
coordinates) if the row is visible. Returns FALSE and does not modify
1711
\a *yPos if \a row is invisible or invalid.
1713
\sa colXPos(), findRow()
1716
bool QtTableView::rowYPos( int row, int *yPos ) const
1719
if ( row >= yCellOffs ) {
1721
int lastVisible = lastRowVisible();
1722
if ( row > lastVisible || lastVisible == -1 )
1724
y = (row - yCellOffs)*cellH + minViewY() - yCellDelta;
1727
y = minViewY() - yCellDelta; // y of leftmost cell in view
1729
QtTableView *tw = (QtTableView *)this;
1730
int maxY = maxViewY();
1731
while ( r < row && y <= maxY )
1732
y += tw->cellHeight( r++ );
1747
Computes the position in the widget of column \a col.
1749
Returns TRUE and stores the result in \a *xPos (in \e widget
1750
coordinates) if the column is visible. Returns FALSE and does not
1751
modify \a *xPos if \a col is invisible or invalid.
1753
\sa rowYPos(), findCol()
1756
bool QtTableView::colXPos( int col, int *xPos ) const
1759
if ( col >= xCellOffs ) {
1761
int lastVisible = lastColVisible();
1762
if ( col > lastVisible || lastVisible == -1 )
1764
x = (col - xCellOffs)*cellW + minViewX() - xCellDelta;
1767
x = minViewX() - xCellDelta; // x of uppermost cell in view
1769
QtTableView *tw = (QtTableView *)this;
1770
int maxX = maxViewX();
1771
while ( c < col && x <= maxX )
1772
x += tw->cellWidth( c++ );
1786
Moves the visible area of the table right by \a xPixels and
1787
down by \a yPixels pixels. Both may be negative.
1789
\warning You might find that QScrollView offers a higher-level of
1790
functionality than using QtTableView and this function.
1792
This function is \e not the same as QWidget::scroll(); in particular,
1793
the signs of \a xPixels and \a yPixels have the reverse semantics.
1795
\sa setXOffset(), setYOffset(), setOffset(), setTopCell(),
1799
void QtTableView::scroll( int xPixels, int yPixels )
1801
QWidget::scroll( -xPixels, -yPixels, contentsRect() );
1806
Returns the leftmost pixel of the table view in \e view
1807
coordinates. This excludes the frame and any header.
1809
\sa maxViewY(), viewWidth(), contentsRect()
1812
int QtTableView::minViewX() const
1814
return frameWidth();
1819
Returns the top pixel of the table view in \e view
1820
coordinates. This excludes the frame and any header.
1822
\sa maxViewX(), viewHeight(), contentsRect()
1825
int QtTableView::minViewY() const
1827
return frameWidth();
1832
Returns the rightmost pixel of the table view in \e view
1833
coordinates. This excludes the frame and any scroll bar, but
1834
includes blank pixels to the right of the visible table data.
1836
\sa maxViewY(), viewWidth(), contentsRect()
1839
int QtTableView::maxViewX() const
1841
return width() - 1 - frameWidth()
1842
- (tFlags & Tbl_vScrollBar ? VSBEXT
1848
Returns the bottom pixel of the table view in \e view
1849
coordinates. This excludes the frame and any scroll bar, but
1850
includes blank pixels below the visible table data.
1852
\sa maxViewX(), viewHeight(), contentsRect()
1855
int QtTableView::maxViewY() const
1857
return height() - 1 - frameWidth()
1858
- (tFlags & Tbl_hScrollBar ? HSBEXT
1864
Returns the width of the table view, as such, in \e view
1865
coordinates. This does not include any header, scroll bar or frame,
1866
but it does include background pixels to the right of the table data.
1868
\sa minViewX() maxViewX(), viewHeight(), contentsRect() viewRect()
1871
int QtTableView::viewWidth() const
1873
return maxViewX() - minViewX() + 1;
1878
Returns the height of the table view, as such, in \e view
1879
coordinates. This does not include any header, scroll bar or frame,
1880
but it does include background pixels below the table data.
1882
\sa minViewY() maxViewY() viewWidth() contentsRect() viewRect()
1885
int QtTableView::viewHeight() const
1887
return maxViewY() - minViewY() + 1;
1891
void QtTableView::doAutoScrollBars()
1893
int viewW = width() - frameWidth() - minViewX();
1894
int viewH = height() - frameWidth() - minViewY();
1895
bool vScrollOn = testTableFlags(Tbl_vScrollBar);
1896
bool hScrollOn = testTableFlags(Tbl_hScrollBar);
1901
if ( testTableFlags(Tbl_autoHScrollBar) ) {
1906
while ( i < nCols && w <= viewW )
1907
w += cellWidth( i++ );
1915
if ( testTableFlags(Tbl_autoVScrollBar) ) {
1920
while ( i < nRows && h <= viewH )
1921
h += cellHeight( i++ );
1930
if ( testTableFlags(Tbl_autoHScrollBar) && vScrollOn && !hScrollOn )
1931
if ( w > viewW - VSBEXT )
1934
if ( testTableFlags(Tbl_autoVScrollBar) && hScrollOn && !vScrollOn )
1935
if ( h > viewH - HSBEXT )
1938
setHorScrollBar( hScrollOn, FALSE );
1939
setVerScrollBar( vScrollOn, FALSE );
1945
\fn void QtTableView::updateScrollBars()
1947
Updates the scroll bars' contents and presence to match the table's
1948
state. Generally, you should not need to call this.
1954
Updates the scroll bars' contents and presence to match the table's
1960
void QtTableView::updateScrollBars( uint f )
1962
sbDirty = sbDirty | f;
1967
if ( testTableFlags(Tbl_autoHScrollBar) && (sbDirty & horRange) ||
1968
testTableFlags(Tbl_autoVScrollBar) && (sbDirty & verRange) )
1969
// if range change and auto
1970
doAutoScrollBars(); // turn scroll bars on/off if needed
1972
if ( !autoUpdate() ) {
1976
if ( yOffset() > 0 && testTableFlags( Tbl_autoVScrollBar ) &&
1977
!testTableFlags( Tbl_vScrollBar ) ) {
1980
if ( xOffset() > 0 && testTableFlags( Tbl_autoHScrollBar ) &&
1981
!testTableFlags( Tbl_hScrollBar ) ) {
1984
if ( !isVisible() ) {
1989
if ( testTableFlags(Tbl_hScrollBar) && (sbDirty & horMask) != 0 ) {
1990
if ( sbDirty & horGeometry )
1991
hScrollBar->setGeometry( 0,height() - HSBEXT,
1992
viewWidth() + frameWidth()*2,
1995
if ( sbDirty & horSteps ) {
1997
hScrollBar->setSteps( QMIN(cellW,viewWidth()/2), viewWidth() );
1999
hScrollBar->setSteps( 16, viewWidth() );
2002
if ( sbDirty & horRange )
2003
hScrollBar->setRange( 0, maxXOffset() );
2005
if ( sbDirty & horValue )
2006
hScrollBar->setValue( xOffs );
2008
// show scrollbar only when it has a sane geometry
2009
if ( !hScrollBar->isVisible() )
2013
if ( testTableFlags(Tbl_vScrollBar) && (sbDirty & verMask) != 0 ) {
2014
if ( sbDirty & verGeometry )
2015
vScrollBar->setGeometry( width() - VSBEXT, 0,
2017
viewHeight() + frameWidth()*2 );
2019
if ( sbDirty & verSteps ) {
2021
vScrollBar->setSteps( QMIN(cellH,viewHeight()/2), viewHeight() );
2023
vScrollBar->setSteps( 16, viewHeight() ); // fttb! ###
2026
if ( sbDirty & verRange )
2027
vScrollBar->setRange( 0, maxYOffset() );
2029
if ( sbDirty & verValue )
2030
vScrollBar->setValue( yOffs );
2032
// show scrollbar only when it has a sane geometry
2033
if ( !vScrollBar->isVisible() )
2036
if ( coveringCornerSquare &&
2037
( (sbDirty & verGeometry ) || (sbDirty & horGeometry)) )
2038
cornerSquare->move( maxViewX() + frameWidth() + 1,
2039
maxViewY() + frameWidth() + 1 );
2046
void QtTableView::updateFrameSize()
2048
int rw = width() - ( testTableFlags(Tbl_vScrollBar) ?
2050
int rh = height() - ( testTableFlags(Tbl_hScrollBar) ?
2057
if ( autoUpdate() ) {
2058
int fh = frameRect().height();
2059
int fw = frameRect().width();
2060
setFrameRect( QRect(0,0,rw,rh) );
2063
update( QMIN(fw,rw) - frameWidth() - 2, 0, frameWidth()+4, rh );
2065
update( 0, QMIN(fh,rh) - frameWidth() - 2, rw, frameWidth()+4 );
2071
Returns the maximum horizontal offset within the table of the
2072
view's left edge in \e table coordinates.
2074
This is used mainly to set the horizontal scroll bar's range.
2076
\sa maxColOffset(), maxYOffset(), totalWidth()
2079
int QtTableView::maxXOffset()
2081
int tw = totalWidth();
2083
if ( testTableFlags(Tbl_scrollLastHCell) ) {
2085
maxOffs = tw - ( cellW ? cellW : cellWidth( nCols - 1 ) );
2087
maxOffs = tw - viewWidth();
2089
if ( testTableFlags(Tbl_snapToHGrid) ) {
2091
maxOffs = tw - (viewWidth()/cellW)*cellW;
2093
int goal = tw - viewWidth();
2095
int nextCol = nCols - 1;
2096
int nextCellWidth = cellWidth( nextCol );
2097
while( nextCol > 0 && pos > goal + nextCellWidth ) {
2098
pos -= nextCellWidth;
2099
nextCellWidth = cellWidth( --nextCol );
2101
if ( goal + nextCellWidth == pos )
2103
else if ( goal < pos )
2109
maxOffs = tw - viewWidth();
2112
return maxOffs > 0 ? maxOffs : 0;
2117
Returns the maximum vertical offset within the table of the
2118
view's top edge in \e table coordinates.
2120
This is used mainly to set the vertical scroll bar's range.
2122
\sa maxRowOffset(), maxXOffset(), totalHeight()
2125
int QtTableView::maxYOffset()
2127
int th = totalHeight();
2129
if ( testTableFlags(Tbl_scrollLastVCell) ) {
2131
maxOffs = th - ( cellH ? cellH : cellHeight( nRows - 1 ) );
2133
maxOffs = th - viewHeight();
2135
if ( testTableFlags(Tbl_snapToVGrid) ) {
2137
maxOffs = th - (viewHeight()/cellH)*cellH;
2139
int goal = th - viewHeight();
2141
int nextRow = nRows - 1;
2142
int nextCellHeight = cellHeight( nextRow );
2143
while( nextRow > 0 && pos > goal + nextCellHeight ) {
2144
pos -= nextCellHeight;
2145
nextCellHeight = cellHeight( --nextRow );
2147
if ( goal + nextCellHeight == pos )
2149
else if ( goal < pos )
2155
maxOffs = th - viewHeight();
2158
return maxOffs > 0 ? maxOffs : 0;
2163
Returns the index of the last column, which may be at the left edge
2166
Depending on the \link setTableFlags() Tbl_scrollLastHCell\endlink flag,
2167
this may or may not be the last column.
2169
\sa maxXOffset(), maxRowOffset()
2172
int QtTableView::maxColOffset()
2174
int mx = maxXOffset();
2179
while ( col < nCols && mx > (xcd=cellWidth(col)) ) {
2189
Returns the index of the last row, which may be at the top edge of
2192
Depending on the \link setTableFlags() Tbl_scrollLastVCell\endlink flag,
2193
this may or may not be the last row.
2195
\sa maxYOffset(), maxColOffset()
2198
int QtTableView::maxRowOffset()
2200
int my = maxYOffset();
2205
while ( row < nRows && my > (ycd=cellHeight(row)) ) {
2214
void QtTableView::showOrHideScrollBars()
2216
if ( !autoUpdate() )
2219
if ( testTableFlags(Tbl_vScrollBar) ) {
2220
if ( !vScrollBar->isVisible() )
2221
sbDirty = sbDirty | verMask;
2223
if ( vScrollBar->isVisible() )
2228
if ( testTableFlags(Tbl_hScrollBar) ) {
2229
if ( !hScrollBar->isVisible() )
2230
sbDirty = sbDirty | horMask;
2232
if ( hScrollBar->isVisible() )
2236
if ( cornerSquare ) {
2237
if ( testTableFlags(Tbl_hScrollBar) &&
2238
testTableFlags(Tbl_vScrollBar) ) {
2239
if ( !cornerSquare->isVisible() )
2240
cornerSquare->show();
2242
if ( cornerSquare->isVisible() )
2243
cornerSquare->hide();
2250
Updates the scroll bars and internal state.
2252
Call this function when the table view's total size is changed;
2253
typically because the result of cellHeight() or cellWidth() have changed.
2255
This function does not repaint the widget.
2258
void QtTableView::updateTableSize()
2260
bool updateOn = autoUpdate();
2261
setAutoUpdate( FALSE );
2262
int xofs = xOffset();
2263
xOffs++; //so that setOffset will not return immediately
2264
setOffset(xofs,yOffset(),FALSE); //to calculate internal state correctly
2265
setAutoUpdate(updateOn);
2267
updateScrollBars( horSteps | horRange |
2268
verSteps | verRange );
2269
showOrHideScrollBars();