Attach to Process: Start the dialog with the filter set to the program name.
[kdbg.git] / kdbg / tableview.cpp
blob6b7c4cb5d70ca601f1a438633ab4a8aa47600768
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include "tableview.h"
8 #include <qapplication.h>
9 #include <qpainter.h>
10 #include <qscrollbar.h>
12 #if 0
13 class CornerSquare : public QWidget // internal class
15 public:
16 CornerSquare(QWidget* parent, const char* name = 0);
17 void paintEvent(QPaintEvent*);
20 CornerSquare::CornerSquare(QWidget* parent, const char* name) :
21 QWidget(parent, name)
25 void CornerSquare::paintEvent(QPaintEvent*)
28 #endif
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),
36 m_numRows(0),
37 m_numCols(0),
38 m_xOffset(0),
39 m_yOffset(0),
40 m_totalSize(0, 0),
41 m_autoUpdate(true)
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());
47 m_sbV->hide();
48 m_sbH->hide();
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");
53 m_sbCorner->hide();
55 setFocusPolicy(WheelFocus);
58 TableView::~TableView()
62 void TableView::setNumCols(int cols)
64 m_numCols = cols;
67 void TableView::setNumRows(int rows)
69 m_numRows = 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);
76 int w = 0;
77 for (int i = 0; i < m_numCols; i++) {
78 w += cellWidth(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));
85 } else {
86 updateScrollBars();
90 int TableView::lastRowVisible() const
92 if (numRows() == 0)
93 return -1;
94 int r = (viewHeight() + m_yOffset) / cellHeight(0) - 1;
95 if (r < 0) {
96 return 0;
97 } else if (r >= numRows()) {
98 return numRows()-1;
99 } else {
100 return r;
104 int TableView::maxXOffset() const
106 int o = m_totalSize.width()-viewWidth();
107 return QMAX(0, o);
110 int TableView::maxYOffset() const
112 int o = m_totalSize.height()-viewHeight();
113 return QMAX(0, o);
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);
124 if (m_autoUpdate) {
125 QRect r(0,0, viewWidth(), viewHeight());
126 scroll(oldX-m_xOffset, oldY-m_yOffset, r);
128 updateScrollBars();
131 void TableView::setTopCell(int row)
133 if (numRows() > 0)
134 setYOffset(row * cellHeight(0));
137 int TableView::topCell() const
139 if (numRows() > 0)
140 return yOffset() / cellHeight(0);
141 else
142 return -1;
145 int TableView::leftCell() const
147 int x = -xOffset();
148 int c = 0;
149 while (x < 0) {
150 x += cellWidth(c);
151 c++;
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
160 int w = width();
161 if (m_sbV->isVisible())
162 w -= m_sbV->width();
163 return w;
166 int TableView::viewHeight() const
168 // takes into account whether scrollbars are visible
169 int h = height();
170 if (m_sbH->isVisible())
171 h -= m_sbH->height();
172 return h;
175 bool TableView::rowIsVisible(int row) const
177 return row >= topCell() && row <= lastRowVisible();
180 int TableView::findRow(int y) const
182 if (numRows() == 0)
183 return -1;
184 int r = (yOffset() + y) / cellHeight(0);
185 if (r < 0 || r >= numRows())
186 return -1;
187 else
188 return r;
191 bool TableView::rowYPos(int row, int* top) const
193 if (numRows() == 0)
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
200 *top = y;
201 return true;
204 int TableView::findCol(int x) const
206 x += xOffset();
207 if (x < 0)
208 return -1;
209 for (int col = 0; col < numCols(); col++) {
210 x -= cellWidth(col);
211 if (x < 0)
212 return col;
214 return -1;
217 bool TableView::colXPos(int col, int* left) const
219 int x = -xOffset();
220 int viewW = viewWidth();
221 int c = 0;
222 while (c < col) {
223 x += cellWidth(c);
224 if (x >= viewW) {
225 // col is completely to the right of view
226 return false;
228 c++;
230 if (x <= 0) {
231 if (x + cellWidth(col) > 0) {
232 // col is partially visible at left of view
233 *left = x;
234 return true;
235 } else {
236 // col is completely to the left of view
237 return false;
239 } else {
240 // left edge of col is in the view
241 *left = x;
242 return true;
246 void TableView::updateCell(int row, int col, bool erase)
248 int x, y;
249 if (!colXPos(col, &x))
250 return;
251 if (!rowYPos(row, &y))
252 return;
253 QRect r(x, y, cellWidth(col), cellHeight(0/*row*/));
254 repaint(r, erase);
257 void TableView::setupPainter(QPainter* /*p*/)
259 // does nothing special
262 void TableView::resizeEvent(QResizeEvent* /*ev*/)
264 updateScrollBars();
267 void TableView::paintEvent(QPaintEvent* /*ev*/)
269 if (numRows() == 0 || numCols() == 0)
270 return;
272 QPainter p(this);
273 setupPainter(&p);
275 int viewH = viewHeight();
276 int viewW = viewWidth();
277 int leftCol = leftCell();
278 int leftX = 0;
279 colXPos(leftCol, &leftX);
280 int row = topCell();
281 int y = 0;
282 rowYPos(row, &y);
283 QWMatrix matrix;
284 while (y < viewH && row < numRows()) {
285 int col = leftCol;
286 int x = leftX;
287 while (x < viewW && col < numCols()) {
288 matrix.translate(x, y);
289 p.setWorldMatrix(matrix);
290 paintCell(&p, row, col);
291 matrix.reset();
292 p.setWorldMatrix(matrix);
293 x += cellWidth(col);
294 col++;
296 row++;
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);
308 else
309 #endif
311 if (m_sbV != 0)
313 QApplication::sendEvent(m_sbV, ev);
318 void TableView::updateScrollBars()
320 // see which scrollbars we absolutely need
321 int w = width();
322 int h = height();
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)
329 m_sbH->hide();
330 m_sbV->hide();
331 m_sbCorner->hide();
332 return;
334 // if we need both, reduce view
335 if (needV && needH) {
336 w -= m_sbV->width();
337 h -= m_sbH->height();
338 } else {
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.
345 if (needV) {
346 w -= m_sbV->width();
347 if (w < 0)
348 w = 0;
349 needH = m_totalSize.width() > w;
350 if (needH) {
351 h -= m_sbH->height();
353 } else {
354 // assert(needH)
355 h -= m_sbH->height();
356 if (h < 0)
357 h = 0;
358 needV = m_totalSize.height() > h;
359 if (needV) {
360 w -= m_sbV->width();
364 // set scrollbars
365 // note: must show() early because max?Offset() depends on visibility
366 if (needH) {
367 m_sbH->setGeometry(0, h, w, m_sbH->height());
368 m_sbH->show();
369 m_sbH->setRange(0, maxXOffset());
370 m_sbH->setValue(xOffset());
371 m_sbH->setSteps(32, w);
372 } else {
373 m_sbH->hide();
375 if (needV) {
376 m_sbV->setGeometry(w, 0, m_sbV->width(), h);
377 m_sbV->show();
378 m_sbV->setRange(0, maxYOffset());
379 m_sbV->setValue(yOffset());
380 m_sbV->setSteps(cellHeight(0), h);
381 } else {
382 m_sbV->hide();
384 // corner square: only if both scrollbars are there
385 if (needH && needV) {
386 m_sbCorner->setGeometry(w, h, m_sbV->width(), m_sbH->height());
387 m_sbCorner->show();
388 } else {
389 m_sbCorner->hide();
393 void TableView::sbVer(int value)
395 setYOffset(value);
398 void TableView::sbHor(int value)
400 setXOffset(value);
403 #include "tableview.moc"