1
/**********************************************************************
2
** $Id: qttableview.cpp,v 1.2 2001/10/27 14:51:47 mlaurent Exp $
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
#include "qttableview.moc"
17
#ifndef QT_NO_QTTABLEVIEW
18
#include "qscrollbar.h"
20
#include "qdrawutil.h"
23
enum ScrollBarDirtyFlags {
37
#define HSBEXT horizontalScrollBar()->sizeHint().height()
38
#define VSBEXT verticalScrollBar()->sizeHint().width()
41
class QCornerSquare : public QWidget // internal class
44
QCornerSquare( QWidget *, const char* = 0 );
45
void paintEvent( QPaintEvent * );
48
QCornerSquare::QCornerSquare( QWidget *parent, const char *name )
49
: QWidget( parent, name )
53
void QCornerSquare::paintEvent( QPaintEvent * )
60
\class QtTableView qttableview.h
61
\brief The QtTableView class provides an abstract base for tables.
65
A table view consists of a number of abstract cells organized in rows
66
and columns, and a visible part called a view. The cells are identified
67
with a row index and a column index. The top-left cell is in row 0,
70
The behavior of the widget can be finely tuned using
71
setTableFlags(); a typical subclass will consist of little more than a
72
call to setTableFlags(), some table content manipulation and an
73
implementation of paintCell(). Subclasses that need cells with
74
variable width or height must reimplement cellHeight() and/or
75
cellWidth(). Use updateTableSize() to tell QtTableView when the
76
width or height has changed.
78
When you read this documentation, it is important to understand the
79
distinctions among the four pixel coordinate systems involved.
82
\i The \e cell coordinates. (0,0) is the top-left corner of a cell.
83
Cell coordinates are used by functions such as paintCell().
85
\i The \e table coordinates. (0,0) is the top-left corner of the cell at
86
row 0 and column 0. These coordinates are absolute; that is, they are
87
independent of what part of the table is visible at the moment. They are
88
used by functions such as setXOffset() or maxYOffset().
90
\i The \e widget coordinates. (0,0) is the top-left corner of the widget,
91
\e including the frame. They are used by functions such as repaint().
93
\i The \e view coordinates. (0,0) is the top-left corner of the view, \e
94
excluding the frame. This is the least-used coordinate system; it is used by
95
functions such as viewWidth(). \endlist
97
It is rather unfortunate that we have to use four different
98
coordinate systems, but there was no alternative to provide a flexible and
101
Note: The row,column indices are always given in that order,
102
i.e., first the vertical (row), then the horizontal (column). This is
103
the opposite order of all pixel operations, which take first the
104
horizontal (x) and then the vertical (y).
106
<img src=qtablevw-m.png> <img src=qtablevw-w.png>
108
\warning the functions setNumRows(), setNumCols(), setCellHeight(),
109
setCellWidth(), setTableFlags() and clearTableFlags() may cause
110
virtual functions such as cellWidth() and cellHeight() to be called,
111
even if autoUpdate() is FALSE. This may cause errors if relevant
112
state variables are not initialized.
114
\warning Experience has shown that use of this widget tends to cause
115
more bugs than expected and our analysis indicates that the widget's
116
very flexibility is the problem. If QScrollView or QListBox can
117
easily be made to do the job you need, we recommend subclassing
118
those widgets rather than QtTableView. In addition, QScrollView makes
119
it easy to have child widgets inside tables, which QtTableView
120
doesn't support at all.
123
\link guibooks.html#fowler GUI Design Handbook: Table\endlink
128
Constructs a table view. The \a parent, \a name and \f arguments
129
are passed to the QFrame constructor.
131
The \link setTableFlags() table flags\endlink are all cleared (set to 0).
132
Set \c Tbl_autoVScrollBar or \c Tbl_autoHScrollBar to get automatic scroll
133
bars and \c Tbl_clipCellPainting to get safe clipping.
135
The \link setCellHeight() cell height\endlink and \link setCellWidth()
136
cell width\endlink are set to 0.
138
Frame line shapes (QFrame::HLink and QFrame::VLine) are disallowed;
139
see QFrame::setFrameStyle().
141
Note that the \a f argument is \e not \link setTableFlags() table
142
flags \endlink but rather \link QWidget::QWidget() widget
147
QtTableView::QtTableView( QWidget *parent, const char *name, WFlags f )
148
: QFrame( parent, name, f )
150
nRows = nCols = 0; // zero rows/cols
151
xCellOffs = yCellOffs = 0; // zero offset
152
xCellDelta = yCellDelta = 0; // zero cell offset
153
xOffs = yOffs = 0; // zero total pixel offset
154
cellH = cellW = 0; // user defined cell size
156
vScrollBar = hScrollBar = 0; // no scroll bars
159
eraseInPaint = FALSE;
161
verSnappingOff = FALSE;
163
horSnappingOff = FALSE;
164
coveringCornerSquare = FALSE;
169
Destroys the table view.
172
QtTableView::~QtTableView()
182
Reimplements QWidget::setBackgroundColor() for binary compatibility.
186
void QtTableView::setBackgroundColor( const QColor &c )
188
QWidget::setBackgroundColor( c );
194
void QtTableView::setPalette( const QPalette &p )
196
QWidget::setPalette( p );
202
void QtTableView::show()
204
showOrHideScrollBars();
210
\overload void QtTableView::repaint( bool erase )
211
Repaints the entire view.
215
Repaints the table view directly by calling paintEvent() directly
216
unless updates are disabled.
218
Erases the view area \a (x,y,w,h) if \a erase is TRUE. Parameters \a
219
(x,y) are in \e widget coordinates.
221
If \a w is negative, it is replaced with <code>width() - x</code>.
222
If \a h is negative, it is replaced with <code>height() - y</code>.
224
Doing a repaint() usually is faster than doing an update(), but
225
calling update() many times in a row will generate a single paint
228
At present, QtTableView is the only widget that reimplements \link
229
QWidget::repaint() repaint()\endlink. It does this because by
230
clearing and then repainting one cell at at time, it can make the
231
screen flicker less than it would otherwise. */
233
void QtTableView::repaint( int x, int y, int w, int h, bool erase )
235
if ( !isVisible() || testWState(WState_BlockUpdates) )
241
QRect r( x, y, w, h );
243
return; // nothing to do
245
if ( erase && backgroundMode() != NoBackground )
246
eraseInPaint = TRUE; // erase when painting
248
eraseInPaint = FALSE;
252
\overload void QtTableView::repaint( const QRect &r, bool erase )
253
Replaints rectangle \a r. If \a erase is TRUE draws the background
254
using the palette's background.
259
\fn int QtTableView::numRows() const
260
Returns the number of rows in the table.
261
\sa numCols(), setNumRows()
265
Sets the number of rows of the table to \a rows (must be non-negative).
266
Does not change topCell().
268
The table repaints itself automatically if autoUpdate() is set.
270
\sa numCols(), setNumCols(), numRows()
273
void QtTableView::setNumRows( int rows )
276
#if defined(QT_CHECK_RANGE)
277
qWarning( "QtTableView::setNumRows: (%s) Negative argument %d.",
278
name( "unnamed" ), rows );
285
if ( autoUpdate() && isVisible() ) {
286
int oldLastVisible = lastRowVisible();
287
int oldTopCell = topCell();
289
if ( autoUpdate() && isVisible() &&
290
( oldLastVisible != lastRowVisible() || oldTopCell != topCell() ) )
291
repaint( oldTopCell != topCell() );
293
// Be more careful - if destructing, bad things might happen.
296
updateScrollBars( verRange );
301
\fn int QtTableView::numCols() const
302
Returns the number of columns in the table.
303
\sa numRows(), setNumCols()
307
Sets the number of columns of the table to \a cols (must be non-negative).
308
Does not change leftCell().
310
The table repaints itself automatically if autoUpdate() is set.
312
\sa numCols(), numRows(), setNumRows()
315
void QtTableView::setNumCols( int cols )
318
#if defined(QT_CHECK_RANGE)
319
qWarning( "QtTableView::setNumCols: (%s) Negative argument %d.",
320
name( "unnamed" ), cols );
328
if ( autoUpdate() && isVisible() ) {
329
int maxCol = lastColVisible();
330
if ( maxCol >= oldCols || maxCol >= nCols )
333
updateScrollBars( horRange );
339
\fn int QtTableView::topCell() const
340
Returns the index of the first row in the table that is visible in
341
the view. The index of the first row is 0.
342
\sa leftCell(), setTopCell()
346
Scrolls the table so that \a row becomes the top row.
347
The index of the very first row is 0.
348
\sa setYOffset(), setTopLeftCell(), setLeftCell()
351
void QtTableView::setTopCell( int row )
353
setTopLeftCell( row, -1 );
358
\fn int QtTableView::leftCell() const
359
Returns the index of the first column in the table that is visible in
360
the view. The index of the very leftmost column is 0.
361
\sa topCell(), setLeftCell()
365
Scrolls the table so that \a col becomes the leftmost
366
column. The index of the leftmost column is 0.
367
\sa setXOffset(), setTopLeftCell(), setTopCell()
370
void QtTableView::setLeftCell( int col )
372
setTopLeftCell( -1, col );
377
Scrolls the table so that the cell at row \a row and colum \a
378
col becomes the top-left cell in the view. The cell at the extreme
379
top left of the table is at position (0,0).
380
\sa setLeftCell(), setTopCell(), setOffset()
383
void QtTableView::setTopLeftCell( int row, int col )
391
if ( newX > maxXOffset() )
396
newX += cellWidth( --col ); // optimize using current! ###
402
if ( newY > maxYOffset() )
407
newY += cellHeight( --row ); // optimize using current! ###
410
setOffset( newX, newY );
415
\fn int QtTableView::xOffset() const
417
Returns the x coordinate in \e table coordinates of the pixel that is
418
currently on the left edge of the view.
420
\sa setXOffset(), yOffset(), leftCell() */
423
Scrolls the table so that \a x becomes the leftmost pixel in the view.
424
The \a x parameter is in \e table coordinates.
426
The interaction with \link setTableFlags() Tbl_snapToHGrid
429
\sa xOffset(), setYOffset(), setOffset(), setLeftCell()
432
void QtTableView::setXOffset( int x )
434
setOffset( x, yOffset() );
438
\fn int QtTableView::yOffset() const
440
Returns the y coordinate in \e table coordinates of the pixel that is
441
currently on the top edge of the view.
443
\sa setYOffset(), xOffset(), topCell()
448
Scrolls the table so that \a y becomes the top pixel in the view.
449
The \a y parameter is in \e table coordinates.
451
The interaction with \link setTableFlags() Tbl_snapToVGrid
454
\sa yOffset(), setXOffset(), setOffset(), setTopCell()
457
void QtTableView::setYOffset( int y )
459
setOffset( xOffset(), y );
463
Scrolls the table so that \a (x,y) becomes the top-left pixel
464
in the view. Parameters \a (x,y) are in \e table coordinates.
466
The interaction with \link setTableFlags() Tbl_snapTo*Grid \endlink
467
is tricky. If \a updateScrBars is TRUE, the scroll bars are
470
\sa xOffset(), yOffset(), setXOffset(), setYOffset(), setTopLeftCell()
473
void QtTableView::setOffset( int x, int y, bool updateScrBars )
475
if ( (!testTableFlags(Tbl_snapToHGrid) || xCellDelta == 0) &&
476
(!testTableFlags(Tbl_snapToVGrid) || yCellDelta == 0) &&
477
(x == xOffs && y == yOffs) )
486
if ( x > maxXOffset() )
488
xCellOffs = x / cellW;
489
if ( !testTableFlags(Tbl_snapToHGrid) ) {
490
xCellDelta = (short)(x % cellW);
496
int xn=0, xcd=0, col = 0;
497
while ( col < nCols-1 && x >= xn+(xcd=cellWidth(col)) ) {
502
if ( testTableFlags(Tbl_snapToHGrid) ) {
506
xCellDelta = (short)(x-xn);
510
if ( y > maxYOffset() )
512
yCellOffs = y / cellH;
513
if ( !testTableFlags(Tbl_snapToVGrid) ) {
514
yCellDelta = (short)(y % cellH);
520
int yn=0, yrd=0, row=0;
521
while ( row < nRows-1 && y >= yn+(yrd=cellHeight(row)) ) {
526
if ( testTableFlags(Tbl_snapToVGrid) ) {
530
yCellDelta = (short)(y-yn);
533
int dx = (x - xOffs);
534
int dy = (y - yOffs);
537
if ( autoUpdate() && isVisible() )
540
updateScrollBars( verValue | horValue );
545
\overload int QtTableView::cellWidth() const
547
Returns the column width in pixels. Returns 0 if the columns have
550
\sa setCellWidth(), cellHeight()
554
Returns the width of column \a col in pixels.
556
This function is virtual and must be reimplemented by subclasses that
557
have variable cell widths. Note that if the total table width
558
changes, updateTableSize() must be called.
560
\sa setCellWidth(), cellHeight(), totalWidth(), updateTableSize()
563
int QtTableView::cellWidth( int )
570
Sets the width in pixels of the table cells to \a cellWidth.
572
Setting it to 0 means that the column width is variable. When
573
set to 0 (this is the default) QtTableView calls the virtual function
574
cellWidth() to get the width.
576
\sa cellWidth(), setCellHeight(), totalWidth(), numCols()
579
void QtTableView::setCellWidth( int cellWidth )
581
if ( cellW == cellWidth )
583
#if defined(QT_CHECK_RANGE)
584
if ( cellWidth < 0 || cellWidth > SHRT_MAX ) {
585
qWarning( "QtTableView::setCellWidth: (%s) Argument out of range (%d)",
586
name( "unnamed" ), cellWidth );
590
cellW = (short)cellWidth;
592
updateScrollBars( horSteps | horRange );
593
if ( autoUpdate() && isVisible() )
599
\overload int QtTableView::cellHeight() const
601
Returns the row height, in pixels. Returns 0 if the rows have
604
\sa setCellHeight(), cellWidth()
609
Returns the height of row \a row in pixels.
611
This function is virtual and must be reimplemented by subclasses that
612
have variable cell heights. Note that if the total table height
613
changes, updateTableSize() must be called.
615
\sa setCellHeight(), cellWidth(), totalHeight()
618
int QtTableView::cellHeight( int )
624
Sets the height in pixels of the table cells to \a cellHeight.
626
Setting it to 0 means that the row height is variable. When set
627
to 0 (this is the default), QtTableView calls the virtual function
628
cellHeight() to get the height.
630
\sa cellHeight(), setCellWidth(), totalHeight(), numRows()
633
void QtTableView::setCellHeight( int cellHeight )
635
if ( cellH == cellHeight )
637
#if defined(QT_CHECK_RANGE)
638
if ( cellHeight < 0 || cellHeight > SHRT_MAX ) {
639
qWarning( "QtTableView::setCellHeight: (%s) Argument out of range (%d)",
640
name( "unnamed" ), cellHeight );
644
cellH = (short)cellHeight;
645
if ( autoUpdate() && isVisible() )
647
updateScrollBars( verSteps | verRange );
652
Returns the total width of the table in pixels.
654
This function is virtual and should be reimplemented by subclasses that
655
have variable cell widths and a non-trivial cellWidth() function, or a
656
large number of columns in the table.
658
The default implementation may be slow for very wide tables.
660
\sa cellWidth(), totalHeight() */
662
int QtTableView::totalWidth()
668
for( int i = 0 ; i < nCols ; i++ )
669
tw += cellWidth( i );
675
Returns the total height of the table in pixels.
677
This function is virtual and should be reimplemented by subclasses that
678
have variable cell heights and a non-trivial cellHeight() function, or a
679
large number of rows in the table.
681
The default implementation may be slow for very tall tables.
683
\sa cellHeight(), totalWidth()
686
int QtTableView::totalHeight()
692
for( int i = 0 ; i < nRows ; i++ )
693
th += cellHeight( i );
700
\fn uint QtTableView::tableFlags() const
702
Returns the union of the table flags that are currently set.
704
\sa setTableFlags(), clearTableFlags(), testTableFlags()
708
\fn bool QtTableView::testTableFlags( uint f ) const
710
Returns TRUE if any of the table flags in \a f are currently set,
713
\sa setTableFlags(), clearTableFlags(), tableFlags()
717
Sets the table flags to \a f.
719
If a flag setting changes the appearance of the table, the table is
720
repainted if - and only if - autoUpdate() is TRUE.
722
The table flags are mostly single bits, though there are some multibit
723
flags for convenience. Here is a complete list:
726
<dt> Tbl_vScrollBar <dd> - The table has a vertical scroll bar.
727
<dt> Tbl_hScrollBar <dd> - The table has a horizontal scroll bar.
728
<dt> Tbl_autoVScrollBar <dd> - The table has a vertical scroll bar if
729
- and only if - the table is taller than the view.
730
<dt> Tbl_autoHScrollBar <dd> The table has a horizontal scroll bar if
731
- and only if - the table is wider than the view.
732
<dt> Tbl_autoScrollBars <dd> - The union of the previous two flags.
733
<dt> Tbl_clipCellPainting <dd> - The table uses QPainter::setClipRect() to
734
make sure that paintCell() will not draw outside the cell
736
<dt> Tbl_cutCellsV <dd> - The table will never show part of a
737
cell at the bottom of the table; if there is not space for all of
738
a cell, the space is left blank.
739
<dt> Tbl_cutCellsH <dd> - The table will never show part of a
740
cell at the right side of the table; if there is not space for all of
741
a cell, the space is left blank.
742
<dt> Tbl_cutCells <dd> - The union of the previous two flags.
743
<dt> Tbl_scrollLastHCell <dd> - When the user scrolls horizontally,
744
let him/her scroll the last cell left until it is at the left
745
edge of the view. If this flag is not set, the user can only scroll
746
to the point where the last cell is completely visible.
747
<dt> Tbl_scrollLastVCell <dd> - When the user scrolls vertically, let
748
him/her scroll the last cell up until it is at the top edge of
749
the view. If this flag is not set, the user can only scroll to the
750
point where the last cell is completely visible.
751
<dt> Tbl_scrollLastCell <dd> - The union of the previous two flags.
752
<dt> Tbl_smoothHScrolling <dd> - The table scrolls as smoothly as
753
possible when the user scrolls horizontally. When this flag is not
754
set, scrolling is done one cell at a time.
755
<dt> Tbl_smoothVScrolling <dd> - The table scrolls as smoothly as
756
possible when scrolling vertically. When this flag is not set,
757
scrolling is done one cell at a time.
758
<dt> Tbl_smoothScrolling <dd> - The union of the previous two flags.
759
<dt> Tbl_snapToHGrid <dd> - Except when the user is actually scrolling,
760
the leftmost column shown snaps to the leftmost edge of the view.
761
<dt> Tbl_snapToVGrid <dd> - Except when the user is actually
762
scrolling, the top row snaps to the top edge of the view.
763
<dt> Tbl_snapToGrid <dd> - The union of the previous two flags.
766
You can specify more than one flag at a time using bitwise OR.
770
setTableFlags( Tbl_smoothScrolling | Tbl_autoScrollBars );
773
\warning The cutCells options (\c Tbl_cutCells, \c Tbl_cutCellsH and
774
Tbl_cutCellsV) may cause painting problems when scrollbars are
775
enabled. Do not combine cutCells and scrollbars.
778
\sa clearTableFlags(), testTableFlags(), tableFlags()
781
void QtTableView::setTableFlags( uint f )
783
f = (f ^ tFlags) & f; // clear flags already set
786
bool updateOn = autoUpdate();
787
setAutoUpdate( FALSE );
789
uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
791
if ( f & Tbl_vScrollBar ) {
792
setVerScrollBar( TRUE );
794
if ( f & Tbl_hScrollBar ) {
795
setHorScrollBar( TRUE );
797
if ( f & Tbl_autoVScrollBar ) {
798
updateScrollBars( verRange );
800
if ( f & Tbl_autoHScrollBar ) {
801
updateScrollBars( horRange );
803
if ( f & Tbl_scrollLastHCell ) {
804
updateScrollBars( horRange );
806
if ( f & Tbl_scrollLastVCell ) {
807
updateScrollBars( verRange );
809
if ( f & Tbl_snapToHGrid ) {
810
updateScrollBars( horRange );
812
if ( f & Tbl_snapToVGrid ) {
813
updateScrollBars( verRange );
815
if ( f & Tbl_snapToGrid ) { // Note: checks for 2 flags
816
if ( (f & Tbl_snapToHGrid) != 0 && xCellDelta != 0 || //have to scroll?
817
(f & Tbl_snapToVGrid) != 0 && yCellDelta != 0 ) {
818
snapToGrid( (f & Tbl_snapToHGrid) != 0, // do snapping
819
(f & Tbl_snapToVGrid) != 0 );
820
repaintMask |= Tbl_snapToGrid; // repaint table
825
setAutoUpdate( TRUE );
827
if ( isVisible() && (f & repaintMask) )
834
Clears the \link setTableFlags() table flags\endlink that are set
837
Example (clears a single flag):
839
clearTableFlags( Tbl_snapToGrid );
842
The default argument clears all flags.
844
\sa setTableFlags(), testTableFlags(), tableFlags()
847
void QtTableView::clearTableFlags( uint f )
849
f = (f ^ ~tFlags) & f; // clear flags that are already 0
852
bool updateOn = autoUpdate();
853
setAutoUpdate( FALSE );
855
uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
857
if ( f & Tbl_vScrollBar ) {
858
setVerScrollBar( FALSE );
860
if ( f & Tbl_hScrollBar ) {
861
setHorScrollBar( FALSE );
863
if ( f & Tbl_scrollLastHCell ) {
864
int maxX = maxXOffset();
865
if ( xOffs > maxX ) {
866
setOffset( maxX, yOffs );
867
repaintMask |= Tbl_scrollLastHCell;
869
updateScrollBars( horRange );
871
if ( f & Tbl_scrollLastVCell ) {
872
int maxY = maxYOffset();
873
if ( yOffs > maxY ) {
874
setOffset( xOffs, maxY );
875
repaintMask |= Tbl_scrollLastVCell;
877
updateScrollBars( verRange );
879
if ( f & Tbl_smoothScrolling ) { // Note: checks for 2 flags
880
if ((f & Tbl_smoothHScrolling) != 0 && xCellDelta != 0 ||//must scroll?
881
(f & Tbl_smoothVScrolling) != 0 && yCellDelta != 0 ) {
882
snapToGrid( (f & Tbl_smoothHScrolling) != 0, // do snapping
883
(f & Tbl_smoothVScrolling) != 0 );
884
repaintMask |= Tbl_smoothScrolling; // repaint table
887
if ( f & Tbl_snapToHGrid ) {
888
updateScrollBars( horRange );
890
if ( f & Tbl_snapToVGrid ) {
891
updateScrollBars( verRange );
894
setAutoUpdate( TRUE );
895
updateScrollBars(); // returns immediately if nothing to do
896
if ( isVisible() && (f & repaintMask) )
904
\fn bool QtTableView::autoUpdate() const
906
Returns TRUE if the view updates itself automatically whenever it
907
is changed in some way.
913
Sets the auto-update option of the table view to \a enable.
915
If \a enable is TRUE (this is the default), the view updates itself
916
automatically whenever it has changed in some way (for example, when a
917
\link setTableFlags() flag\endlink is changed).
919
If \a enable is FALSE, the view does NOT repaint itself or update
920
its internal state variables when it is changed. This can be
921
useful to avoid flicker during large changes and is singularly
922
useless otherwise. Disable auto-update, do the changes, re-enable
923
auto-update and call repaint().
925
\warning Do not leave the view in this state for a long time
926
(i.e., between events). If, for example, the user interacts with the
927
view when auto-update is off, strange things can happen.
929
Setting auto-update to TRUE does not repaint the view; you must call
930
repaint() to do this.
932
\sa autoUpdate(), repaint()
935
void QtTableView::setAutoUpdate( bool enable )
937
if ( isUpdatesEnabled() == enable )
939
setUpdatesEnabled( enable );
941
showOrHideScrollBars();
948
Repaints the cell at row \a row, column \a col if it is inside the view.
950
If \a erase is TRUE, the relevant part of the view is cleared to the
951
background color/pixmap before the contents are repainted.
956
void QtTableView::updateCell( int row, int col, bool erase )
959
if ( !colXPos( col, &xPos ) )
961
if ( !rowYPos( row, &yPos ) )
963
QRect uR = QRect( xPos, yPos,
964
cellW ? cellW : cellWidth(col),
965
cellH ? cellH : cellHeight(row) );
966
repaint( uR.intersect(viewRect()), erase );
971
\fn QRect QtTableView::cellUpdateRect() const
973
This function should be called only from the paintCell() function in
974
subclasses. It returns the portion of a cell that actually needs to be
975
updated in \e cell coordinates. This is useful only for non-trivial
981
Returns the rectangle that is the actual table, excluding any
982
frame, in \e widget coordinates.
985
QRect QtTableView::viewRect() const
987
return QRect( frameWidth(), frameWidth(), viewWidth(), viewHeight() );
992
Returns the index of the last (bottom) row in the view.
993
The index of the first row is 0.
995
If no rows are visible it returns -1. This can happen if the
996
view is too small for the first row and Tbl_cutCellsV is set.
1001
int QtTableView::lastRowVisible() const
1004
int row = findRawRow( maxViewY(), &cellMaxY );
1005
if ( row == -1 || row >= nRows ) { // maxViewY() past end?
1006
row = nRows - 1; // yes: return last row
1008
if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() ) {
1009
if ( row == yCellOffs ) // cut by right margin?
1010
return -1; // yes, nothing in the view
1012
row = row - 1; // cut by margin, one back
1019
Returns the index of the last (right) column in the view.
1020
The index of the first column is 0.
1022
If no columns are visible it returns -1. This can happen if the
1023
view is too narrow for the first column and Tbl_cutCellsH is set.
1025
\sa lastRowVisible()
1028
int QtTableView::lastColVisible() const
1031
int col = findRawCol( maxViewX(), &cellMaxX );
1032
if ( col == -1 || col >= nCols ) { // maxViewX() past end?
1033
col = nCols - 1; // yes: return last col
1035
if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() ) {
1036
if ( col == xCellOffs ) // cut by bottom margin?
1037
return -1; // yes, nothing in the view
1039
col = col - 1; // cell by margin, one back
1046
Returns TRUE if \a row is at least partially visible.
1050
bool QtTableView::rowIsVisible( int row ) const
1052
return rowYPos( row, 0 );
1056
Returns TRUE if \a col is at least partially visible.
1060
bool QtTableView::colIsVisible( int col ) const
1062
return colXPos( col, 0 );
1068
Called when both scroll bars are active at the same time. Covers the
1069
bottom left corner between the two scroll bars with an empty widget.
1072
void QtTableView::coverCornerSquare( bool enable )
1074
coveringCornerSquare = enable;
1075
if ( !cornerSquare && enable ) {
1076
cornerSquare = new QCornerSquare( this );
1077
Q_CHECK_PTR( cornerSquare );
1078
cornerSquare->setGeometry( maxViewX() + frameWidth() + 1,
1079
maxViewY() + frameWidth() + 1,
1083
if ( autoUpdate() && cornerSquare ) {
1085
cornerSquare->show();
1087
cornerSquare->hide();
1094
Scroll the view to a position such that:
1096
If \a horizontal is TRUE, the leftmost column shown fits snugly
1097
with the left edge of the view.
1099
If \a vertical is TRUE, the top row shown fits snugly with the top
1102
You can achieve the same effect automatically by setting any of the
1103
\link setTableFlags() Tbl_snapTo*Grid \endlink table flags.
1106
void QtTableView::snapToGrid( bool horizontal, bool vertical )
1110
if ( horizontal && xCellDelta != 0 ) {
1111
int w = cellW ? cellW : cellWidth( xCellOffs );
1112
if ( xCellDelta >= w/2 )
1113
newXCell = xCellOffs + 1;
1115
newXCell = xCellOffs;
1117
if ( vertical && yCellDelta != 0 ) {
1118
int h = cellH ? cellH : cellHeight( yCellOffs );
1119
if ( yCellDelta >= h/2 )
1120
newYCell = yCellOffs + 1;
1122
newYCell = yCellOffs;
1124
setTopLeftCell( newYCell, newXCell ); //row,column
1129
This internal slot is connected to the horizontal scroll bar's
1130
QScrollBar::valueChanged() signal.
1132
Moves the table horizontally to offset \a val without updating the
1136
void QtTableView::horSbValue( int val )
1140
if ( horSnappingOff ) {
1141
horSnappingOff = FALSE;
1142
tFlags |= Tbl_snapToHGrid;
1145
setOffset( val, yOffs, FALSE );
1150
This internal slot is connected to the horizontal scroll bar's
1151
QScrollBar::sliderMoved() signal.
1153
Scrolls the table smoothly horizontally even if \c Tbl_snapToHGrid is set.
1156
void QtTableView::horSbSliding( int val )
1158
if ( testTableFlags(Tbl_snapToHGrid) &&
1159
testTableFlags(Tbl_smoothHScrolling) ) {
1160
tFlags &= ~Tbl_snapToHGrid; // turn off snapping while sliding
1161
setOffset( val, yOffs, FALSE );
1162
tFlags |= Tbl_snapToHGrid; // turn on snapping again
1164
setOffset( val, yOffs, FALSE );
1170
This internal slot is connected to the horizontal scroll bar's
1171
QScrollBar::sliderReleased() signal.
1174
void QtTableView::horSbSlidingDone( )
1176
if ( testTableFlags(Tbl_snapToHGrid) &&
1177
testTableFlags(Tbl_smoothHScrolling) )
1178
snapToGrid( TRUE, FALSE );
1183
This internal slot is connected to the vertical scroll bar's
1184
QScrollBar::valueChanged() signal.
1186
Moves the table vertically to offset \a val without updating the
1190
void QtTableView::verSbValue( int val )
1194
if ( verSnappingOff ) {
1195
verSnappingOff = FALSE;
1196
tFlags |= Tbl_snapToVGrid;
1199
setOffset( xOffs, val, FALSE );
1204
This internal slot is connected to the vertical scroll bar's
1205
QScrollBar::sliderMoved() signal.
1207
Scrolls the table smoothly vertically even if \c Tbl_snapToVGrid is set.
1210
void QtTableView::verSbSliding( int val )
1212
if ( testTableFlags(Tbl_snapToVGrid) &&
1213
testTableFlags(Tbl_smoothVScrolling) ) {
1214
tFlags &= ~Tbl_snapToVGrid; // turn off snapping while sliding
1215
setOffset( xOffs, val, FALSE );
1216
tFlags |= Tbl_snapToVGrid; // turn on snapping again
1218
setOffset( xOffs, val, FALSE );
1224
This internal slot is connected to the vertical scroll bar's
1225
QScrollBar::sliderReleased() signal.
1228
void QtTableView::verSbSlidingDone( )
1230
if ( testTableFlags(Tbl_snapToVGrid) &&
1231
testTableFlags(Tbl_smoothVScrolling) )
1232
snapToGrid( FALSE, TRUE );
1237
This virtual function is called before painting of table cells
1238
is started. It can be reimplemented by subclasses that want to
1239
to set up the painter in a special way and that do not want to
1240
do so for each cell.
1243
void QtTableView::setupPainter( QPainter * )
1248
\fn void QtTableView::paintCell( QPainter *p, int row, int col )
1250
This pure virtual function is called to paint the single cell at \a
1251
(row,col) using \a p, which is open when paintCell() is called and
1254
The coordinate system is \link QPainter::translate() translated \endlink
1255
so that the origin is at the top-left corner of the cell to be
1256
painted, i.e. \e cell coordinates. Do not scale or shear the coordinate
1257
system (or if you do, restore the transformation matrix before you
1260
The painter is not clipped by default and for maximum efficiency. For safety,
1261
call setTableFlags(Tbl_clipCellPainting) to enable clipping.
1263
\sa paintEvent(), setTableFlags() */
1267
Handles paint events, \a e, for the table view.
1269
Calls paintCell() for the cells that needs to be repainted.
1272
void QtTableView::paintEvent( QPaintEvent *e )
1274
QRect updateR = e->rect(); // update rectangle
1276
bool e = eraseInPaint;
1281
QPainter paint( this );
1283
if ( !contentsRect().contains( updateR, TRUE ) ) {// update frame ?
1284
drawFrame( &paint );
1285
if ( updateR.left() < frameWidth() ) //###
1286
updateR.setLeft( frameWidth() );
1287
if ( updateR.top() < frameWidth() )
1288
updateR.setTop( frameWidth() );
1291
int maxWX = maxViewX();
1292
int maxWY = maxViewY();
1293
if ( updateR.right() > maxWX )
1294
updateR.setRight( maxWX );
1295
if ( updateR.bottom() > maxWY )
1296
updateR.setBottom( maxWY );
1298
setupPainter( &paint ); // prepare for painting table
1300
int firstRow = findRow( updateR.y() );
1301
int firstCol = findCol( updateR.x() );
1303
if ( !colXPos( firstCol, &xStart ) || !rowYPos( firstRow, &yStart ) ) {
1304
paint.eraseRect( updateR ); // erase area outside cells but in view
1307
int maxX = updateR.right();
1308
int maxY = updateR.bottom();
1312
int xPos = maxX+1; // in case the while() is empty
1315
QRect winR = viewRect();
1318
#ifndef QT_NO_TRANSFORMATIONS
1322
while ( yPos <= maxY && row < nRows ) {
1323
nextY = yPos + (cellH ? cellH : cellHeight( row ));
1324
if ( testTableFlags( Tbl_cutCellsV ) && nextY > ( maxWY + 1 ) )
1328
while ( xPos <= maxX && col < nCols ) {
1329
nextX = xPos + (cellW ? cellW : cellWidth( col ));
1330
if ( testTableFlags( Tbl_cutCellsH ) && nextX > ( maxWX + 1 ) )
1333
cellR.setRect( xPos, yPos, cellW ? cellW : cellWidth(col),
1334
cellH ? cellH : cellHeight(row) );
1335
cellUR = cellR.intersect( updateR );
1336
if ( cellUR.isValid() ) {
1337
cellUpdateR = cellUR;
1338
cellUpdateR.moveBy( -xPos, -yPos ); // cell coordinates
1340
paint.eraseRect( cellUR );
1342
#ifndef QT_NO_TRANSFORMATIONS
1343
matrix.translate( xPos, yPos );
1344
paint.setWorldMatrix( matrix );
1345
if ( testTableFlags(Tbl_clipCellPainting) ||
1346
frameWidth() > 0 && !winR.contains( cellR ) ) { //##arnt
1347
paint.setClipRect( cellUR );
1348
paintCell( &paint, row, col );
1349
paint.setClipping( FALSE );
1351
paintCell( &paint, row, col );
1354
paint.setWorldMatrix( matrix );
1356
paint.translate( xPos, yPos );
1357
if ( testTableFlags(Tbl_clipCellPainting) ||
1358
frameWidth() > 0 && !winR.contains( cellR ) ) { //##arnt
1359
paint.setClipRect( cellUR );
1360
paintCell( &paint, row, col );
1361
paint.setClipping( FALSE );
1363
paintCell( &paint, row, col );
1365
paint.translate( -xPos, -yPos );
1375
// while painting we have to erase any areas in the view that
1376
// are not covered by cells but are covered by the paint event
1377
// rectangle these must be erased. We know that xPos is the last
1378
// x pixel updated + 1 and that yPos is the last y pixel updated + 1.
1380
// Note that this needs to be done regardless whether we do
1381
// eraseInPaint or not. Reason: a subclass may implement
1382
// flicker-freeness and encourage the use of repaint(FALSE).
1383
// The subclass, however, cannot draw all pixels, just those
1384
// inside the cells. So QtTableView is reponsible for all pixels
1385
// outside the cells.
1387
QRect viewR = viewRect();
1388
const QColorGroup g = colorGroup();
1390
if ( xPos <= maxX ) {
1393
r.setBottom( yPos<maxY?yPos:maxY );
1394
if ( inherits( "QMultiLineEdit" ) )
1395
paint.fillRect( r.intersect( updateR ), g.base() );
1397
paint.eraseRect( r.intersect( updateR ) );
1399
if ( yPos <= maxY ) {
1402
if ( inherits( "QMultiLineEdit" ) )
1403
paint.fillRect( r.intersect( updateR ), g.base() );
1405
paint.eraseRect( r.intersect( updateR ) );
1411
void QtTableView::resizeEvent( QResizeEvent * )
1413
updateScrollBars( horValue | verValue | horSteps | horGeometry | horRange |
1414
verSteps | verGeometry | verRange );
1415
showOrHideScrollBars();
1417
int maxX = QMIN( xOffs, maxXOffset() ); // ### can be slow
1418
int maxY = QMIN( yOffs, maxYOffset() );
1419
setOffset( maxX, maxY );
1424
Redraws all visible cells in the table view.
1427
void QtTableView::updateView()
1429
repaint( viewRect() );
1433
Returns a pointer to the vertical scroll bar mainly so you can
1434
connect() to its signals. Note that the scroll bar works in pixel
1435
values; use findRow() to translate to cell numbers.
1438
QScrollBar *QtTableView::verticalScrollBar() const
1440
QtTableView *that = (QtTableView*)this; // semantic const
1441
if ( !vScrollBar ) {
1442
QScrollBar *sb = new QScrollBar( QScrollBar::Vertical, that );
1443
#ifndef QT_NO_CURSOR
1444
sb->setCursor( arrowCursor );
1446
sb->resize( sb->sizeHint() ); // height is irrelevant
1448
sb->setTracking( FALSE );
1449
sb->setFocusPolicy( NoFocus );
1450
connect( sb, SIGNAL(valueChanged(int)),
1451
SLOT(verSbValue(int)));
1452
connect( sb, SIGNAL(sliderMoved(int)),
1453
SLOT(verSbSliding(int)));
1454
connect( sb, SIGNAL(sliderReleased()),
1455
SLOT(verSbSlidingDone()));
1457
that->vScrollBar = sb;
1464
Returns a pointer to the horizontal scroll bar mainly so you can
1465
connect() to its signals. Note that the scroll bar works in pixel
1466
values; use findCol() to translate to cell numbers.
1469
QScrollBar *QtTableView::horizontalScrollBar() const
1471
QtTableView *that = (QtTableView*)this; // semantic const
1472
if ( !hScrollBar ) {
1473
QScrollBar *sb = new QScrollBar( QScrollBar::Horizontal, that );
1474
#ifndef QT_NO_CURSOR
1475
sb->setCursor( arrowCursor );
1477
sb->resize( sb->sizeHint() ); // width is irrelevant
1478
sb->setFocusPolicy( NoFocus );
1480
sb->setTracking( FALSE );
1481
connect( sb, SIGNAL(valueChanged(int)),
1482
SLOT(horSbValue(int)));
1483
connect( sb, SIGNAL(sliderMoved(int)),
1484
SLOT(horSbSliding(int)));
1485
connect( sb, SIGNAL(sliderReleased()),
1486
SLOT(horSbSlidingDone()));
1488
that->hScrollBar = sb;
1495
Enables or disables the horizontal scroll bar, as required by
1496
setAutoUpdate() and the \link setTableFlags() table flags\endlink.
1499
void QtTableView::setHorScrollBar( bool on, bool update )
1502
tFlags |= Tbl_hScrollBar;
1503
horizontalScrollBar(); // created
1505
updateScrollBars( horMask | verMask );
1507
sbDirty = sbDirty | (horMask | verMask);
1508
if ( testTableFlags( Tbl_vScrollBar ) )
1509
coverCornerSquare( TRUE );
1511
sbDirty = sbDirty | horMask;
1513
tFlags &= ~Tbl_hScrollBar;
1516
coverCornerSquare( FALSE );
1517
bool hideScrollBar = autoUpdate() && hScrollBar->isVisible();
1518
if ( hideScrollBar )
1521
updateScrollBars( verMask );
1523
sbDirty = sbDirty | verMask;
1524
if ( hideScrollBar && isVisible() )
1525
repaint( hScrollBar->x(), hScrollBar->y(),
1526
width() - hScrollBar->x(), hScrollBar->height() );
1534
Enables or disables the vertical scroll bar, as required by
1535
setAutoUpdate() and the \link setTableFlags() table flags\endlink.
1538
void QtTableView::setVerScrollBar( bool on, bool update )
1541
tFlags |= Tbl_vScrollBar;
1542
verticalScrollBar(); // created
1544
updateScrollBars( verMask | horMask );
1546
sbDirty = sbDirty | (horMask | verMask);
1547
if ( testTableFlags( Tbl_hScrollBar ) )
1548
coverCornerSquare( TRUE );
1550
sbDirty = sbDirty | verMask;
1552
tFlags &= ~Tbl_vScrollBar;
1555
coverCornerSquare( FALSE );
1556
bool hideScrollBar = autoUpdate() && vScrollBar->isVisible();
1557
if ( hideScrollBar )
1560
updateScrollBars( horMask );
1562
sbDirty = sbDirty | horMask;
1563
if ( hideScrollBar && isVisible() )
1564
repaint( vScrollBar->x(), vScrollBar->y(),
1565
vScrollBar->width(), height() - vScrollBar->y() );
1574
int QtTableView::findRawRow( int yPos, int *cellMaxY, int *cellMinY,
1575
bool goOutsideView ) const
1580
if ( goOutsideView || yPos >= minViewY() && yPos <= maxViewY() ) {
1581
if ( yPos < minViewY() ) {
1582
#if defined(QT_CHECK_RANGE)
1583
qWarning( "QtTableView::findRawRow: (%s) internal error: "
1584
"yPos < minViewY() && goOutsideView "
1585
"not supported. (%d,%d)",
1586
name( "unnamed" ), yPos, yOffs );
1590
if ( cellH ) { // uniform cell height
1591
r = (yPos - minViewY() + yCellDelta)/cellH; // cell offs from top
1593
*cellMaxY = (r + 1)*cellH + minViewY() - yCellDelta - 1;
1595
*cellMinY = r*cellH + minViewY() - yCellDelta;
1596
r += yCellOffs; // absolute cell index
1597
} else { // variable cell height
1598
QtTableView *tw = (QtTableView *)this;
1600
int h = minViewY() - yCellDelta; //##arnt3
1602
Q_ASSERT( r < nRows );
1603
while ( r < nRows ) {
1605
h += tw->cellHeight( r ); // Start of next cell
1621
int QtTableView::findRawCol( int xPos, int *cellMaxX, int *cellMinX ,
1622
bool goOutsideView ) const
1627
if ( goOutsideView || xPos >= minViewX() && xPos <= maxViewX() ) {
1628
if ( xPos < minViewX() ) {
1629
#if defined(QT_CHECK_RANGE)
1630
qWarning( "QtTableView::findRawCol: (%s) internal error: "
1631
"xPos < minViewX() && goOutsideView "
1632
"not supported. (%d,%d)",
1633
name( "unnamed" ), xPos, xOffs );
1637
if ( cellW ) { // uniform cell width
1638
c = (xPos - minViewX() + xCellDelta)/cellW; //cell offs from left
1640
*cellMaxX = (c + 1)*cellW + minViewX() - xCellDelta - 1;
1642
*cellMinX = c*cellW + minViewX() - xCellDelta;
1643
c += xCellOffs; // absolute cell index
1644
} else { // variable cell width
1645
QtTableView *tw = (QtTableView *)this;
1647
int w = minViewX() - xCellDelta; //##arnt3
1649
Q_ASSERT( c < nCols );
1650
while ( c < nCols ) {
1652
w += tw->cellWidth( c ); // Start of next cell
1668
Returns the index of the row at position \a yPos, where \a yPos is in
1669
\e widget coordinates. Returns -1 if \a yPos is outside the valid
1672
\sa findCol(), rowYPos()
1675
int QtTableView::findRow( int yPos ) const
1678
int row = findRawRow( yPos, &cellMaxY );
1679
if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() )
1680
row = - 1; // cell cut by bottom margin
1688
Returns the index of the column at position \a xPos, where \a xPos is
1689
in \e widget coordinates. Returns -1 if \a xPos is outside the valid
1692
\sa findRow(), colXPos()
1695
int QtTableView::findCol( int xPos ) const
1698
int col = findRawCol( xPos, &cellMaxX );
1699
if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() )
1700
col = - 1; // cell cut by right margin
1708
Computes the position in the widget of row \a row.
1710
Returns TRUE and stores the result in \a *yPos (in \e widget
1711
coordinates) if the row is visible. Returns FALSE and does not modify
1712
\a *yPos if \a row is invisible or invalid.
1714
\sa colXPos(), findRow()
1717
bool QtTableView::rowYPos( int row, int *yPos ) const
1720
if ( row >= yCellOffs ) {
1722
int lastVisible = lastRowVisible();
1723
if ( row > lastVisible || lastVisible == -1 )
1725
y = (row - yCellOffs)*cellH + minViewY() - yCellDelta;
1728
y = minViewY() - yCellDelta; // y of leftmost cell in view
1730
QtTableView *tw = (QtTableView *)this;
1731
int maxY = maxViewY();
1732
while ( r < row && y <= maxY )
1733
y += tw->cellHeight( r++ );
1748
Computes the position in the widget of column \a col.
1750
Returns TRUE and stores the result in \a *xPos (in \e widget
1751
coordinates) if the column is visible. Returns FALSE and does not
1752
modify \a *xPos if \a col is invisible or invalid.
1754
\sa rowYPos(), findCol()
1757
bool QtTableView::colXPos( int col, int *xPos ) const
1760
if ( col >= xCellOffs ) {
1762
int lastVisible = lastColVisible();
1763
if ( col > lastVisible || lastVisible == -1 )
1765
x = (col - xCellOffs)*cellW + minViewX() - xCellDelta;
1768
x = minViewX() - xCellDelta; // x of uppermost cell in view
1770
QtTableView *tw = (QtTableView *)this;
1771
int maxX = maxViewX();
1772
while ( c < col && x <= maxX )
1773
x += tw->cellWidth( c++ );
1787
Moves the visible area of the table right by \a xPixels and
1788
down by \a yPixels pixels. Both may be negative.
1790
\warning You might find that QScrollView offers a higher-level of
1791
functionality than using QtTableView and this function.
1793
This function is \e not the same as QWidget::scroll(); in particular,
1794
the signs of \a xPixels and \a yPixels have the reverse semantics.
1796
\sa setXOffset(), setYOffset(), setOffset(), setTopCell(),
1800
void QtTableView::scroll( int xPixels, int yPixels )
1802
QWidget::scroll( -xPixels, -yPixels, contentsRect() );
1807
Returns the leftmost pixel of the table view in \e view
1808
coordinates. This excludes the frame and any header.
1810
\sa maxViewY(), viewWidth(), contentsRect()
1813
int QtTableView::minViewX() const
1815
return frameWidth();
1820
Returns the top pixel of the table view in \e view
1821
coordinates. This excludes the frame and any header.
1823
\sa maxViewX(), viewHeight(), contentsRect()
1826
int QtTableView::minViewY() const
1828
return frameWidth();
1833
Returns the rightmost pixel of the table view in \e view
1834
coordinates. This excludes the frame and any scroll bar, but
1835
includes blank pixels to the right of the visible table data.
1837
\sa maxViewY(), viewWidth(), contentsRect()
1840
int QtTableView::maxViewX() const
1842
return width() - 1 - frameWidth()
1843
- (tFlags & Tbl_vScrollBar ? VSBEXT
1849
Returns the bottom pixel of the table view in \e view
1850
coordinates. This excludes the frame and any scroll bar, but
1851
includes blank pixels below the visible table data.
1853
\sa maxViewX(), viewHeight(), contentsRect()
1856
int QtTableView::maxViewY() const
1858
return height() - 1 - frameWidth()
1859
- (tFlags & Tbl_hScrollBar ? HSBEXT
1865
Returns the width of the table view, as such, in \e view
1866
coordinates. This does not include any header, scroll bar or frame,
1867
but it does include background pixels to the right of the table data.
1869
\sa minViewX() maxViewX(), viewHeight(), contentsRect() viewRect()
1872
int QtTableView::viewWidth() const
1874
return maxViewX() - minViewX() + 1;
1879
Returns the height of the table view, as such, in \e view
1880
coordinates. This does not include any header, scroll bar or frame,
1881
but it does include background pixels below the table data.
1883
\sa minViewY() maxViewY() viewWidth() contentsRect() viewRect()
1886
int QtTableView::viewHeight() const
1888
return maxViewY() - minViewY() + 1;
1892
void QtTableView::doAutoScrollBars()
1894
int viewW = width() - frameWidth() - minViewX();
1895
int viewH = height() - frameWidth() - minViewY();
1896
bool vScrollOn = testTableFlags(Tbl_vScrollBar);
1897
bool hScrollOn = testTableFlags(Tbl_hScrollBar);
1902
if ( testTableFlags(Tbl_autoHScrollBar) ) {
1907
while ( i < nCols && w <= viewW )
1908
w += cellWidth( i++ );
1916
if ( testTableFlags(Tbl_autoVScrollBar) ) {
1921
while ( i < nRows && h <= viewH )
1922
h += cellHeight( i++ );
1931
if ( testTableFlags(Tbl_autoHScrollBar) && vScrollOn && !hScrollOn )
1932
if ( w > viewW - VSBEXT )
1935
if ( testTableFlags(Tbl_autoVScrollBar) && hScrollOn && !vScrollOn )
1936
if ( h > viewH - HSBEXT )
1939
setHorScrollBar( hScrollOn, FALSE );
1940
setVerScrollBar( vScrollOn, FALSE );
1946
\fn void QtTableView::updateScrollBars()
1948
Updates the scroll bars' contents and presence to match the table's
1949
state. Generally, you should not need to call this.
1955
Updates the scroll bars' contents and presence to match the table's
1961
void QtTableView::updateScrollBars( uint f )
1963
sbDirty = sbDirty | f;
1968
if ( testTableFlags(Tbl_autoHScrollBar) && (sbDirty & horRange) ||
1969
testTableFlags(Tbl_autoVScrollBar) && (sbDirty & verRange) )
1970
// if range change and auto
1971
doAutoScrollBars(); // turn scroll bars on/off if needed
1973
if ( !autoUpdate() ) {
1977
if ( yOffset() > 0 && testTableFlags( Tbl_autoVScrollBar ) &&
1978
!testTableFlags( Tbl_vScrollBar ) ) {
1981
if ( xOffset() > 0 && testTableFlags( Tbl_autoHScrollBar ) &&
1982
!testTableFlags( Tbl_hScrollBar ) ) {
1985
if ( !isVisible() ) {
1990
if ( testTableFlags(Tbl_hScrollBar) && (sbDirty & horMask) != 0 ) {
1991
if ( sbDirty & horGeometry )
1992
hScrollBar->setGeometry( 0,height() - HSBEXT,
1993
viewWidth() + frameWidth()*2,
1996
if ( sbDirty & horSteps ) {
1998
hScrollBar->setSteps( QMIN(cellW,viewWidth()/2), viewWidth() );
2000
hScrollBar->setSteps( 16, viewWidth() );
2003
if ( sbDirty & horRange )
2004
hScrollBar->setRange( 0, maxXOffset() );
2006
if ( sbDirty & horValue )
2007
hScrollBar->setValue( xOffs );
2009
// show scrollbar only when it has a sane geometry
2010
if ( !hScrollBar->isVisible() )
2014
if ( testTableFlags(Tbl_vScrollBar) && (sbDirty & verMask) != 0 ) {
2015
if ( sbDirty & verGeometry )
2016
vScrollBar->setGeometry( width() - VSBEXT, 0,
2018
viewHeight() + frameWidth()*2 );
2020
if ( sbDirty & verSteps ) {
2022
vScrollBar->setSteps( QMIN(cellH,viewHeight()/2), viewHeight() );
2024
vScrollBar->setSteps( 16, viewHeight() ); // fttb! ###
2027
if ( sbDirty & verRange )
2028
vScrollBar->setRange( 0, maxYOffset() );
2030
if ( sbDirty & verValue )
2031
vScrollBar->setValue( yOffs );
2033
// show scrollbar only when it has a sane geometry
2034
if ( !vScrollBar->isVisible() )
2037
if ( coveringCornerSquare &&
2038
( (sbDirty & verGeometry ) || (sbDirty & horGeometry)) )
2039
cornerSquare->move( maxViewX() + frameWidth() + 1,
2040
maxViewY() + frameWidth() + 1 );
2047
void QtTableView::updateFrameSize()
2049
int rw = width() - ( testTableFlags(Tbl_vScrollBar) ?
2051
int rh = height() - ( testTableFlags(Tbl_hScrollBar) ?
2058
if ( autoUpdate() ) {
2059
int fh = frameRect().height();
2060
int fw = frameRect().width();
2061
setFrameRect( QRect(0,0,rw,rh) );
2064
update( QMIN(fw,rw) - frameWidth() - 2, 0, frameWidth()+4, rh );
2066
update( 0, QMIN(fh,rh) - frameWidth() - 2, rw, frameWidth()+4 );
2072
Returns the maximum horizontal offset within the table of the
2073
view's left edge in \e table coordinates.
2075
This is used mainly to set the horizontal scroll bar's range.
2077
\sa maxColOffset(), maxYOffset(), totalWidth()
2080
int QtTableView::maxXOffset()
2082
int tw = totalWidth();
2084
if ( testTableFlags(Tbl_scrollLastHCell) ) {
2086
maxOffs = tw - ( cellW ? cellW : cellWidth( nCols - 1 ) );
2088
maxOffs = tw - viewWidth();
2090
if ( testTableFlags(Tbl_snapToHGrid) ) {
2092
maxOffs = tw - (viewWidth()/cellW)*cellW;
2094
int goal = tw - viewWidth();
2096
int nextCol = nCols - 1;
2097
int nextCellWidth = cellWidth( nextCol );
2098
while( nextCol > 0 && pos > goal + nextCellWidth ) {
2099
pos -= nextCellWidth;
2100
nextCellWidth = cellWidth( --nextCol );
2102
if ( goal + nextCellWidth == pos )
2104
else if ( goal < pos )
2110
maxOffs = tw - viewWidth();
2113
return maxOffs > 0 ? maxOffs : 0;
2118
Returns the maximum vertical offset within the table of the
2119
view's top edge in \e table coordinates.
2121
This is used mainly to set the vertical scroll bar's range.
2123
\sa maxRowOffset(), maxXOffset(), totalHeight()
2126
int QtTableView::maxYOffset()
2128
int th = totalHeight();
2130
if ( testTableFlags(Tbl_scrollLastVCell) ) {
2132
maxOffs = th - ( cellH ? cellH : cellHeight( nRows - 1 ) );
2134
maxOffs = th - viewHeight();
2136
if ( testTableFlags(Tbl_snapToVGrid) ) {
2138
maxOffs = th - (viewHeight()/cellH)*cellH;
2140
int goal = th - viewHeight();
2142
int nextRow = nRows - 1;
2143
int nextCellHeight = cellHeight( nextRow );
2144
while( nextRow > 0 && pos > goal + nextCellHeight ) {
2145
pos -= nextCellHeight;
2146
nextCellHeight = cellHeight( --nextRow );
2148
if ( goal + nextCellHeight == pos )
2150
else if ( goal < pos )
2156
maxOffs = th - viewHeight();
2159
return maxOffs > 0 ? maxOffs : 0;
2164
Returns the index of the last column, which may be at the left edge
2167
Depending on the \link setTableFlags() Tbl_scrollLastHCell\endlink flag,
2168
this may or may not be the last column.
2170
\sa maxXOffset(), maxRowOffset()
2173
int QtTableView::maxColOffset()
2175
int mx = maxXOffset();
2180
while ( col < nCols && mx > (xcd=cellWidth(col)) ) {
2190
Returns the index of the last row, which may be at the top edge of
2193
Depending on the \link setTableFlags() Tbl_scrollLastVCell\endlink flag,
2194
this may or may not be the last row.
2196
\sa maxYOffset(), maxColOffset()
2199
int QtTableView::maxRowOffset()
2201
int my = maxYOffset();
2206
while ( row < nRows && my > (ycd=cellHeight(row)) ) {
2215
void QtTableView::showOrHideScrollBars()
2217
if ( !autoUpdate() )
2220
if ( testTableFlags(Tbl_vScrollBar) ) {
2221
if ( !vScrollBar->isVisible() )
2222
sbDirty = sbDirty | verMask;
2224
if ( vScrollBar->isVisible() )
2229
if ( testTableFlags(Tbl_hScrollBar) ) {
2230
if ( !hScrollBar->isVisible() )
2231
sbDirty = sbDirty | horMask;
2233
if ( hScrollBar->isVisible() )
2237
if ( cornerSquare ) {
2238
if ( testTableFlags(Tbl_hScrollBar) &&
2239
testTableFlags(Tbl_vScrollBar) ) {
2240
if ( !cornerSquare->isVisible() )
2241
cornerSquare->show();
2243
if ( cornerSquare->isVisible() )
2244
cornerSquare->hide();
2251
Updates the scroll bars and internal state.
2253
Call this function when the table view's total size is changed;
2254
typically because the result of cellHeight() or cellWidth() have changed.
2256
This function does not repaint the widget.
2259
void QtTableView::updateTableSize()
2261
bool updateOn = autoUpdate();
2262
setAutoUpdate( FALSE );
2263
int xofs = xOffset();
2264
xOffs++; //so that setOffset will not return immediately
2265
setOffset(xofs,yOffset(),FALSE); //to calculate internal state correctly
2266
setAutoUpdate(updateOn);
2268
updateScrollBars( horSteps | horRange |
2269
verSteps | verRange );
2270
showOrHideScrollBars();