3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
8 #include <qapplication.h>
10 #include <qscrollbar.h>
13 class CornerSquare
: public QWidget
// internal class
16 CornerSquare(QWidget
* parent
, const char* name
= 0);
17 void paintEvent(QPaintEvent
*);
20 CornerSquare::CornerSquare(QWidget
* parent
, const char* name
) :
25 void CornerSquare::paintEvent(QPaintEvent
*)
31 * A simplified version of QTableView, which works only for rows of uniform
32 * height: cellHeight() is only invoked for row 0.
34 TableView::TableView(QWidget
* parent
, const char* name
, WFlags f
) :
35 QWidget(parent
, name
, f
),
43 m_sbV
= new QScrollBar(QScrollBar::Vertical
, this, "table_sbV");
44 m_sbH
= new QScrollBar(QScrollBar::Horizontal
, this, "table_sbH");
45 m_sbV
->resize(m_sbV
->sizeHint());
46 m_sbH
->resize(m_sbH
->sizeHint());
49 connect(m_sbV
, SIGNAL(valueChanged(int)), this, SLOT(sbVer(int)));
50 connect(m_sbH
, SIGNAL(valueChanged(int)), this, SLOT(sbHor(int)));
52 m_sbCorner
= new QWidget(this, "table_corner");
55 setFocusPolicy(WheelFocus
);
58 TableView::~TableView()
62 void TableView::setNumCols(int cols
)
67 void TableView::setNumRows(int rows
)
72 void TableView::updateTableSize()
74 // don't call cellHeight if there are now rows
75 m_totalSize
.setHeight(m_numRows
> 0 ? cellHeight(0) * m_numRows
: 0);
77 for (int i
= 0; i
< m_numCols
; i
++) {
80 m_totalSize
.setWidth(w
);
81 int maxX
= maxXOffset();
82 int maxY
= maxYOffset();
83 if (xOffset() > maxX
|| yOffset() > maxY
) {
84 setOffset(QMIN(xOffset(),maxX
), QMIN(yOffset(),maxY
));
90 int TableView::lastRowVisible() const
94 int r
= (viewHeight() + m_yOffset
) / cellHeight(0) - 1;
97 } else if (r
>= numRows()) {
104 int TableView::maxXOffset() const
106 int o
= m_totalSize
.width()-viewWidth();
110 int TableView::maxYOffset() const
112 int o
= m_totalSize
.height()-viewHeight();
116 void TableView::setOffset(int x
, int y
)
118 int oldX
= m_xOffset
;
119 int oldY
= m_yOffset
;
120 int maxX
= maxXOffset();
121 int maxY
= maxYOffset();
122 m_xOffset
= QMIN(x
, maxX
);
123 m_yOffset
= QMIN(y
, maxY
);
125 QRect
r(0,0, viewWidth(), viewHeight());
126 scroll(oldX
-m_xOffset
, oldY
-m_yOffset
, r
);
131 void TableView::setTopCell(int row
)
134 setYOffset(row
* cellHeight(0));
137 int TableView::topCell() const
140 return yOffset() / cellHeight(0);
145 int TableView::leftCell() const
153 // special-casing x == 0 saves one call to cellWidth()
154 return x
== 0 ? c
: c
-1;
157 int TableView::viewWidth() const
159 // takes into account whether scrollbars are visible
161 if (m_sbV
->isVisible())
166 int TableView::viewHeight() const
168 // takes into account whether scrollbars are visible
170 if (m_sbH
->isVisible())
171 h
-= m_sbH
->height();
175 bool TableView::rowIsVisible(int row
) const
177 return row
>= topCell() && row
<= lastRowVisible();
180 int TableView::findRow(int y
) const
184 int r
= (yOffset() + y
) / cellHeight(0);
185 if (r
< 0 || r
>= numRows())
191 bool TableView::rowYPos(int row
, int* top
) const
194 return false; // now rows => nothing visible
195 int y
= row
* cellHeight(0) - yOffset();
196 if (y
<= -cellHeight(0))
197 return false; // row is above view
198 if (y
> viewHeight())
199 return false; // row is below view
204 int TableView::findCol(int x
) const
209 for (int col
= 0; col
< numCols(); col
++) {
217 bool TableView::colXPos(int col
, int* left
) const
220 int viewW
= viewWidth();
225 // col is completely to the right of view
231 if (x
+ cellWidth(col
) > 0) {
232 // col is partially visible at left of view
236 // col is completely to the left of view
240 // left edge of col is in the view
246 void TableView::updateCell(int row
, int col
, bool erase
)
249 if (!colXPos(col
, &x
))
251 if (!rowYPos(row
, &y
))
253 QRect
r(x
, y
, cellWidth(col
), cellHeight(0/*row*/));
257 void TableView::setupPainter(QPainter
* /*p*/)
259 // does nothing special
262 void TableView::resizeEvent(QResizeEvent
* /*ev*/)
267 void TableView::paintEvent(QPaintEvent
* /*ev*/)
269 if (numRows() == 0 || numCols() == 0)
275 int viewH
= viewHeight();
276 int viewW
= viewWidth();
277 int leftCol
= leftCell();
279 colXPos(leftCol
, &leftX
);
284 while (y
< viewH
&& row
< numRows()) {
287 while (x
< viewW
&& col
< numCols()) {
288 matrix
.translate(x
, y
);
289 p
.setWorldMatrix(matrix
);
290 paintCell(&p
, row
, col
);
292 p
.setWorldMatrix(matrix
);
297 y
+= cellHeight(0/*row*/);
301 void TableView::wheelEvent(QWheelEvent
* ev
)
303 #if QT_VERSION >= 300
304 if (ev
->orientation() == Horizontal
&& m_sbH
!= 0)
306 QApplication::sendEvent(m_sbH
, ev
);
313 QApplication::sendEvent(m_sbV
, ev
);
318 void TableView::updateScrollBars()
320 // see which scrollbars we absolutely need
323 bool needV
= m_totalSize
.height() > h
;
324 bool needH
= m_totalSize
.width() > w
;
326 // if we need neither, remove the scrollbars and we're done
327 if (!needV
&& !needH
)
334 // if we need both, reduce view
335 if (needV
&& needH
) {
337 h
-= m_sbH
->height();
340 * If we need the vertical bar, but not the horizontal, the
341 * presence of the vertical bar might reduce the space so that we
342 * also need the horizontal bar. Likewise, if we need the
343 * horizontal but not necessarily the vertical bar.
347 needH
= m_totalSize
.width() > w
;
349 h
-= m_sbH
->height();
353 h
-= m_sbH
->height();
354 needV
= m_totalSize
.height() > h
;
361 // note: must show() early because max?Offset() depends on visibility
363 m_sbH
->setGeometry(0, h
, w
, m_sbH
->height());
365 m_sbH
->setRange(0, maxXOffset());
366 m_sbH
->setValue(xOffset());
367 m_sbH
->setSteps(32, w
);
372 m_sbV
->setGeometry(w
, 0, m_sbV
->width(), h
);
374 m_sbV
->setRange(0, maxYOffset());
375 m_sbV
->setValue(yOffset());
376 m_sbV
->setSteps(cellHeight(0), h
);
380 // corner square: only if both scrollbars are there
381 if (needH
&& needV
) {
382 m_sbCorner
->setGeometry(w
, h
, m_sbV
->width(), m_sbH
->height());
389 void TableView::sbVer(int value
)
394 void TableView::sbHor(int value
)
399 #include "tableview.moc"