3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
8 #include <qscrollbar.h>
11 class CornerSquare
: public QWidget
// internal class
14 CornerSquare(QWidget
* parent
, const char* name
= 0);
15 void paintEvent(QPaintEvent
*);
18 CornerSquare::CornerSquare(QWidget
* parent
, const char* name
) :
23 void CornerSquare::paintEvent(QPaintEvent
*)
29 * A simplified version of QTableView, which works only for rows of uniform
30 * height: cellHeight() is only invoked for row 0.
32 TableView::TableView(QWidget
* parent
, const char* name
, WFlags f
) :
33 QWidget(parent
, name
, f
),
41 m_sbV
= new QScrollBar(QScrollBar::Vertical
, this, "table_sbV");
42 m_sbH
= new QScrollBar(QScrollBar::Horizontal
, this, "table_sbH");
43 m_sbV
->resize(m_sbV
->sizeHint());
44 m_sbH
->resize(m_sbH
->sizeHint());
47 connect(m_sbV
, SIGNAL(valueChanged(int)), this, SLOT(sbVer(int)));
48 connect(m_sbH
, SIGNAL(valueChanged(int)), this, SLOT(sbHor(int)));
50 m_sbCorner
= new QWidget(this, "table_corner");
53 setFocusPolicy(WheelFocus
);
56 TableView::~TableView()
60 void TableView::setNumCols(int cols
)
65 void TableView::setNumRows(int rows
)
70 void TableView::updateTableSize()
72 // don't call cellHeight if there are now rows
73 m_totalSize
.setHeight(m_numRows
> 0 ? cellHeight(0) * m_numRows
: 0);
75 for (int i
= 0; i
< m_numCols
; i
++) {
78 m_totalSize
.setWidth(w
);
79 int maxX
= maxXOffset();
80 int maxY
= maxYOffset();
81 if (xOffset() > maxX
|| yOffset() > maxY
) {
82 setOffset(QMIN(xOffset(),maxX
), QMIN(yOffset(),maxY
));
88 int TableView::lastRowVisible() const
92 int r
= (viewHeight() + m_yOffset
) / cellHeight(0) - 1;
95 } else if (r
>= numRows()) {
102 int TableView::maxXOffset() const
104 int o
= m_totalSize
.width()-viewWidth();
108 int TableView::maxYOffset() const
110 int o
= m_totalSize
.height()-viewHeight();
114 void TableView::setOffset(int x
, int y
)
116 int oldX
= m_xOffset
;
117 int oldY
= m_yOffset
;
118 int maxX
= maxXOffset();
119 int maxY
= maxYOffset();
120 m_xOffset
= QMIN(x
, maxX
);
121 m_yOffset
= QMIN(y
, maxY
);
123 QRect
r(0,0, viewWidth(), viewHeight());
124 scroll(oldX
-m_xOffset
, oldY
-m_yOffset
, r
);
129 void TableView::setTopCell(int row
)
132 setYOffset(row
* cellHeight(0));
135 int TableView::topCell() const
138 return yOffset() / cellHeight(0);
143 int TableView::leftCell() const
151 // special-casing x == 0 saves one call to cellWidth()
152 return x
== 0 ? c
: c
-1;
155 int TableView::viewWidth() const
157 // takes into account whether scrollbars are visible
159 if (m_sbV
->isVisible())
164 int TableView::viewHeight() const
166 // takes into account whether scrollbars are visible
168 if (m_sbH
->isVisible())
169 h
-= m_sbH
->height();
173 bool TableView::rowIsVisible(int row
) const
175 return row
>= topCell() && row
<= lastRowVisible();
178 int TableView::findRow(int y
) const
182 int r
= (yOffset() + y
) / cellHeight(0);
183 if (r
< 0 || r
>= numRows())
189 bool TableView::rowYPos(int row
, int* top
) const
192 return false; // now rows => nothing visible
193 int y
= row
* cellHeight(0) - yOffset();
194 if (y
<= -cellHeight(0))
195 return false; // row is above view
196 if (y
> viewHeight())
197 return false; // row is below view
202 int TableView::findCol(int x
) const
207 for (int col
= 0; col
< numCols(); col
++) {
215 bool TableView::colXPos(int col
, int* left
) const
218 int viewW
= viewWidth();
223 // col is completely to the right of view
229 if (x
+ cellWidth(col
) > 0) {
230 // col is partially visible at left of view
234 // col is completely to the left of view
238 // left edge of col is in the view
244 void TableView::updateCell(int row
, int col
, bool erase
)
247 if (!colXPos(col
, &x
))
249 if (!rowYPos(row
, &y
))
251 QRect
r(x
, y
, cellWidth(col
), cellHeight(0/*row*/));
255 void TableView::setupPainter(QPainter
* /*p*/)
257 // does nothing special
260 void TableView::resizeEvent(QResizeEvent
* /*ev*/)
265 void TableView::paintEvent(QPaintEvent
* /*ev*/)
267 if (numRows() == 0 || numCols() == 0)
273 int viewH
= viewHeight();
274 int viewW
= viewWidth();
275 int leftCol
= leftCell();
277 colXPos(leftCol
, &leftX
);
282 while (y
< viewH
&& row
< numRows()) {
285 while (x
< viewW
&& col
< numCols()) {
286 matrix
.translate(x
, y
);
287 p
.setWorldMatrix(matrix
);
288 paintCell(&p
, row
, col
);
290 p
.setWorldMatrix(matrix
);
295 y
+= cellHeight(0/*row*/);
299 void TableView::updateScrollBars()
301 // see which scrollbars we absolutely need
304 bool needV
= m_totalSize
.height() > h
;
305 bool needH
= m_totalSize
.width() > w
;
307 // if we need neither, remove the scrollbars and we're done
308 if (!needV
&& !needH
)
315 // if we need both, reduce view
316 if (needV
&& needH
) {
318 h
-= m_sbH
->height();
321 * If we need the vertical bar, but not the horizontal, the
322 * presence of the vertical bar might reduce the space so that we
323 * also need the horizontal bar. Likewise, if we need the
324 * horizontal but not necessarily the vertical bar.
328 needH
= m_totalSize
.width() > w
;
330 h
-= m_sbH
->height();
334 h
-= m_sbH
->height();
335 needV
= m_totalSize
.height() > h
;
342 // note: must show() early because max?Offset() depends on visibility
344 m_sbH
->setGeometry(0, h
, w
, m_sbH
->height());
346 m_sbH
->setRange(0, maxXOffset());
347 m_sbH
->setValue(xOffset());
348 m_sbH
->setSteps(32, w
);
353 m_sbV
->setGeometry(w
, 0, m_sbV
->width(), h
);
355 m_sbV
->setRange(0, maxYOffset());
356 m_sbV
->setValue(yOffset());
357 m_sbV
->setSteps(cellHeight(0), h
);
361 // corner square: only if both scrollbars are there
362 if (needH
&& needV
) {
363 m_sbCorner
->setGeometry(w
, h
, m_sbV
->width(), m_sbH
->height());
370 void TableView::sbVer(int value
)
375 void TableView::sbHor(int value
)
380 #include "tableview.moc"