~ubuntu-branches/ubuntu/breezy/koffice/breezy-security

« back to all changes in this revision

Viewing changes to kchart/qttableview.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-10-11 14:49:50 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051011144950-lwpngbifzp8nk0ds
Tags: 1:1.4.1-0ubuntu7
* SECURITY UPDATE: fix heap based buffer overflow in the RTF importer of KWord
* Opening specially crafted RTF files in KWord can cause
  execution of abitrary code.
* Add kubuntu_01_rtfimport_heap_overflow.diff
* References:
  CAN-2005-2971
  CESA-2005-005
  http://www.koffice.org/security/advisory-20051011-1.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**********************************************************************
2
 
** $Id: qttableview.cpp,v 1.2 2001/10/27 14:51:47 mlaurent Exp $
3
 
**
4
 
** Implementation of QtTableView class
5
 
**
6
 
** Created : 941115
7
 
**
8
 
** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
9
 
**
10
 
** This file contains a class moved out of the Qt GUI Toolkit API. It
11
 
** may be used, distributed and modified without limitation.
12
 
**
13
 
**********************************************************************/
14
 
 
15
 
#include "qttableview.h"
16
 
#include "qttableview.moc"
17
 
#ifndef QT_NO_QTTABLEVIEW
18
 
#include "qscrollbar.h"
19
 
#include "qpainter.h"
20
 
#include "qdrawutil.h"
21
 
#include <limits.h>
22
 
 
23
 
enum ScrollBarDirtyFlags {
24
 
    verGeometry   = 0x01,
25
 
    verSteps      = 0x02,
26
 
    verRange      = 0x04,
27
 
    verValue      = 0x08,
28
 
    horGeometry   = 0x10,
29
 
    horSteps      = 0x20,
30
 
    horRange      = 0x40,
31
 
    horValue      = 0x80,
32
 
    verMask       = 0x0F,
33
 
    horMask       = 0xF0
34
 
};
35
 
 
36
 
 
37
 
#define HSBEXT horizontalScrollBar()->sizeHint().height()
38
 
#define VSBEXT verticalScrollBar()->sizeHint().width()
39
 
 
40
 
 
41
 
class QCornerSquare : public QWidget            // internal class
42
 
{
43
 
public:
44
 
    QCornerSquare( QWidget *, const char* = 0 );
45
 
    void paintEvent( QPaintEvent * );
46
 
};
47
 
 
48
 
QCornerSquare::QCornerSquare( QWidget *parent, const char *name )
49
 
        : QWidget( parent, name )
50
 
{
51
 
}
52
 
 
53
 
void QCornerSquare::paintEvent( QPaintEvent * )
54
 
{
55
 
}
56
 
 
57
 
 
58
 
// NOT REVISED
59
 
/*!
60
 
  \class QtTableView qttableview.h
61
 
  \brief The QtTableView class provides an abstract base for tables.
62
 
 
63
 
  \obsolete
64
 
 
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,
68
 
  column 0.
69
 
 
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.
77
 
 
78
 
  When you read this documentation, it is important to understand the
79
 
  distinctions among the four pixel coordinate systems involved.
80
 
 
81
 
  \list 1
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().
84
 
 
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().
89
 
 
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().
92
 
 
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
96
 
 
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
99
 
  powerful base class.
100
 
 
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).
105
 
 
106
 
  <img src=qtablevw-m.png> <img src=qtablevw-w.png>
107
 
 
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.
113
 
 
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.
121
 
 
122
 
  \sa QScrollView
123
 
  \link guibooks.html#fowler GUI Design Handbook: Table\endlink
124
 
*/
125
 
 
126
 
 
127
 
/*!
128
 
  Constructs a table view.  The \a parent, \a name and \f arguments
129
 
  are passed to the QFrame constructor.
130
 
 
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.
134
 
 
135
 
  The \link setCellHeight() cell height\endlink and \link setCellWidth()
136
 
  cell width\endlink are set to 0.
137
 
 
138
 
  Frame line shapes (QFrame::HLink and QFrame::VLine) are disallowed;
139
 
  see QFrame::setFrameStyle().
140
 
 
141
 
  Note that the \a f argument is \e not \link setTableFlags() table
142
 
  flags \endlink but rather \link QWidget::QWidget() widget
143
 
  flags. \endlink
144
 
 
145
 
*/
146
 
 
147
 
QtTableView::QtTableView( QWidget *parent, const char *name, WFlags f )
148
 
    : QFrame( parent, name, f )
149
 
{
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
155
 
    tFlags               = 0;
156
 
    vScrollBar           = hScrollBar = 0;      // no scroll bars
157
 
    cornerSquare         = 0;
158
 
    sbDirty              = 0;
159
 
    eraseInPaint         = FALSE;
160
 
    verSliding           = FALSE;
161
 
    verSnappingOff       = FALSE;
162
 
    horSliding           = FALSE;
163
 
    horSnappingOff       = FALSE;
164
 
    coveringCornerSquare = FALSE;
165
 
    inSbUpdate           = FALSE;
166
 
}
167
 
 
168
 
/*!
169
 
  Destroys the table view.
170
 
*/
171
 
 
172
 
QtTableView::~QtTableView()
173
 
{
174
 
    delete vScrollBar;
175
 
    delete hScrollBar;
176
 
    delete cornerSquare;
177
 
}
178
 
 
179
 
 
180
 
/*!
181
 
  \internal
182
 
  Reimplements QWidget::setBackgroundColor() for binary compatibility.
183
 
  \sa setPalette()
184
 
*/
185
 
 
186
 
void QtTableView::setBackgroundColor( const QColor &c )
187
 
{
188
 
    QWidget::setBackgroundColor( c );
189
 
}
190
 
 
191
 
/*!\reimp
192
 
*/
193
 
 
194
 
void QtTableView::setPalette( const QPalette &p )
195
 
{
196
 
    QWidget::setPalette( p );
197
 
}
198
 
 
199
 
/*!\reimp
200
 
*/
201
 
 
202
 
void QtTableView::show()
203
 
{
204
 
    showOrHideScrollBars();
205
 
    QWidget::show();
206
 
}
207
 
 
208
 
 
209
 
/*!
210
 
  \overload void QtTableView::repaint( bool erase )
211
 
  Repaints the entire view.
212
 
*/
213
 
 
214
 
/*!
215
 
  Repaints the table view directly by calling paintEvent() directly
216
 
  unless updates are disabled.
217
 
 
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.
220
 
 
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>.
223
 
 
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
226
 
  event.
227
 
 
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.  */
232
 
 
233
 
void QtTableView::repaint( int x, int y, int w, int h, bool erase )
234
 
{
235
 
    if ( !isVisible() || testWState(WState_BlockUpdates) )
236
 
        return;
237
 
    if ( w < 0 )
238
 
        w = width()  - x;
239
 
    if ( h < 0 )
240
 
        h = height() - y;
241
 
    QRect r( x, y, w, h );
242
 
    if ( r.isEmpty() )
243
 
        return; // nothing to do
244
 
    QPaintEvent e( r );
245
 
    if ( erase && backgroundMode() != NoBackground )
246
 
        eraseInPaint = TRUE;                    // erase when painting
247
 
    paintEvent( &e );
248
 
    eraseInPaint = FALSE;
249
 
}
250
 
 
251
 
/*!
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.
255
 
*/
256
 
 
257
 
 
258
 
/*!
259
 
  \fn int QtTableView::numRows() const
260
 
  Returns the number of rows in the table.
261
 
  \sa numCols(), setNumRows()
262
 
*/
263
 
 
264
 
/*!
265
 
  Sets the number of rows of the table to \a rows (must be non-negative).
266
 
  Does not change topCell().
267
 
 
268
 
  The table repaints itself automatically if autoUpdate() is set.
269
 
 
270
 
  \sa numCols(), setNumCols(), numRows()
271
 
*/
272
 
 
273
 
void QtTableView::setNumRows( int rows )
274
 
{
275
 
    if ( rows < 0 ) {
276
 
#if defined(QT_CHECK_RANGE)
277
 
        qWarning( "QtTableView::setNumRows: (%s) Negative argument %d.",
278
 
                 name( "unnamed" ), rows );
279
 
#endif
280
 
        return;
281
 
    }
282
 
    if ( nRows == rows )
283
 
        return;
284
 
 
285
 
    if ( autoUpdate() && isVisible() ) {
286
 
        int oldLastVisible = lastRowVisible();
287
 
        int oldTopCell = topCell();
288
 
        nRows = rows;
289
 
        if ( autoUpdate() && isVisible() &&
290
 
             ( oldLastVisible != lastRowVisible() || oldTopCell != topCell() ) )
291
 
                repaint( oldTopCell != topCell() );
292
 
    } else {
293
 
        // Be more careful - if destructing, bad things might happen.
294
 
        nRows = rows;
295
 
    }
296
 
    updateScrollBars( verRange );
297
 
    updateFrameSize();
298
 
}
299
 
 
300
 
/*!
301
 
  \fn int QtTableView::numCols() const
302
 
  Returns the number of columns in the table.
303
 
  \sa numRows(), setNumCols()
304
 
*/
305
 
 
306
 
/*!
307
 
  Sets the number of columns of the table to \a cols (must be non-negative).
308
 
  Does not change leftCell().
309
 
 
310
 
  The table repaints itself automatically if autoUpdate() is set.
311
 
 
312
 
  \sa numCols(), numRows(), setNumRows()
313
 
*/
314
 
 
315
 
void QtTableView::setNumCols( int cols )
316
 
{
317
 
    if ( cols < 0 ) {
318
 
#if defined(QT_CHECK_RANGE)
319
 
        qWarning( "QtTableView::setNumCols: (%s) Negative argument %d.",
320
 
                 name( "unnamed" ), cols );
321
 
#endif
322
 
        return;
323
 
    }
324
 
    if ( nCols == cols )
325
 
        return;
326
 
    int oldCols = nCols;
327
 
    nCols = cols;
328
 
    if ( autoUpdate() && isVisible() ) {
329
 
        int maxCol = lastColVisible();
330
 
        if ( maxCol >= oldCols || maxCol >= nCols )
331
 
            repaint();
332
 
    }
333
 
    updateScrollBars( horRange );
334
 
    updateFrameSize();
335
 
}
336
 
 
337
 
 
338
 
/*!
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()
343
 
*/
344
 
 
345
 
/*!
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()
349
 
*/
350
 
 
351
 
void QtTableView::setTopCell( int row )
352
 
{
353
 
    setTopLeftCell( row, -1 );
354
 
    return;
355
 
}
356
 
 
357
 
/*!
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()
362
 
*/
363
 
 
364
 
/*!
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()
368
 
*/
369
 
 
370
 
void QtTableView::setLeftCell( int col )
371
 
{
372
 
    setTopLeftCell( -1, col );
373
 
    return;
374
 
}
375
 
 
376
 
/*!
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()
381
 
*/
382
 
 
383
 
void QtTableView::setTopLeftCell( int row, int col )
384
 
{
385
 
    int newX = xOffs;
386
 
    int newY = yOffs;
387
 
 
388
 
    if ( col >= 0 ) {
389
 
        if ( cellW ) {
390
 
            newX = col*cellW;
391
 
            if ( newX > maxXOffset() )
392
 
                newX = maxXOffset();
393
 
        } else {
394
 
            newX = 0;
395
 
            while ( col )
396
 
                newX += cellWidth( --col );   // optimize using current! ###
397
 
        }
398
 
    }
399
 
    if ( row >= 0 ) {
400
 
        if ( cellH ) {
401
 
            newY = row*cellH;
402
 
            if ( newY > maxYOffset() )
403
 
                newY = maxYOffset();
404
 
        } else {
405
 
            newY = 0;
406
 
            while ( row )
407
 
                newY += cellHeight( --row );   // optimize using current! ###
408
 
        }
409
 
    }
410
 
    setOffset( newX, newY );
411
 
}
412
 
 
413
 
 
414
 
/*!
415
 
  \fn int QtTableView::xOffset() const
416
 
 
417
 
  Returns the x coordinate in \e table coordinates of the pixel that is
418
 
  currently on the left edge of the view.
419
 
 
420
 
  \sa setXOffset(), yOffset(), leftCell() */
421
 
 
422
 
/*!
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.
425
 
 
426
 
  The interaction with \link setTableFlags() Tbl_snapToHGrid
427
 
  \endlink is tricky.
428
 
 
429
 
  \sa xOffset(), setYOffset(), setOffset(), setLeftCell()
430
 
*/
431
 
 
432
 
void QtTableView::setXOffset( int x )
433
 
{
434
 
    setOffset( x, yOffset() );
435
 
}
436
 
 
437
 
/*!
438
 
  \fn int QtTableView::yOffset() const
439
 
 
440
 
  Returns the y coordinate in \e table coordinates of the pixel that is
441
 
  currently on the top edge of the view.
442
 
 
443
 
  \sa setYOffset(), xOffset(), topCell()
444
 
*/
445
 
 
446
 
 
447
 
/*!
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.
450
 
 
451
 
  The interaction with \link setTableFlags() Tbl_snapToVGrid
452
 
  \endlink is tricky.
453
 
 
454
 
  \sa yOffset(), setXOffset(), setOffset(), setTopCell()
455
 
*/
456
 
 
457
 
void QtTableView::setYOffset( int y )
458
 
{
459
 
    setOffset( xOffset(), y );
460
 
}
461
 
 
462
 
/*!
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.
465
 
 
466
 
  The interaction with \link setTableFlags() Tbl_snapTo*Grid \endlink
467
 
  is tricky.  If \a updateScrBars is TRUE, the scroll bars are
468
 
  updated.
469
 
 
470
 
  \sa xOffset(), yOffset(), setXOffset(), setYOffset(), setTopLeftCell()
471
 
*/
472
 
 
473
 
void QtTableView::setOffset( int x, int y, bool updateScrBars )
474
 
{
475
 
    if ( (!testTableFlags(Tbl_snapToHGrid) || xCellDelta == 0) &&
476
 
         (!testTableFlags(Tbl_snapToVGrid) || yCellDelta == 0) &&
477
 
         (x == xOffs && y == yOffs) )
478
 
        return;
479
 
 
480
 
    if ( x < 0 )
481
 
        x = 0;
482
 
    if ( y < 0 )
483
 
        y = 0;
484
 
 
485
 
    if ( cellW ) {
486
 
        if ( x > maxXOffset() )
487
 
            x = maxXOffset();
488
 
        xCellOffs = x / cellW;
489
 
        if ( !testTableFlags(Tbl_snapToHGrid) ) {
490
 
            xCellDelta  = (short)(x % cellW);
491
 
        } else {
492
 
            x           = xCellOffs*cellW;
493
 
            xCellDelta  = 0;
494
 
        }
495
 
    } else {
496
 
        int xn=0, xcd=0, col = 0;
497
 
        while ( col < nCols-1 && x >= xn+(xcd=cellWidth(col)) ) {
498
 
            xn += xcd;
499
 
            col++;
500
 
        }
501
 
        xCellOffs = col;
502
 
        if ( testTableFlags(Tbl_snapToHGrid) ) {
503
 
            xCellDelta = 0;
504
 
            x = xn;
505
 
        } else {
506
 
            xCellDelta = (short)(x-xn);
507
 
        }
508
 
    }
509
 
    if ( cellH ) {
510
 
        if ( y > maxYOffset() )
511
 
            y = maxYOffset();
512
 
        yCellOffs = y / cellH;
513
 
        if ( !testTableFlags(Tbl_snapToVGrid) ) {
514
 
            yCellDelta  = (short)(y % cellH);
515
 
        } else {
516
 
            y           = yCellOffs*cellH;
517
 
            yCellDelta  = 0;
518
 
        }
519
 
    } else {
520
 
        int yn=0, yrd=0, row=0;
521
 
        while ( row < nRows-1 && y >= yn+(yrd=cellHeight(row)) ) {
522
 
            yn += yrd;
523
 
            row++;
524
 
        }
525
 
        yCellOffs = row;
526
 
        if ( testTableFlags(Tbl_snapToVGrid) ) {
527
 
            yCellDelta = 0;
528
 
            y = yn;
529
 
        } else {
530
 
            yCellDelta = (short)(y-yn);
531
 
        }
532
 
    }
533
 
    int dx = (x - xOffs);
534
 
    int dy = (y - yOffs);
535
 
    xOffs = x;
536
 
    yOffs = y;
537
 
    if ( autoUpdate() && isVisible() )
538
 
        scroll( dx, dy );
539
 
    if ( updateScrBars )
540
 
        updateScrollBars( verValue | horValue );
541
 
}
542
 
 
543
 
 
544
 
/*!
545
 
  \overload int QtTableView::cellWidth() const
546
 
 
547
 
  Returns the column width in pixels.   Returns 0 if the columns have
548
 
  variable widths.
549
 
 
550
 
  \sa setCellWidth(), cellHeight()
551
 
*/
552
 
 
553
 
/*!
554
 
  Returns the width of column \a col in pixels.
555
 
 
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.
559
 
 
560
 
  \sa setCellWidth(), cellHeight(), totalWidth(), updateTableSize()
561
 
*/
562
 
 
563
 
int QtTableView::cellWidth( int )
564
 
{
565
 
    return cellW;
566
 
}
567
 
 
568
 
 
569
 
/*!
570
 
  Sets the width in pixels of the table cells to \a cellWidth.
571
 
 
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.
575
 
 
576
 
  \sa cellWidth(), setCellHeight(), totalWidth(), numCols()
577
 
*/
578
 
 
579
 
void QtTableView::setCellWidth( int cellWidth )
580
 
{
581
 
    if ( cellW == cellWidth )
582
 
        return;
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 );
587
 
        return;
588
 
    }
589
 
#endif
590
 
    cellW = (short)cellWidth;
591
 
 
592
 
    updateScrollBars( horSteps | horRange );
593
 
    if ( autoUpdate() && isVisible() )
594
 
        repaint();
595
 
 
596
 
}
597
 
 
598
 
/*!
599
 
  \overload int QtTableView::cellHeight() const
600
 
 
601
 
  Returns the row height, in pixels.  Returns 0 if the rows have
602
 
  variable heights.
603
 
 
604
 
  \sa setCellHeight(), cellWidth()
605
 
*/
606
 
 
607
 
 
608
 
/*!
609
 
  Returns the height of row \a row in pixels.
610
 
 
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.
614
 
 
615
 
  \sa setCellHeight(), cellWidth(), totalHeight()
616
 
*/
617
 
 
618
 
int QtTableView::cellHeight( int )
619
 
{
620
 
    return cellH;
621
 
}
622
 
 
623
 
/*!
624
 
  Sets the height in pixels of the table cells to \a cellHeight.
625
 
 
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.
629
 
 
630
 
  \sa cellHeight(), setCellWidth(), totalHeight(), numRows()
631
 
*/
632
 
 
633
 
void QtTableView::setCellHeight( int cellHeight )
634
 
{
635
 
    if ( cellH == cellHeight )
636
 
        return;
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 );
641
 
        return;
642
 
    }
643
 
#endif
644
 
    cellH = (short)cellHeight;
645
 
    if ( autoUpdate() && isVisible() )
646
 
        repaint();
647
 
    updateScrollBars( verSteps | verRange );
648
 
}
649
 
 
650
 
 
651
 
/*!
652
 
  Returns the total width of the table in pixels.
653
 
 
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.
657
 
 
658
 
  The default implementation may be slow for very wide tables.
659
 
 
660
 
  \sa cellWidth(), totalHeight() */
661
 
 
662
 
int QtTableView::totalWidth()
663
 
{
664
 
    if ( cellW ) {
665
 
        return cellW*nCols;
666
 
    } else {
667
 
        int tw = 0;
668
 
        for( int i = 0 ; i < nCols ; i++ )
669
 
            tw += cellWidth( i );
670
 
        return tw;
671
 
    }
672
 
}
673
 
 
674
 
/*!
675
 
  Returns the total height of the table in pixels.
676
 
 
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.
680
 
 
681
 
  The default implementation may be slow for very tall tables.
682
 
 
683
 
  \sa cellHeight(), totalWidth()
684
 
*/
685
 
 
686
 
int QtTableView::totalHeight()
687
 
{
688
 
    if ( cellH ) {
689
 
        return cellH*nRows;
690
 
    } else {
691
 
        int th = 0;
692
 
        for( int i = 0 ; i < nRows ; i++ )
693
 
            th += cellHeight( i );
694
 
        return th;
695
 
    }
696
 
}
697
 
 
698
 
 
699
 
/*!
700
 
  \fn uint QtTableView::tableFlags() const
701
 
 
702
 
  Returns the union of the table flags that are currently set.
703
 
 
704
 
  \sa setTableFlags(), clearTableFlags(), testTableFlags()
705
 
*/
706
 
 
707
 
/*!
708
 
  \fn bool QtTableView::testTableFlags( uint f ) const
709
 
 
710
 
  Returns TRUE if any of the table flags in \a f are currently set,
711
 
  otherwise FALSE.
712
 
 
713
 
  \sa setTableFlags(), clearTableFlags(), tableFlags()
714
 
*/
715
 
 
716
 
/*!
717
 
  Sets the table flags to \a f.
718
 
 
719
 
  If a flag setting changes the appearance of the table, the table is
720
 
  repainted if - and only if - autoUpdate() is TRUE.
721
 
 
722
 
  The table flags are mostly single bits, though there are some multibit
723
 
  flags for convenience. Here is a complete list:
724
 
 
725
 
  <dl compact>
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
735
 
  boundaries.
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.
764
 
  </dl>
765
 
 
766
 
  You can specify more than one flag at a time using bitwise OR.
767
 
 
768
 
  Example:
769
 
  \code
770
 
    setTableFlags( Tbl_smoothScrolling | Tbl_autoScrollBars );
771
 
  \endcode
772
 
 
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.
776
 
 
777
 
 
778
 
  \sa clearTableFlags(), testTableFlags(), tableFlags()
779
 
*/
780
 
 
781
 
void QtTableView::setTableFlags( uint f )
782
 
{
783
 
    f = (f ^ tFlags) & f;                       // clear flags already set
784
 
    tFlags |= f;
785
 
 
786
 
    bool updateOn = autoUpdate();
787
 
    setAutoUpdate( FALSE );
788
 
 
789
 
    uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
790
 
 
791
 
    if ( f & Tbl_vScrollBar ) {
792
 
        setVerScrollBar( TRUE );
793
 
    }
794
 
    if ( f & Tbl_hScrollBar ) {
795
 
        setHorScrollBar( TRUE );
796
 
    }
797
 
    if ( f & Tbl_autoVScrollBar ) {
798
 
        updateScrollBars( verRange );
799
 
    }
800
 
    if ( f & Tbl_autoHScrollBar ) {
801
 
        updateScrollBars( horRange );
802
 
    }
803
 
    if ( f & Tbl_scrollLastHCell ) {
804
 
        updateScrollBars( horRange );
805
 
    }
806
 
    if ( f & Tbl_scrollLastVCell ) {
807
 
        updateScrollBars( verRange );
808
 
    }
809
 
    if ( f & Tbl_snapToHGrid ) {
810
 
        updateScrollBars( horRange );
811
 
    }
812
 
    if ( f & Tbl_snapToVGrid ) {
813
 
        updateScrollBars( verRange );
814
 
    }
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
821
 
        }
822
 
    }
823
 
 
824
 
    if ( updateOn ) {
825
 
        setAutoUpdate( TRUE );
826
 
        updateScrollBars();
827
 
        if ( isVisible() && (f & repaintMask) )
828
 
            repaint();
829
 
    }
830
 
 
831
 
}
832
 
 
833
 
/*!
834
 
  Clears the \link setTableFlags() table flags\endlink that are set
835
 
  in \a f.
836
 
 
837
 
  Example (clears a single flag):
838
 
  \code
839
 
    clearTableFlags( Tbl_snapToGrid );
840
 
  \endcode
841
 
 
842
 
  The default argument clears all flags.
843
 
 
844
 
  \sa setTableFlags(), testTableFlags(), tableFlags()
845
 
*/
846
 
 
847
 
void QtTableView::clearTableFlags( uint f )
848
 
{
849
 
    f = (f ^ ~tFlags) & f;              // clear flags that are already 0
850
 
    tFlags &= ~f;
851
 
 
852
 
    bool updateOn = autoUpdate();
853
 
    setAutoUpdate( FALSE );
854
 
 
855
 
    uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
856
 
 
857
 
    if ( f & Tbl_vScrollBar ) {
858
 
        setVerScrollBar( FALSE );
859
 
    }
860
 
    if ( f & Tbl_hScrollBar ) {
861
 
        setHorScrollBar( FALSE );
862
 
    }
863
 
    if ( f & Tbl_scrollLastHCell ) {
864
 
        int maxX = maxXOffset();
865
 
        if ( xOffs > maxX ) {
866
 
            setOffset( maxX, yOffs );
867
 
            repaintMask |= Tbl_scrollLastHCell;
868
 
        }
869
 
        updateScrollBars( horRange );
870
 
    }
871
 
    if ( f & Tbl_scrollLastVCell ) {
872
 
        int maxY = maxYOffset();
873
 
        if ( yOffs > maxY ) {
874
 
            setOffset( xOffs, maxY );
875
 
            repaintMask |= Tbl_scrollLastVCell;
876
 
        }
877
 
        updateScrollBars( verRange );
878
 
    }
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
885
 
        }
886
 
    }
887
 
    if ( f & Tbl_snapToHGrid ) {
888
 
        updateScrollBars( horRange );
889
 
    }
890
 
    if ( f & Tbl_snapToVGrid ) {
891
 
        updateScrollBars( verRange );
892
 
    }
893
 
    if ( updateOn ) {
894
 
        setAutoUpdate( TRUE );
895
 
        updateScrollBars();          // returns immediately if nothing to do
896
 
        if ( isVisible() && (f & repaintMask) )
897
 
            repaint();
898
 
    }
899
 
 
900
 
}
901
 
 
902
 
 
903
 
/*!
904
 
  \fn bool QtTableView::autoUpdate() const
905
 
 
906
 
  Returns TRUE if the view updates itself automatically whenever it
907
 
  is changed in some way.
908
 
 
909
 
  \sa setAutoUpdate()
910
 
*/
911
 
 
912
 
/*!
913
 
  Sets the auto-update option of the table view to \a enable.
914
 
 
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).
918
 
 
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().
924
 
 
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.
928
 
 
929
 
  Setting auto-update to TRUE does not repaint the view; you must call
930
 
  repaint() to do this.
931
 
 
932
 
  \sa autoUpdate(), repaint()
933
 
*/
934
 
 
935
 
void QtTableView::setAutoUpdate( bool enable )
936
 
{
937
 
    if ( isUpdatesEnabled() == enable )
938
 
        return;
939
 
    setUpdatesEnabled( enable );
940
 
    if ( enable ) {
941
 
        showOrHideScrollBars();
942
 
        updateScrollBars();
943
 
    }
944
 
}
945
 
 
946
 
 
947
 
/*!
948
 
  Repaints the cell at row \a row, column \a col if it is inside the view.
949
 
 
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.
952
 
 
953
 
  \sa isVisible()
954
 
*/
955
 
 
956
 
void QtTableView::updateCell( int row, int col, bool erase )
957
 
{
958
 
    int xPos, yPos;
959
 
    if ( !colXPos( col, &xPos ) )
960
 
        return;
961
 
    if ( !rowYPos( row, &yPos ) )
962
 
        return;
963
 
    QRect uR = QRect( xPos, yPos,
964
 
                      cellW ? cellW : cellWidth(col),
965
 
                      cellH ? cellH : cellHeight(row) );
966
 
    repaint( uR.intersect(viewRect()), erase );
967
 
}
968
 
 
969
 
 
970
 
/*!
971
 
  \fn QRect QtTableView::cellUpdateRect() const
972
 
 
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
976
 
  paintCell().
977
 
 
978
 
*/
979
 
 
980
 
/*!
981
 
  Returns the rectangle that is the actual table, excluding any
982
 
  frame, in \e widget coordinates.
983
 
*/
984
 
 
985
 
QRect QtTableView::viewRect() const
986
 
{
987
 
    return QRect( frameWidth(), frameWidth(), viewWidth(), viewHeight() );
988
 
}
989
 
 
990
 
 
991
 
/*!
992
 
  Returns the index of the last (bottom) row in the view.
993
 
  The index of the first row is 0.
994
 
 
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.
997
 
 
998
 
  \sa lastColVisible()
999
 
*/
1000
 
 
1001
 
int QtTableView::lastRowVisible() const
1002
 
{
1003
 
    int cellMaxY;
1004
 
    int row = findRawRow( maxViewY(), &cellMaxY );
1005
 
    if ( row == -1 || row >= nRows ) {          // maxViewY() past end?
1006
 
        row = nRows - 1;                        // yes: return last row
1007
 
    } else {
1008
 
        if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() ) {
1009
 
            if ( row == yCellOffs )             // cut by right margin?
1010
 
                return -1;                      // yes, nothing in the view
1011
 
            else
1012
 
               row = row - 1;                   // cut by margin, one back
1013
 
        }
1014
 
    }
1015
 
    return row;
1016
 
}
1017
 
 
1018
 
/*!
1019
 
  Returns the index of the last (right) column in the view.
1020
 
  The index of the first column is 0.
1021
 
 
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.
1024
 
 
1025
 
  \sa lastRowVisible()
1026
 
*/
1027
 
 
1028
 
int QtTableView::lastColVisible() const
1029
 
{
1030
 
    int cellMaxX;
1031
 
    int col = findRawCol( maxViewX(), &cellMaxX );
1032
 
    if ( col == -1 || col >= nCols ) {          // maxViewX() past end?
1033
 
        col = nCols - 1;                        // yes: return last col
1034
 
    } else {
1035
 
        if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() ) {
1036
 
            if ( col == xCellOffs )             // cut by bottom margin?
1037
 
                return -1;                      // yes, nothing in the view
1038
 
            else
1039
 
               col = col - 1;                   // cell by margin, one back
1040
 
        }
1041
 
    }
1042
 
    return col;
1043
 
}
1044
 
 
1045
 
/*!
1046
 
  Returns TRUE if \a row is at least partially visible.
1047
 
  \sa colIsVisible()
1048
 
*/
1049
 
 
1050
 
bool QtTableView::rowIsVisible( int row ) const
1051
 
{
1052
 
    return rowYPos( row, 0 );
1053
 
}
1054
 
 
1055
 
/*!
1056
 
  Returns TRUE if \a col is at least partially visible.
1057
 
  \sa rowIsVisible()
1058
 
*/
1059
 
 
1060
 
bool QtTableView::colIsVisible( int col ) const
1061
 
{
1062
 
    return colXPos( col, 0 );
1063
 
}
1064
 
 
1065
 
 
1066
 
/*!
1067
 
  \internal
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.
1070
 
*/
1071
 
 
1072
 
void QtTableView::coverCornerSquare( bool enable )
1073
 
{
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,
1080
 
                                   VSBEXT,
1081
 
                                 HSBEXT);
1082
 
    }
1083
 
    if ( autoUpdate() && cornerSquare ) {
1084
 
        if ( enable )
1085
 
            cornerSquare->show();
1086
 
        else
1087
 
            cornerSquare->hide();
1088
 
    }
1089
 
}
1090
 
 
1091
 
 
1092
 
/*!
1093
 
  \internal
1094
 
  Scroll the view to a position such that:
1095
 
 
1096
 
  If \a horizontal is TRUE, the leftmost column shown fits snugly
1097
 
  with the left edge of the view.
1098
 
 
1099
 
  If \a vertical is TRUE, the top row shown fits snugly with the top
1100
 
  of the view.
1101
 
 
1102
 
  You can achieve the same effect automatically by setting any of the
1103
 
  \link setTableFlags() Tbl_snapTo*Grid \endlink table flags.
1104
 
*/
1105
 
 
1106
 
void QtTableView::snapToGrid( bool horizontal, bool vertical )
1107
 
{
1108
 
    int newXCell = -1;
1109
 
    int newYCell = -1;
1110
 
    if ( horizontal && xCellDelta != 0 ) {
1111
 
        int w = cellW ? cellW : cellWidth( xCellOffs );
1112
 
        if ( xCellDelta >= w/2 )
1113
 
            newXCell = xCellOffs + 1;
1114
 
        else
1115
 
            newXCell = xCellOffs;
1116
 
    }
1117
 
    if ( vertical && yCellDelta != 0 ) {
1118
 
        int h = cellH ? cellH : cellHeight( yCellOffs );
1119
 
        if ( yCellDelta >= h/2 )
1120
 
            newYCell = yCellOffs + 1;
1121
 
        else
1122
 
            newYCell = yCellOffs;
1123
 
    }
1124
 
    setTopLeftCell( newYCell, newXCell );  //row,column
1125
 
}
1126
 
 
1127
 
/*!
1128
 
  \internal
1129
 
  This internal slot is connected to the horizontal scroll bar's
1130
 
  QScrollBar::valueChanged() signal.
1131
 
 
1132
 
  Moves the table horizontally to offset \a val without updating the
1133
 
  scroll bar.
1134
 
*/
1135
 
 
1136
 
void QtTableView::horSbValue( int val )
1137
 
{
1138
 
    if ( horSliding ) {
1139
 
        horSliding = FALSE;
1140
 
        if ( horSnappingOff ) {
1141
 
            horSnappingOff = FALSE;
1142
 
            tFlags |= Tbl_snapToHGrid;
1143
 
        }
1144
 
    }
1145
 
    setOffset( val, yOffs, FALSE );
1146
 
}
1147
 
 
1148
 
/*!
1149
 
  \internal
1150
 
  This internal slot is connected to the horizontal scroll bar's
1151
 
  QScrollBar::sliderMoved() signal.
1152
 
 
1153
 
  Scrolls the table smoothly horizontally even if \c Tbl_snapToHGrid is set.
1154
 
*/
1155
 
 
1156
 
void QtTableView::horSbSliding( int val )
1157
 
{
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
1163
 
    } else {
1164
 
        setOffset( val, yOffs, FALSE );
1165
 
    }
1166
 
}
1167
 
 
1168
 
/*!
1169
 
  \internal
1170
 
  This internal slot is connected to the horizontal scroll bar's
1171
 
  QScrollBar::sliderReleased() signal.
1172
 
*/
1173
 
 
1174
 
void QtTableView::horSbSlidingDone( )
1175
 
{
1176
 
    if ( testTableFlags(Tbl_snapToHGrid) &&
1177
 
         testTableFlags(Tbl_smoothHScrolling) )
1178
 
        snapToGrid( TRUE, FALSE );
1179
 
}
1180
 
 
1181
 
/*!
1182
 
  \internal
1183
 
  This internal slot is connected to the vertical scroll bar's
1184
 
  QScrollBar::valueChanged() signal.
1185
 
 
1186
 
  Moves the table vertically to offset \a val without updating the
1187
 
  scroll bar.
1188
 
*/
1189
 
 
1190
 
void QtTableView::verSbValue( int val )
1191
 
{
1192
 
    if ( verSliding ) {
1193
 
        verSliding = FALSE;
1194
 
        if ( verSnappingOff ) {
1195
 
            verSnappingOff = FALSE;
1196
 
            tFlags |= Tbl_snapToVGrid;
1197
 
        }
1198
 
    }
1199
 
    setOffset( xOffs, val, FALSE );
1200
 
}
1201
 
 
1202
 
/*!
1203
 
  \internal
1204
 
  This internal slot is connected to the vertical scroll bar's
1205
 
  QScrollBar::sliderMoved() signal.
1206
 
 
1207
 
  Scrolls the table smoothly vertically even if \c Tbl_snapToVGrid is set.
1208
 
*/
1209
 
 
1210
 
void QtTableView::verSbSliding( int val )
1211
 
{
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
1217
 
    } else {
1218
 
        setOffset( xOffs, val, FALSE );
1219
 
    }
1220
 
}
1221
 
 
1222
 
/*!
1223
 
  \internal
1224
 
  This internal slot is connected to the vertical scroll bar's
1225
 
  QScrollBar::sliderReleased() signal.
1226
 
*/
1227
 
 
1228
 
void QtTableView::verSbSlidingDone( )
1229
 
{
1230
 
    if ( testTableFlags(Tbl_snapToVGrid) &&
1231
 
         testTableFlags(Tbl_smoothVScrolling) )
1232
 
        snapToGrid( FALSE, TRUE );
1233
 
}
1234
 
 
1235
 
 
1236
 
/*!
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.
1241
 
*/
1242
 
 
1243
 
void QtTableView::setupPainter( QPainter * )
1244
 
{
1245
 
}
1246
 
 
1247
 
/*!
1248
 
  \fn void QtTableView::paintCell( QPainter *p, int row, int col )
1249
 
 
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
1252
 
  must remain open.
1253
 
 
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
1258
 
  return).
1259
 
 
1260
 
  The painter is not clipped by default and for maximum efficiency. For safety,
1261
 
  call setTableFlags(Tbl_clipCellPainting) to enable clipping.
1262
 
 
1263
 
  \sa paintEvent(), setTableFlags() */
1264
 
 
1265
 
 
1266
 
/*!
1267
 
  Handles paint events, \a e, for the table view.
1268
 
 
1269
 
  Calls paintCell() for the cells that needs to be repainted.
1270
 
*/
1271
 
 
1272
 
void QtTableView::paintEvent( QPaintEvent *e )
1273
 
{
1274
 
    QRect updateR = e->rect();                  // update rectangle
1275
 
    if ( sbDirty ) {
1276
 
        bool e = eraseInPaint;
1277
 
        updateScrollBars();
1278
 
        eraseInPaint = e;
1279
 
    }
1280
 
 
1281
 
    QPainter paint( this );
1282
 
 
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() );
1289
 
    }
1290
 
 
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 );
1297
 
 
1298
 
    setupPainter( &paint );                     // prepare for painting table
1299
 
 
1300
 
    int firstRow = findRow( updateR.y() );
1301
 
    int firstCol = findCol( updateR.x() );
1302
 
    int  xStart, yStart;
1303
 
    if ( !colXPos( firstCol, &xStart ) || !rowYPos( firstRow, &yStart ) ) {
1304
 
        paint.eraseRect( updateR ); // erase area outside cells but in view
1305
 
        return;
1306
 
    }
1307
 
    int   maxX  = updateR.right();
1308
 
    int   maxY  = updateR.bottom();
1309
 
    int   row   = firstRow;
1310
 
    int   col;
1311
 
    int   yPos  = yStart;
1312
 
    int   xPos = maxX+1; // in case the while() is empty
1313
 
    int   nextX;
1314
 
    int   nextY;
1315
 
    QRect winR = viewRect();
1316
 
    QRect cellR;
1317
 
    QRect cellUR;
1318
 
#ifndef QT_NO_TRANSFORMATIONS
1319
 
    QWMatrix matrix;
1320
 
#endif
1321
 
 
1322
 
    while ( yPos <= maxY && row < nRows ) {
1323
 
        nextY = yPos + (cellH ? cellH : cellHeight( row ));
1324
 
        if ( testTableFlags( Tbl_cutCellsV ) && nextY > ( maxWY + 1 ) )
1325
 
            break;
1326
 
        col  = firstCol;
1327
 
        xPos = xStart;
1328
 
        while ( xPos <= maxX && col < nCols ) {
1329
 
            nextX = xPos + (cellW ? cellW : cellWidth( col ));
1330
 
            if ( testTableFlags( Tbl_cutCellsH ) && nextX > ( maxWX + 1 ) )
1331
 
                break;
1332
 
 
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
1339
 
                if ( eraseInPaint )
1340
 
                    paint.eraseRect( cellUR );
1341
 
 
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 );
1350
 
                } else {
1351
 
                    paintCell( &paint, row, col );
1352
 
                }
1353
 
                matrix.reset();
1354
 
                paint.setWorldMatrix( matrix );
1355
 
#else
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 );
1362
 
                } else {
1363
 
                    paintCell( &paint, row, col );
1364
 
                }
1365
 
                paint.translate( -xPos, -yPos );
1366
 
#endif
1367
 
            }
1368
 
            col++;
1369
 
            xPos = nextX;
1370
 
        }
1371
 
        row++;
1372
 
        yPos = nextY;
1373
 
    }
1374
 
 
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.
1379
 
 
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.
1386
 
 
1387
 
    QRect viewR = viewRect();
1388
 
    const QColorGroup g = colorGroup();
1389
 
 
1390
 
    if ( xPos <= maxX ) {
1391
 
        QRect r = viewR;
1392
 
        r.setLeft( xPos );
1393
 
        r.setBottom( yPos<maxY?yPos:maxY );
1394
 
        if ( inherits( "QMultiLineEdit" ) )
1395
 
            paint.fillRect( r.intersect( updateR ), g.base() );
1396
 
        else
1397
 
            paint.eraseRect( r.intersect( updateR ) );
1398
 
    }
1399
 
    if ( yPos <= maxY ) {
1400
 
        QRect r = viewR;
1401
 
        r.setTop( yPos );
1402
 
        if ( inherits( "QMultiLineEdit" ) )
1403
 
            paint.fillRect( r.intersect( updateR ), g.base() );
1404
 
        else
1405
 
            paint.eraseRect( r.intersect( updateR ) );
1406
 
    }
1407
 
}
1408
 
 
1409
 
/*!\reimp
1410
 
*/
1411
 
void QtTableView::resizeEvent( QResizeEvent * )
1412
 
{
1413
 
    updateScrollBars( horValue | verValue | horSteps | horGeometry | horRange |
1414
 
                      verSteps | verGeometry | verRange );
1415
 
    showOrHideScrollBars();
1416
 
    updateFrameSize();
1417
 
    int maxX = QMIN( xOffs, maxXOffset() );                     // ### can be slow
1418
 
    int maxY = QMIN( yOffs, maxYOffset() );
1419
 
    setOffset( maxX, maxY );
1420
 
}
1421
 
 
1422
 
 
1423
 
/*!
1424
 
  Redraws all visible cells in the table view.
1425
 
*/
1426
 
 
1427
 
void QtTableView::updateView()
1428
 
{
1429
 
    repaint( viewRect() );
1430
 
}
1431
 
 
1432
 
/*!
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.
1436
 
*/
1437
 
 
1438
 
QScrollBar *QtTableView::verticalScrollBar() const
1439
 
{
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 );
1445
 
#endif
1446
 
        sb->resize( sb->sizeHint() ); // height is irrelevant
1447
 
        Q_CHECK_PTR(sb);
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()));
1456
 
        sb->hide();
1457
 
        that->vScrollBar = sb;
1458
 
        return sb;
1459
 
    }
1460
 
    return vScrollBar;
1461
 
}
1462
 
 
1463
 
/*!
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.
1467
 
*/
1468
 
 
1469
 
QScrollBar *QtTableView::horizontalScrollBar() const
1470
 
{
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 );
1476
 
#endif
1477
 
        sb->resize( sb->sizeHint() ); // width is irrelevant
1478
 
        sb->setFocusPolicy( NoFocus );
1479
 
        Q_CHECK_PTR(sb);
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()));
1487
 
        sb->hide();
1488
 
        that->hScrollBar = sb;
1489
 
        return sb;
1490
 
    }
1491
 
    return hScrollBar;
1492
 
}
1493
 
 
1494
 
/*!
1495
 
  Enables or disables the horizontal scroll bar, as required by
1496
 
  setAutoUpdate() and the \link setTableFlags() table flags\endlink.
1497
 
*/
1498
 
 
1499
 
void QtTableView::setHorScrollBar( bool on, bool update )
1500
 
{
1501
 
    if ( on ) {
1502
 
        tFlags |= Tbl_hScrollBar;
1503
 
        horizontalScrollBar(); // created
1504
 
        if ( update )
1505
 
            updateScrollBars( horMask | verMask );
1506
 
        else
1507
 
            sbDirty = sbDirty | (horMask | verMask);
1508
 
        if ( testTableFlags( Tbl_vScrollBar ) )
1509
 
            coverCornerSquare( TRUE );
1510
 
        if ( autoUpdate() )
1511
 
            sbDirty = sbDirty | horMask;
1512
 
    } else {
1513
 
        tFlags &= ~Tbl_hScrollBar;
1514
 
        if ( !hScrollBar )
1515
 
            return;
1516
 
        coverCornerSquare( FALSE );
1517
 
        bool hideScrollBar = autoUpdate() && hScrollBar->isVisible();
1518
 
        if ( hideScrollBar )
1519
 
            hScrollBar->hide();
1520
 
        if ( update )
1521
 
            updateScrollBars( verMask );
1522
 
        else
1523
 
            sbDirty = sbDirty | verMask;
1524
 
        if ( hideScrollBar && isVisible() )
1525
 
            repaint( hScrollBar->x(), hScrollBar->y(),
1526
 
                     width() - hScrollBar->x(), hScrollBar->height() );
1527
 
    }
1528
 
    if ( update )
1529
 
        updateFrameSize();
1530
 
}
1531
 
 
1532
 
 
1533
 
/*!
1534
 
  Enables or disables the vertical scroll bar, as required by
1535
 
  setAutoUpdate() and the \link setTableFlags() table flags\endlink.
1536
 
*/
1537
 
 
1538
 
void QtTableView::setVerScrollBar( bool on, bool update )
1539
 
{
1540
 
    if ( on ) {
1541
 
        tFlags |= Tbl_vScrollBar;
1542
 
        verticalScrollBar(); // created
1543
 
        if ( update )
1544
 
            updateScrollBars( verMask | horMask );
1545
 
        else
1546
 
            sbDirty = sbDirty | (horMask | verMask);
1547
 
        if ( testTableFlags( Tbl_hScrollBar ) )
1548
 
            coverCornerSquare( TRUE );
1549
 
        if ( autoUpdate() )
1550
 
            sbDirty = sbDirty | verMask;
1551
 
    } else {
1552
 
        tFlags &= ~Tbl_vScrollBar;
1553
 
        if ( !vScrollBar )
1554
 
            return;
1555
 
        coverCornerSquare( FALSE );
1556
 
        bool hideScrollBar = autoUpdate() && vScrollBar->isVisible();
1557
 
        if ( hideScrollBar )
1558
 
            vScrollBar->hide();
1559
 
        if ( update )
1560
 
            updateScrollBars( horMask );
1561
 
        else
1562
 
            sbDirty = sbDirty | horMask;
1563
 
        if ( hideScrollBar && isVisible() )
1564
 
            repaint( vScrollBar->x(), vScrollBar->y(),
1565
 
                     vScrollBar->width(), height() - vScrollBar->y() );
1566
 
    }
1567
 
    if ( update )
1568
 
        updateFrameSize();
1569
 
}
1570
 
 
1571
 
 
1572
 
 
1573
 
 
1574
 
int QtTableView::findRawRow( int yPos, int *cellMaxY, int *cellMinY,
1575
 
                            bool goOutsideView ) const
1576
 
{
1577
 
    int r = -1;
1578
 
    if ( nRows == 0 )
1579
 
        return r;
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 );
1587
 
#endif
1588
 
            return -1;
1589
 
        }
1590
 
        if ( cellH ) {                               // uniform cell height
1591
 
            r = (yPos - minViewY() + yCellDelta)/cellH; // cell offs from top
1592
 
            if ( cellMaxY )
1593
 
                *cellMaxY = (r + 1)*cellH + minViewY() - yCellDelta - 1;
1594
 
            if ( cellMinY )
1595
 
                *cellMinY = r*cellH + minViewY() - yCellDelta;
1596
 
            r += yCellOffs;                          // absolute cell index
1597
 
        } else {                                     // variable cell height
1598
 
            QtTableView *tw = (QtTableView *)this;
1599
 
            r        = yCellOffs;
1600
 
            int h    = minViewY() - yCellDelta; //##arnt3
1601
 
            int oldH = h;
1602
 
            Q_ASSERT( r < nRows );
1603
 
            while ( r < nRows ) {
1604
 
                oldH = h;
1605
 
                h += tw->cellHeight( r );            // Start of next cell
1606
 
                if ( yPos < h )
1607
 
                    break;
1608
 
                r++;
1609
 
            }
1610
 
            if ( cellMaxY )
1611
 
                *cellMaxY = h - 1;
1612
 
            if ( cellMinY )
1613
 
                *cellMinY = oldH;
1614
 
        }
1615
 
    }
1616
 
    return r;
1617
 
 
1618
 
}
1619
 
 
1620
 
 
1621
 
int QtTableView::findRawCol( int xPos, int *cellMaxX, int *cellMinX ,
1622
 
                            bool goOutsideView ) const
1623
 
{
1624
 
    int c = -1;
1625
 
    if ( nCols == 0 )
1626
 
        return c;
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 );
1634
 
#endif
1635
 
            return -1;
1636
 
        }
1637
 
        if ( cellW ) {                          // uniform cell width
1638
 
            c = (xPos - minViewX() + xCellDelta)/cellW; //cell offs from left
1639
 
            if ( cellMaxX )
1640
 
                *cellMaxX = (c + 1)*cellW + minViewX() - xCellDelta - 1;
1641
 
            if ( cellMinX )
1642
 
                *cellMinX = c*cellW + minViewX() - xCellDelta;
1643
 
            c += xCellOffs;                     // absolute cell index
1644
 
        } else {                                // variable cell width
1645
 
            QtTableView *tw = (QtTableView *)this;
1646
 
            c        = xCellOffs;
1647
 
            int w    = minViewX() - xCellDelta; //##arnt3
1648
 
            int oldW = w;
1649
 
            Q_ASSERT( c < nCols );
1650
 
            while ( c < nCols ) {
1651
 
                oldW = w;
1652
 
                w += tw->cellWidth( c );        // Start of next cell
1653
 
                if ( xPos < w )
1654
 
                    break;
1655
 
                c++;
1656
 
            }
1657
 
            if ( cellMaxX )
1658
 
                *cellMaxX = w - 1;
1659
 
            if ( cellMinX )
1660
 
                *cellMinX = oldW;
1661
 
        }
1662
 
    }
1663
 
    return c;
1664
 
}
1665
 
 
1666
 
 
1667
 
/*!
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
1670
 
  range.
1671
 
 
1672
 
  \sa findCol(), rowYPos()
1673
 
*/
1674
 
 
1675
 
int QtTableView::findRow( int yPos ) const
1676
 
{
1677
 
    int cellMaxY;
1678
 
    int row = findRawRow( yPos, &cellMaxY );
1679
 
    if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() )
1680
 
        row = - 1;                              //  cell cut by bottom margin
1681
 
    if ( row >= nRows )
1682
 
        row = -1;
1683
 
    return row;
1684
 
}
1685
 
 
1686
 
 
1687
 
/*!
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
1690
 
  range.
1691
 
 
1692
 
  \sa findRow(), colXPos()
1693
 
*/
1694
 
 
1695
 
int QtTableView::findCol( int xPos ) const
1696
 
{
1697
 
    int cellMaxX;
1698
 
    int col = findRawCol( xPos, &cellMaxX );
1699
 
    if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() )
1700
 
        col = - 1;                              //  cell cut by right margin
1701
 
    if ( col >= nCols )
1702
 
        col = -1;
1703
 
    return col;
1704
 
}
1705
 
 
1706
 
 
1707
 
/*!
1708
 
  Computes the position in the widget of row \a row.
1709
 
 
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.
1713
 
 
1714
 
  \sa colXPos(), findRow()
1715
 
*/
1716
 
 
1717
 
bool QtTableView::rowYPos( int row, int *yPos ) const
1718
 
{
1719
 
    int y;
1720
 
    if ( row >= yCellOffs ) {
1721
 
        if ( cellH ) {
1722
 
            int lastVisible = lastRowVisible();
1723
 
            if ( row > lastVisible || lastVisible == -1 )
1724
 
                return FALSE;
1725
 
            y = (row - yCellOffs)*cellH + minViewY() - yCellDelta;
1726
 
        } else {
1727
 
            //##arnt3
1728
 
            y = minViewY() - yCellDelta;        // y of leftmost cell in view
1729
 
            int r = yCellOffs;
1730
 
            QtTableView *tw = (QtTableView *)this;
1731
 
            int maxY = maxViewY();
1732
 
            while ( r < row && y <= maxY )
1733
 
                y += tw->cellHeight( r++ );
1734
 
            if ( y > maxY )
1735
 
                return FALSE;
1736
 
 
1737
 
        }
1738
 
    } else {
1739
 
        return FALSE;
1740
 
    }
1741
 
    if ( yPos )
1742
 
        *yPos = y;
1743
 
    return TRUE;
1744
 
}
1745
 
 
1746
 
 
1747
 
/*!
1748
 
  Computes the position in the widget of column \a col.
1749
 
 
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.
1753
 
 
1754
 
  \sa rowYPos(), findCol()
1755
 
*/
1756
 
 
1757
 
bool QtTableView::colXPos( int col, int *xPos ) const
1758
 
{
1759
 
    int x;
1760
 
    if ( col >= xCellOffs ) {
1761
 
        if ( cellW ) {
1762
 
            int lastVisible = lastColVisible();
1763
 
            if ( col > lastVisible || lastVisible == -1 )
1764
 
                return FALSE;
1765
 
            x = (col - xCellOffs)*cellW + minViewX() - xCellDelta;
1766
 
        } else {
1767
 
            //##arnt3
1768
 
            x = minViewX() - xCellDelta;        // x of uppermost cell in view
1769
 
            int c = xCellOffs;
1770
 
            QtTableView *tw = (QtTableView *)this;
1771
 
            int maxX = maxViewX();
1772
 
            while ( c < col && x <= maxX )
1773
 
                x += tw->cellWidth( c++ );
1774
 
            if ( x > maxX )
1775
 
                return FALSE;
1776
 
        }
1777
 
    } else {
1778
 
        return FALSE;
1779
 
    }
1780
 
    if ( xPos )
1781
 
        *xPos = x;
1782
 
    return TRUE;
1783
 
}
1784
 
 
1785
 
 
1786
 
/*!
1787
 
  Moves the visible area of the table right by \a xPixels and
1788
 
  down by \a yPixels pixels.  Both may be negative.
1789
 
 
1790
 
  \warning You might find that QScrollView offers a higher-level of
1791
 
        functionality than using QtTableView and this function.
1792
 
 
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.
1795
 
 
1796
 
  \sa setXOffset(), setYOffset(), setOffset(), setTopCell(),
1797
 
  setLeftCell()
1798
 
*/
1799
 
 
1800
 
void QtTableView::scroll( int xPixels, int yPixels )
1801
 
{
1802
 
    QWidget::scroll( -xPixels, -yPixels, contentsRect() );
1803
 
}
1804
 
 
1805
 
 
1806
 
/*!
1807
 
  Returns the leftmost pixel of the table view in \e view
1808
 
  coordinates.  This excludes the frame and any header.
1809
 
 
1810
 
  \sa maxViewY(), viewWidth(), contentsRect()
1811
 
*/
1812
 
 
1813
 
int QtTableView::minViewX() const
1814
 
{
1815
 
    return frameWidth();
1816
 
}
1817
 
 
1818
 
 
1819
 
/*!
1820
 
  Returns the top pixel of the table view in \e view
1821
 
  coordinates.  This excludes the frame and any header.
1822
 
 
1823
 
  \sa maxViewX(), viewHeight(), contentsRect()
1824
 
*/
1825
 
 
1826
 
int QtTableView::minViewY() const
1827
 
{
1828
 
    return frameWidth();
1829
 
}
1830
 
 
1831
 
 
1832
 
/*!
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.
1836
 
 
1837
 
  \sa maxViewY(), viewWidth(), contentsRect()
1838
 
*/
1839
 
 
1840
 
int QtTableView::maxViewX() const
1841
 
{
1842
 
    return width() - 1 - frameWidth()
1843
 
        - (tFlags & Tbl_vScrollBar ? VSBEXT
1844
 
           : 0);
1845
 
}
1846
 
 
1847
 
 
1848
 
/*!
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.
1852
 
 
1853
 
  \sa maxViewX(), viewHeight(), contentsRect()
1854
 
*/
1855
 
 
1856
 
int QtTableView::maxViewY() const
1857
 
{
1858
 
    return height() - 1 - frameWidth()
1859
 
        - (tFlags & Tbl_hScrollBar ? HSBEXT
1860
 
           : 0);
1861
 
}
1862
 
 
1863
 
 
1864
 
/*!
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.
1868
 
 
1869
 
  \sa minViewX() maxViewX(), viewHeight(), contentsRect() viewRect()
1870
 
*/
1871
 
 
1872
 
int QtTableView::viewWidth() const
1873
 
{
1874
 
    return maxViewX() - minViewX() + 1;
1875
 
}
1876
 
 
1877
 
 
1878
 
/*!
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.
1882
 
 
1883
 
  \sa minViewY() maxViewY() viewWidth() contentsRect() viewRect()
1884
 
*/
1885
 
 
1886
 
int QtTableView::viewHeight() const
1887
 
{
1888
 
    return maxViewY() - minViewY() + 1;
1889
 
}
1890
 
 
1891
 
 
1892
 
void QtTableView::doAutoScrollBars()
1893
 
{
1894
 
    int viewW = width()  - frameWidth() - minViewX();
1895
 
    int viewH = height() - frameWidth() - minViewY();
1896
 
    bool vScrollOn = testTableFlags(Tbl_vScrollBar);
1897
 
    bool hScrollOn = testTableFlags(Tbl_hScrollBar);
1898
 
    int w = 0;
1899
 
    int h = 0;
1900
 
    int i;
1901
 
 
1902
 
    if ( testTableFlags(Tbl_autoHScrollBar) ) {
1903
 
        if ( cellW ) {
1904
 
            w = cellW*nCols;
1905
 
        } else {
1906
 
            i = 0;
1907
 
            while ( i < nCols && w <= viewW )
1908
 
                w += cellWidth( i++ );
1909
 
        }
1910
 
        if ( w > viewW )
1911
 
            hScrollOn = TRUE;
1912
 
        else
1913
 
            hScrollOn = FALSE;
1914
 
    }
1915
 
 
1916
 
    if ( testTableFlags(Tbl_autoVScrollBar) ) {
1917
 
        if ( cellH ) {
1918
 
            h = cellH*nRows;
1919
 
        } else {
1920
 
            i = 0;
1921
 
            while ( i < nRows && h <= viewH )
1922
 
                h += cellHeight( i++ );
1923
 
        }
1924
 
 
1925
 
        if ( h > viewH )
1926
 
            vScrollOn = TRUE;
1927
 
        else
1928
 
            vScrollOn = FALSE;
1929
 
    }
1930
 
 
1931
 
    if ( testTableFlags(Tbl_autoHScrollBar) && vScrollOn && !hScrollOn )
1932
 
        if ( w > viewW - VSBEXT )
1933
 
            hScrollOn = TRUE;
1934
 
 
1935
 
    if ( testTableFlags(Tbl_autoVScrollBar) && hScrollOn && !vScrollOn )
1936
 
        if ( h > viewH - HSBEXT )
1937
 
            vScrollOn = TRUE;
1938
 
 
1939
 
    setHorScrollBar( hScrollOn, FALSE );
1940
 
    setVerScrollBar( vScrollOn, FALSE );
1941
 
    updateFrameSize();
1942
 
}
1943
 
 
1944
 
 
1945
 
/*!
1946
 
  \fn void QtTableView::updateScrollBars()
1947
 
 
1948
 
  Updates the scroll bars' contents and presence to match the table's
1949
 
  state.  Generally, you should not need to call this.
1950
 
 
1951
 
  \sa setTableFlags()
1952
 
*/
1953
 
 
1954
 
/*!
1955
 
  Updates the scroll bars' contents and presence to match the table's
1956
 
  state \c or \a f.
1957
 
 
1958
 
  \sa setTableFlags()
1959
 
*/
1960
 
 
1961
 
void QtTableView::updateScrollBars( uint f )
1962
 
{
1963
 
    sbDirty = sbDirty | f;
1964
 
    if ( inSbUpdate )
1965
 
        return;
1966
 
    inSbUpdate = TRUE;
1967
 
 
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
1972
 
 
1973
 
    if ( !autoUpdate() ) {
1974
 
        inSbUpdate = FALSE;
1975
 
        return;
1976
 
    }
1977
 
    if ( yOffset() > 0 && testTableFlags( Tbl_autoVScrollBar ) &&
1978
 
         !testTableFlags( Tbl_vScrollBar ) ) {
1979
 
        setYOffset( 0 );
1980
 
    }
1981
 
    if ( xOffset() > 0 && testTableFlags( Tbl_autoHScrollBar ) &&
1982
 
         !testTableFlags( Tbl_hScrollBar ) ) {
1983
 
        setXOffset( 0 );
1984
 
    }
1985
 
    if ( !isVisible() ) {
1986
 
        inSbUpdate = FALSE;
1987
 
        return;
1988
 
    }
1989
 
 
1990
 
    if ( testTableFlags(Tbl_hScrollBar) && (sbDirty & horMask) != 0 ) {
1991
 
        if ( sbDirty & horGeometry )
1992
 
            hScrollBar->setGeometry( 0,height() - HSBEXT,
1993
 
                                     viewWidth() + frameWidth()*2,
1994
 
                                   HSBEXT);
1995
 
 
1996
 
        if ( sbDirty & horSteps ) {
1997
 
            if ( cellW )
1998
 
                hScrollBar->setSteps( QMIN(cellW,viewWidth()/2), viewWidth() );
1999
 
            else
2000
 
                hScrollBar->setSteps( 16, viewWidth() );
2001
 
        }
2002
 
 
2003
 
        if ( sbDirty & horRange )
2004
 
            hScrollBar->setRange( 0, maxXOffset() );
2005
 
 
2006
 
        if ( sbDirty & horValue )
2007
 
            hScrollBar->setValue( xOffs );
2008
 
 
2009
 
                        // show scrollbar only when it has a sane geometry
2010
 
        if ( !hScrollBar->isVisible() )
2011
 
            hScrollBar->show();
2012
 
    }
2013
 
 
2014
 
    if ( testTableFlags(Tbl_vScrollBar) && (sbDirty & verMask) != 0 ) {
2015
 
        if ( sbDirty & verGeometry )
2016
 
            vScrollBar->setGeometry( width() - VSBEXT, 0,
2017
 
                                     VSBEXT,
2018
 
                                     viewHeight() + frameWidth()*2 );
2019
 
 
2020
 
        if ( sbDirty & verSteps ) {
2021
 
            if ( cellH )
2022
 
                vScrollBar->setSteps( QMIN(cellH,viewHeight()/2), viewHeight() );
2023
 
            else
2024
 
                vScrollBar->setSteps( 16, viewHeight() );  // fttb! ###
2025
 
        }
2026
 
 
2027
 
        if ( sbDirty & verRange )
2028
 
            vScrollBar->setRange( 0, maxYOffset() );
2029
 
 
2030
 
        if ( sbDirty & verValue )
2031
 
            vScrollBar->setValue( yOffs );
2032
 
 
2033
 
                        // show scrollbar only when it has a sane geometry
2034
 
        if ( !vScrollBar->isVisible() )
2035
 
            vScrollBar->show();
2036
 
    }
2037
 
    if ( coveringCornerSquare &&
2038
 
         ( (sbDirty & verGeometry ) || (sbDirty & horGeometry)) )
2039
 
        cornerSquare->move( maxViewX() + frameWidth() + 1,
2040
 
                            maxViewY() + frameWidth() + 1 );
2041
 
 
2042
 
    sbDirty = 0;
2043
 
    inSbUpdate = FALSE;
2044
 
}
2045
 
 
2046
 
 
2047
 
void QtTableView::updateFrameSize()
2048
 
{
2049
 
    int rw = width()  - ( testTableFlags(Tbl_vScrollBar) ?
2050
 
                          VSBEXT : 0 );
2051
 
    int rh = height() - ( testTableFlags(Tbl_hScrollBar) ?
2052
 
                          HSBEXT : 0 );
2053
 
    if ( rw < 0 )
2054
 
        rw = 0;
2055
 
    if ( rh < 0 )
2056
 
        rh = 0;
2057
 
 
2058
 
    if ( autoUpdate() ) {
2059
 
        int fh = frameRect().height();
2060
 
        int fw = frameRect().width();
2061
 
        setFrameRect( QRect(0,0,rw,rh) );
2062
 
 
2063
 
        if ( rw != fw )
2064
 
            update( QMIN(fw,rw) - frameWidth() - 2, 0, frameWidth()+4, rh );
2065
 
        if ( rh != fh )
2066
 
            update( 0, QMIN(fh,rh) - frameWidth() - 2, rw, frameWidth()+4 );
2067
 
    }
2068
 
}
2069
 
 
2070
 
 
2071
 
/*!
2072
 
  Returns the maximum horizontal offset within the table of the
2073
 
  view's left edge in \e table coordinates.
2074
 
 
2075
 
  This is used mainly to set the horizontal scroll bar's range.
2076
 
 
2077
 
  \sa maxColOffset(), maxYOffset(), totalWidth()
2078
 
*/
2079
 
 
2080
 
int QtTableView::maxXOffset()
2081
 
{
2082
 
    int tw = totalWidth();
2083
 
    int maxOffs;
2084
 
    if ( testTableFlags(Tbl_scrollLastHCell) ) {
2085
 
        if ( nCols != 1)
2086
 
            maxOffs =  tw - ( cellW ? cellW : cellWidth( nCols - 1 ) );
2087
 
        else
2088
 
            maxOffs = tw - viewWidth();
2089
 
    } else {
2090
 
        if ( testTableFlags(Tbl_snapToHGrid) ) {
2091
 
            if ( cellW ) {
2092
 
                maxOffs =  tw - (viewWidth()/cellW)*cellW;
2093
 
            } else {
2094
 
                int goal = tw - viewWidth();
2095
 
                int pos = tw;
2096
 
                int nextCol = nCols - 1;
2097
 
                int nextCellWidth = cellWidth( nextCol );
2098
 
                while( nextCol > 0 && pos > goal + nextCellWidth ) {
2099
 
                    pos -= nextCellWidth;
2100
 
                    nextCellWidth = cellWidth( --nextCol );
2101
 
                }
2102
 
                if ( goal + nextCellWidth == pos )
2103
 
                    maxOffs = goal;
2104
 
                 else if ( goal < pos )
2105
 
                   maxOffs = pos;
2106
 
                 else
2107
 
                   maxOffs = 0;
2108
 
            }
2109
 
        } else {
2110
 
            maxOffs = tw - viewWidth();
2111
 
        }
2112
 
    }
2113
 
    return maxOffs > 0 ? maxOffs : 0;
2114
 
}
2115
 
 
2116
 
 
2117
 
/*!
2118
 
  Returns the maximum vertical offset within the table of the
2119
 
  view's top edge in \e table coordinates.
2120
 
 
2121
 
  This is used mainly to set the vertical scroll bar's range.
2122
 
 
2123
 
  \sa maxRowOffset(), maxXOffset(), totalHeight()
2124
 
*/
2125
 
 
2126
 
int QtTableView::maxYOffset()
2127
 
{
2128
 
    int th = totalHeight();
2129
 
    int maxOffs;
2130
 
    if ( testTableFlags(Tbl_scrollLastVCell) ) {
2131
 
        if ( nRows != 1)
2132
 
            maxOffs =  th - ( cellH ? cellH : cellHeight( nRows - 1 ) );
2133
 
        else
2134
 
            maxOffs = th - viewHeight();
2135
 
    } else {
2136
 
        if ( testTableFlags(Tbl_snapToVGrid) ) {
2137
 
            if ( cellH ) {
2138
 
                maxOffs =  th - (viewHeight()/cellH)*cellH;
2139
 
            } else {
2140
 
                int goal = th - viewHeight();
2141
 
                int pos = th;
2142
 
                int nextRow = nRows - 1;
2143
 
                int nextCellHeight = cellHeight( nextRow );
2144
 
                while( nextRow > 0 && pos > goal + nextCellHeight ) {
2145
 
                    pos -= nextCellHeight;
2146
 
                    nextCellHeight = cellHeight( --nextRow );
2147
 
                }
2148
 
                if ( goal + nextCellHeight == pos )
2149
 
                    maxOffs = goal;
2150
 
                 else if ( goal < pos )
2151
 
                   maxOffs = pos;
2152
 
                 else
2153
 
                   maxOffs = 0;
2154
 
            }
2155
 
        } else {
2156
 
            maxOffs = th - viewHeight();
2157
 
        }
2158
 
    }
2159
 
    return maxOffs > 0 ? maxOffs : 0;
2160
 
}
2161
 
 
2162
 
 
2163
 
/*!
2164
 
  Returns the index of the last column, which may be at the left edge
2165
 
  of the view.
2166
 
 
2167
 
  Depending on the \link setTableFlags() Tbl_scrollLastHCell\endlink flag,
2168
 
  this may or may not be the last column.
2169
 
 
2170
 
  \sa maxXOffset(), maxRowOffset()
2171
 
*/
2172
 
 
2173
 
int QtTableView::maxColOffset()
2174
 
{
2175
 
    int mx = maxXOffset();
2176
 
    if ( cellW )
2177
 
        return mx/cellW;
2178
 
    else {
2179
 
        int xcd=0, col=0;
2180
 
        while ( col < nCols && mx > (xcd=cellWidth(col)) ) {
2181
 
            mx -= xcd;
2182
 
            col++;
2183
 
        }
2184
 
        return col;
2185
 
    }
2186
 
}
2187
 
 
2188
 
 
2189
 
/*!
2190
 
  Returns the index of the last row, which may be at the top edge of
2191
 
  the view.
2192
 
 
2193
 
  Depending on the \link setTableFlags() Tbl_scrollLastVCell\endlink flag,
2194
 
  this may or may not be the last row.
2195
 
 
2196
 
  \sa maxYOffset(), maxColOffset()
2197
 
*/
2198
 
 
2199
 
int QtTableView::maxRowOffset()
2200
 
{
2201
 
    int my = maxYOffset();
2202
 
    if ( cellH )
2203
 
        return my/cellH;
2204
 
    else {
2205
 
        int ycd=0, row=0;
2206
 
        while ( row < nRows && my > (ycd=cellHeight(row)) ) {
2207
 
            my -= ycd;
2208
 
            row++;
2209
 
        }
2210
 
        return row;
2211
 
    }
2212
 
}
2213
 
 
2214
 
 
2215
 
void QtTableView::showOrHideScrollBars()
2216
 
{
2217
 
    if ( !autoUpdate() )
2218
 
        return;
2219
 
    if ( vScrollBar ) {
2220
 
        if ( testTableFlags(Tbl_vScrollBar) ) {
2221
 
            if ( !vScrollBar->isVisible() )
2222
 
                sbDirty = sbDirty | verMask;
2223
 
        } else {
2224
 
            if ( vScrollBar->isVisible() )
2225
 
               vScrollBar->hide();
2226
 
        }
2227
 
    }
2228
 
    if ( hScrollBar ) {
2229
 
        if ( testTableFlags(Tbl_hScrollBar) ) {
2230
 
            if ( !hScrollBar->isVisible() )
2231
 
                sbDirty = sbDirty | horMask;
2232
 
        } else {
2233
 
            if ( hScrollBar->isVisible() )
2234
 
                hScrollBar->hide();
2235
 
        }
2236
 
    }
2237
 
    if ( cornerSquare ) {
2238
 
        if ( testTableFlags(Tbl_hScrollBar) &&
2239
 
             testTableFlags(Tbl_vScrollBar) ) {
2240
 
            if ( !cornerSquare->isVisible() )
2241
 
                cornerSquare->show();
2242
 
        } else {
2243
 
            if ( cornerSquare->isVisible() )
2244
 
                cornerSquare->hide();
2245
 
        }
2246
 
    }
2247
 
}
2248
 
 
2249
 
 
2250
 
/*!
2251
 
  Updates the scroll bars and internal state.
2252
 
 
2253
 
  Call this function when the table view's total size is changed;
2254
 
  typically because the result of cellHeight() or cellWidth() have changed.
2255
 
 
2256
 
  This function does not repaint the widget.
2257
 
*/
2258
 
 
2259
 
void QtTableView::updateTableSize()
2260
 
{
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);
2267
 
 
2268
 
    updateScrollBars( horSteps |  horRange |
2269
 
                      verSteps |  verRange );
2270
 
    showOrHideScrollBars();
2271
 
}
2272
 
 
2273
 
 
2274
 
#endif