Added a primitive guess of the executable's language.
[kdbg.git] / kdbg / tableview.cpp
bloba95bd6649f7fc4a0f2982694bc518b137a39e79f
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include "tableview.h"
7 #include <qpainter.h>
8 #include <qscrollbar.h>
10 #if 0
11 class CornerSquare : public QWidget // internal class
13 public:
14 CornerSquare(QWidget* parent, const char* name = 0);
15 void paintEvent(QPaintEvent*);
18 CornerSquare::CornerSquare(QWidget* parent, const char* name) :
19 QWidget(parent, name)
23 void CornerSquare::paintEvent(QPaintEvent*)
26 #endif
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),
34 m_numRows(0),
35 m_numCols(0),
36 m_xOffset(0),
37 m_yOffset(0),
38 m_totalSize(0, 0),
39 m_autoUpdate(true)
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());
45 m_sbV->hide();
46 m_sbH->hide();
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");
51 m_sbCorner->hide();
53 setFocusPolicy(WheelFocus);
56 TableView::~TableView()
60 void TableView::setNumCols(int cols)
62 m_numCols = cols;
65 void TableView::setNumRows(int rows)
67 m_numRows = 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);
74 int w = 0;
75 for (int i = 0; i < m_numCols; i++) {
76 w += cellWidth(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));
83 } else {
84 updateScrollBars();
88 int TableView::lastRowVisible() const
90 if (numRows() == 0)
91 return -1;
92 int r = (viewHeight() + m_yOffset) / cellHeight(0) - 1;
93 if (r < 0) {
94 return 0;
95 } else if (r >= numRows()) {
96 return numRows()-1;
97 } else {
98 return r;
102 int TableView::maxXOffset() const
104 int o = m_totalSize.width()-viewWidth();
105 return QMAX(0, o);
108 int TableView::maxYOffset() const
110 int o = m_totalSize.height()-viewHeight();
111 return QMAX(0, o);
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);
122 if (m_autoUpdate) {
123 QRect r(0,0, viewWidth(), viewHeight());
124 scroll(oldX-m_xOffset, oldY-m_yOffset, r);
126 updateScrollBars();
129 void TableView::setTopCell(int row)
131 if (numRows() > 0)
132 setYOffset(row * cellHeight(0));
135 int TableView::topCell() const
137 if (numRows() > 0)
138 return yOffset() / cellHeight(0);
139 else
140 return -1;
143 int TableView::leftCell() const
145 int x = -xOffset();
146 int c = 0;
147 while (x < 0) {
148 x += cellWidth(c);
149 c++;
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
158 int w = width();
159 if (m_sbV->isVisible())
160 w -= m_sbV->width();
161 return w;
164 int TableView::viewHeight() const
166 // takes into account whether scrollbars are visible
167 int h = height();
168 if (m_sbH->isVisible())
169 h -= m_sbH->height();
170 return h;
173 bool TableView::rowIsVisible(int row) const
175 return row >= topCell() && row <= lastRowVisible();
178 int TableView::findRow(int y) const
180 if (numRows() == 0)
181 return -1;
182 int r = (yOffset() + y) / cellHeight(0);
183 if (r < 0 || r >= numRows())
184 return -1;
185 else
186 return r;
189 bool TableView::rowYPos(int row, int* top) const
191 if (numRows() == 0)
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
198 *top = y;
199 return true;
202 int TableView::findCol(int x) const
204 x += xOffset();
205 if (x < 0)
206 return -1;
207 for (int col = 0; col < numCols(); col++) {
208 x -= cellWidth(col);
209 if (x < 0)
210 return col;
212 return -1;
215 bool TableView::colXPos(int col, int* left) const
217 int x = -xOffset();
218 int viewW = viewWidth();
219 int c = 0;
220 while (c < col) {
221 x += cellWidth(c);
222 if (x >= viewW) {
223 // col is completely to the right of view
224 return false;
226 c++;
228 if (x <= 0) {
229 if (x + cellWidth(col) > 0) {
230 // col is partially visible at left of view
231 *left = x;
232 return true;
233 } else {
234 // col is completely to the left of view
235 return false;
237 } else {
238 // left edge of col is in the view
239 *left = x;
240 return true;
244 void TableView::updateCell(int row, int col, bool erase)
246 int x, y;
247 if (!colXPos(col, &x))
248 return;
249 if (!rowYPos(row, &y))
250 return;
251 QRect r(x, y, cellWidth(col), cellHeight(0/*row*/));
252 repaint(r, erase);
255 void TableView::setupPainter(QPainter* /*p*/)
257 // does nothing special
260 void TableView::resizeEvent(QResizeEvent* /*ev*/)
262 updateScrollBars();
265 void TableView::paintEvent(QPaintEvent* /*ev*/)
267 if (numRows() == 0 || numCols() == 0)
268 return;
270 QPainter p(this);
271 setupPainter(&p);
273 int viewH = viewHeight();
274 int viewW = viewWidth();
275 int leftCol = leftCell();
276 int leftX = 0;
277 colXPos(leftCol, &leftX);
278 int row = topCell();
279 int y = 0;
280 rowYPos(row, &y);
281 QWMatrix matrix;
282 while (y < viewH && row < numRows()) {
283 int col = leftCol;
284 int x = leftX;
285 while (x < viewW && col < numCols()) {
286 matrix.translate(x, y);
287 p.setWorldMatrix(matrix);
288 paintCell(&p, row, col);
289 matrix.reset();
290 p.setWorldMatrix(matrix);
291 x += cellWidth(col);
292 col++;
294 row++;
295 y += cellHeight(0/*row*/);
299 void TableView::updateScrollBars()
301 // see which scrollbars we absolutely need
302 int w = width();
303 int h = height();
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)
310 m_sbH->hide();
311 m_sbV->hide();
312 m_sbCorner->hide();
313 return;
315 // if we need both, reduce view
316 if (needV && needH) {
317 w -= m_sbV->width();
318 h -= m_sbH->height();
319 } else {
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.
326 if (needV) {
327 w -= m_sbV->width();
328 needH = m_totalSize.width() > w;
329 if (needH) {
330 h -= m_sbH->height();
332 } else {
333 // assert(needH)
334 h -= m_sbH->height();
335 needV = m_totalSize.height() > h;
336 if (needV) {
337 w -= m_sbV->width();
341 // set scrollbars
342 // note: must show() early because max?Offset() depends on visibility
343 if (needH) {
344 m_sbH->setGeometry(0, h, w, m_sbH->height());
345 m_sbH->show();
346 m_sbH->setRange(0, maxXOffset());
347 m_sbH->setValue(xOffset());
348 m_sbH->setSteps(32, w);
349 } else {
350 m_sbH->hide();
352 if (needV) {
353 m_sbV->setGeometry(w, 0, m_sbV->width(), h);
354 m_sbV->show();
355 m_sbV->setRange(0, maxYOffset());
356 m_sbV->setValue(yOffset());
357 m_sbV->setSteps(cellHeight(0), h);
358 } else {
359 m_sbV->hide();
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());
364 m_sbCorner->show();
365 } else {
366 m_sbCorner->hide();
370 void TableView::sbVer(int value)
372 setYOffset(value);
375 void TableView::sbHor(int value)
377 setXOffset(value);
380 #include "tableview.moc"