You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1270 lines
33 KiB
1270 lines
33 KiB
9 years ago
|
// very dirty and complex code ( fasthyun@magicn.com)
|
||
|
// Disaster !!
|
||
|
|
||
|
// htable.cpp
|
||
|
// This program is free software. See the file COPYING for details.
|
||
|
// Author: Mattias Engdeg?rd, 1997-1999
|
||
|
|
||
|
// TODO:
|
||
|
// * autoscroll speed proportional to distance from edge
|
||
|
// * interface to add/remove rows (for disclosure triangles)
|
||
|
// * interface to display pixmaps in cells (for disclosure triangles etc)
|
||
|
// * include sorting functionality here for more generality
|
||
|
|
||
|
#include "htable.h"
|
||
|
#include <QMouseEvent>
|
||
|
#include <QStyleOption>
|
||
|
#include <QShortcut>
|
||
|
#include <QPalette>
|
||
|
|
||
|
#define DEBUG qDebug
|
||
|
//#define DEBUG
|
||
|
VPointer *vp = NULL; // Temporary
|
||
|
|
||
|
VPointer::VPointer(QWidget *parent) : QWidget(parent)
|
||
|
{
|
||
|
pix = new QPixmap(":/icon/vpointer.png");
|
||
|
pix_vcross = new QPixmap(":/icon/vcross.png");
|
||
|
int w = pix->width();
|
||
|
bool flag_movable = true;
|
||
|
setGeometry(0, 0, w, w);
|
||
|
}
|
||
|
|
||
|
void VPointer::paintEvent(QPaintEvent *event)
|
||
|
{
|
||
|
QPainter p(this);
|
||
|
p.setClipping(false); // not work
|
||
|
if (flag_movable)
|
||
|
p.drawPixmap(0, 0, *pix);
|
||
|
else
|
||
|
p.drawPixmap(0, 0, *pix_vcross);
|
||
|
}
|
||
|
|
||
|
FloatingHead::FloatingHead(QWidget *parent) : QWidget(parent) {}
|
||
|
|
||
|
void FloatingHead::setTitle(QString str, int w, int h)
|
||
|
{
|
||
|
title = str;
|
||
|
resize(w, h);
|
||
|
}
|
||
|
void FloatingHead::paintEvent(QPaintEvent *event)
|
||
|
{
|
||
|
QPainter p(this);
|
||
|
QStyleOptionHeader opt;
|
||
|
p.setOpacity(0.7);
|
||
|
opt.rect = rect();
|
||
|
opt.text = title;
|
||
|
opt.state = QStyle::State_Enabled;
|
||
|
// if(htable->sortedCol()==col) opt.state= opt.state |
|
||
|
// QStyle::State_Sunken;
|
||
|
// CE_Header, CE_HeaderSection, CE_HeaderLabel
|
||
|
style()->drawControl(QStyle::CE_Header, &opt, &p, this);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// TableHead: the horizontally scrollable table head
|
||
|
TableHead::TableHead(HeadedTable *parent)
|
||
|
: QtTableView(parent), htable(parent), dragging(false)
|
||
|
{
|
||
|
setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
|
||
|
// setSizePolicy(QSizePolicy
|
||
|
// (QSizePolicy::Minimum,QSizePolicy::Expanding));
|
||
|
// setTableFlags(Tbl_smoothHScrolling | Tbl_scrollLastHCell);
|
||
|
setTableFlags(Tbl_scrollLastHCell); // ?
|
||
|
setNumRows(1);
|
||
|
|
||
|
setMouseTracking(true); // for tooltip
|
||
|
|
||
|
floatHead = new FloatingHead(parent); // tiny memory leak! don't care.
|
||
|
floatHead->hide();
|
||
|
// setMinimumHeight(20);//cellHeight()); //ZERO!! fault
|
||
|
}
|
||
|
|
||
|
// Description : draw a field name of table when DRAG !!
|
||
|
// called by paintHeading()
|
||
|
// called by QtTableView::repaint()
|
||
|
void TableHead::paintCell(QPainter *p, int row, int col, bool use_cache)
|
||
|
{
|
||
|
static int count = 0;
|
||
|
/// printf(" paintcell %d,%d\n",row,col);
|
||
|
int w = htable->max_widths[col];
|
||
|
|
||
|
// if( isCellChanged (row,col,true)==false)
|
||
|
{
|
||
|
// printf(" paintcell %d,%d\n",row,col);
|
||
|
// if(use_cache==true) // check cached value
|
||
|
{
|
||
|
// return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if( col ==11 ) printf("head: %d (%d) \n",col,count++);
|
||
|
// w = cellUpdateR.width();
|
||
|
{
|
||
|
QStyleOptionHeader opt;
|
||
|
QRect rectR(0, 0, w, height());
|
||
|
opt.rect = rectR;
|
||
|
opt.text = htable->title(col);
|
||
|
opt.state = QStyle::State_Enabled;
|
||
|
if (htable->sortedCol() == col)
|
||
|
opt.state = opt.state | QStyle::State_Sunken;
|
||
|
// CE_Header, CE_HeaderSection, CE_HeaderLabel
|
||
|
style()->drawControl(QStyle::CE_Header, &opt, p, this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// works
|
||
|
void TableHead::eraseRight(QPainter *p, QRect &r)
|
||
|
{
|
||
|
QStyleOptionHeader opt;
|
||
|
// printf("widt=%d \n",r.width());
|
||
|
opt.rect = r;
|
||
|
opt.text = "";
|
||
|
style()->drawControl(QStyle::CE_Header, &opt, p, this);
|
||
|
}
|
||
|
|
||
|
// virtual !
|
||
|
int TableHead::cellWidth(int col) { return htable->max_widths[col]; }
|
||
|
|
||
|
//
|
||
|
void TableHead::scrollSideways(int val) { setXOffset(val); }
|
||
|
|
||
|
void TableHead::mousePressEvent(QMouseEvent *e)
|
||
|
{
|
||
|
int col = findCol(e->x());
|
||
|
// printf("col=%d\n",col);
|
||
|
if (col == -1)
|
||
|
return;
|
||
|
click_col = col;
|
||
|
|
||
|
if (e->button() == Qt::RightButton)
|
||
|
// && htable->options & HTBL_HEADING_CONTEXT_MENU)
|
||
|
{
|
||
|
emit rightClicked(e->globalPos(), col);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (e->button() == Qt::LeftButton)
|
||
|
{
|
||
|
press = e->pos();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TableHead::dragEnterEvent(QDragEnterEvent *event)
|
||
|
{
|
||
|
printf("dragEnterEvent()\n");
|
||
|
}
|
||
|
void TableHead::dragLeaveEvent(QDragLeaveEvent *event)
|
||
|
{
|
||
|
printf("dragLeaveEvent()\n");
|
||
|
}
|
||
|
|
||
|
void TableHead::mouseMoveEvent(QMouseEvent *e)
|
||
|
{
|
||
|
// printf("mouseMoveEvent()\n");
|
||
|
int col = findCol(e->x());
|
||
|
if (col < 0)
|
||
|
{
|
||
|
emit htable->outOfHCell();
|
||
|
return;
|
||
|
}
|
||
|
// if( !dragging) return;
|
||
|
emit htable->flyOnHCell(col);
|
||
|
|
||
|
int thold = abs(press.x() - e->pos().x());
|
||
|
|
||
|
if (e->buttons() == Qt::LeftButton // Button state
|
||
|
and htable->options & HTBL_REORDER_COLS)
|
||
|
{
|
||
|
{
|
||
|
|
||
|
if (!dragging and thold > 5)
|
||
|
{
|
||
|
dragging = true;
|
||
|
drag_offset =
|
||
|
press.x() - htable->colOffset(click_col) + xOffset();
|
||
|
floatHead->setTitle(htable->title(click_col),
|
||
|
cellWidth(click_col), height());
|
||
|
floatHead->show();
|
||
|
// vp->show();
|
||
|
}
|
||
|
|
||
|
if (dragging)
|
||
|
{
|
||
|
// htable->body->drawGhostCol(drag_pos -
|
||
|
// drag_offset, w);
|
||
|
floatHead->move(e->x() - drag_offset, 0);
|
||
|
|
||
|
int vcol = findColNoMinus(e->x() - drag_offset);
|
||
|
int vcol_offx = htable->colOffset(vcol);
|
||
|
static int old_pos = -1;
|
||
|
// printf("vcol=%d\n",vcol);
|
||
|
|
||
|
// virtual Pointer move!
|
||
|
if (old_pos != vcol_offx)
|
||
|
{
|
||
|
QWidget *p = parentWidget(); // htable
|
||
|
// vp->setMovable(htable->columnMovable(htable->columnMovable(vcol)
|
||
|
// and htable->columnMovable(click_col)
|
||
|
// ));
|
||
|
// vp->move(vcol_offx -
|
||
|
// p->geometry().x()
|
||
|
//,p->geometry().y() -
|
||
|
// 13);
|
||
|
// vp->move(e->x() ,10);
|
||
|
old_pos = vcol_offx;
|
||
|
}
|
||
|
drag_pos = e->x(); // save old pos
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (col != -1) // ToolTip
|
||
|
{
|
||
|
// for(int i=0;i<1024*1024;i++) htable->tipText(col);
|
||
|
//// memory leak
|
||
|
// test
|
||
|
QString s = htable->tipText(col);
|
||
|
|
||
|
if (!s.isEmpty())
|
||
|
QToolTip::showText(e->globalPos(), s);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TableHead::mouseReleaseEvent(QMouseEvent *e)
|
||
|
{
|
||
|
if (e->button() == Qt::LeftButton) // Returns the button that caused the
|
||
|
// event.
|
||
|
{
|
||
|
int col = findCol(e->x());
|
||
|
if (col < 0)
|
||
|
col = (e->x() < 0) ? 0 : htable->ncols - 1; // good!
|
||
|
|
||
|
if (!dragging and col == click_col)
|
||
|
{
|
||
|
// htable->emit_click_signal(col); // just click no drag
|
||
|
emit htable->titleClicked(col);
|
||
|
}
|
||
|
|
||
|
if (dragging)
|
||
|
{
|
||
|
int vcol = findColNoMinus(e->x() - drag_offset);
|
||
|
if (click_col >= 0)
|
||
|
{
|
||
|
htable->moveCol(click_col, vcol); // call
|
||
|
// Pstable::moveCol(int
|
||
|
// col, int place)
|
||
|
// should emit !!
|
||
|
// emit colMoved(click_col, vcol);
|
||
|
}
|
||
|
/// printf(" vcol2=%d \n",vcol);
|
||
|
}
|
||
|
dragging = false;
|
||
|
floatHead->hide();
|
||
|
// vp->hide();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#include <QStyleFactory>
|
||
|
|
||
|
// TableBody: the table body, scrollable in all ways
|
||
|
TableBody::TableBody(HeadedTable *parent) : QtTableView(parent), htable(parent)
|
||
|
{
|
||
|
|
||
|
// setTableFlags(Tbl_autoScrollBars | Tbl_smoothScrolling);
|
||
|
setTableFlags(Tbl_snapToVGrid); // works
|
||
|
setTableFlags(Tbl_hScrollBar | Tbl_vScrollBar);
|
||
|
first_drag_row = prev_drag_row = -1;
|
||
|
autoscrolling = false;
|
||
|
gadget_click = false;
|
||
|
setMouseTracking(true);
|
||
|
|
||
|
QStyle *s = QStyleFactory::create("windows");
|
||
|
if (s)
|
||
|
setStyle(s);
|
||
|
}
|
||
|
|
||
|
// virtual from QtTableView
|
||
|
void TableBody::scrollTrigger(int rx, int ry)
|
||
|
{
|
||
|
if (ry == 0)
|
||
|
return;
|
||
|
int n = ry / cellHeight();
|
||
|
/// printf("ry=%d n=%d\n",ry,n);
|
||
|
if (ry > 0)
|
||
|
tablecache.cutDown(n); // error?
|
||
|
else
|
||
|
tablecache.cutUp(-n);
|
||
|
// printf("ry=%d cellheight=%d n=%d\n",ry,cellHeight(),n);
|
||
|
}
|
||
|
|
||
|
// new, possible COMMON?
|
||
|
bool TableBody::isCellChanged(int row, int col)
|
||
|
{
|
||
|
QString str;
|
||
|
int xpos;
|
||
|
int fold, dep;
|
||
|
bool selected;
|
||
|
bool sorted;
|
||
|
int lc;
|
||
|
int width;
|
||
|
|
||
|
{
|
||
|
str = htable->text(row, col);
|
||
|
xpos = htable->colXPos(col);
|
||
|
selected = htable->isSelected(row);
|
||
|
sorted = (htable->sortedCol() == col);
|
||
|
width = htable->max_widths[col];
|
||
|
}
|
||
|
|
||
|
// int left = leftCell(), top = topCell();
|
||
|
CellAttribute *attr = tablecache.value(row - topCell(), col - leftCell());
|
||
|
|
||
|
if (attr == NULL) // never NULL
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bool result = false;
|
||
|
if (attr->text == str and attr->selected == selected and
|
||
|
attr->sorted == sorted and attr->xpos == xpos and attr->w == width
|
||
|
// and attr->size==tmp_size
|
||
|
and
|
||
|
(attr->size.height() >= tmp_size.height())
|
||
|
// and (attr->size.width()>=tmp_size.width())
|
||
|
)
|
||
|
{
|
||
|
result = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// attr->text=str;
|
||
|
// attr->selected=selected;
|
||
|
// attr->sorted=sorted;
|
||
|
// attr->xpos=xpos;
|
||
|
// attr->size=tmp_size;
|
||
|
// attr->w=width;
|
||
|
|
||
|
// if (row==29 and col==0)
|
||
|
// printf("(%d %d) xpos=%d %d sorted=%d %d sel=%d
|
||
|
//%d str=%s
|
||
|
//%s\n",attr->size.height(),tmp_size.height(),
|
||
|
// attr->xpos,xpos,attr->sorted,sorted,attr->selected,selected
|
||
|
// ,qPrintable(attr->text),qPrintable(str));
|
||
|
// printf("true (%d
|
||
|
//%d)\n",row-topCell(),col-leftCell());
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (col == 0)
|
||
|
{
|
||
|
dep = htable->rowDepth(row); // folding_level
|
||
|
fold = htable->folded(row);
|
||
|
lc = htable->lastChild(row);
|
||
|
|
||
|
if (attr->depth == dep /* Uninitial*/
|
||
|
and attr->folded == fold and attr->lastchild == lc)
|
||
|
{
|
||
|
// false
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// attr->depth=dep;
|
||
|
// attr->folded=fold;
|
||
|
result = true;
|
||
|
// printf("true (%d
|
||
|
//%d)\n",row-topCell(),col-leftCell());
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool TableHead::isCellChanged(int row, int col)
|
||
|
{
|
||
|
int xpos;
|
||
|
int ypos;
|
||
|
int w;
|
||
|
int fold, dep;
|
||
|
QString str;
|
||
|
bool sorted = (htable->sortedCol() == col);
|
||
|
|
||
|
w = htable->max_widths[col];
|
||
|
xpos = htable->colXPos(col);
|
||
|
|
||
|
{
|
||
|
str = htable->title(col);
|
||
|
}
|
||
|
// int left = leftCell();
|
||
|
// int top = topCell();
|
||
|
CellAttribute *attr = tablecache.value(row - topCell(), col - leftCell());
|
||
|
|
||
|
if (attr == NULL) // Uninitialed?
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bool result = false;
|
||
|
if (attr->text == str and attr->sorted == sorted and
|
||
|
attr->size == tmp_size and attr->xpos == xpos
|
||
|
// and attr->w==w
|
||
|
)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
attr->text = str;
|
||
|
attr->sorted = sorted;
|
||
|
attr->xpos = xpos;
|
||
|
// attr->w=w;
|
||
|
attr->size = tmp_size;
|
||
|
// if(head) printf("head
|
||
|
// true");
|
||
|
return true;
|
||
|
}
|
||
|
// printf("return %s x=%d\n",str.toAscii().data(),xpos);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#include <Qt>
|
||
|
|
||
|
// DRAFT CODE !! BOTTLENECK !!!
|
||
|
// Description : draw a cell of table
|
||
|
// 1. draw the background of a cell
|
||
|
// 2. draw the text of a cell
|
||
|
//
|
||
|
// called by
|
||
|
// 1.QtTableView::paintEvent()
|
||
|
void TableBody::paintCell(QPainter *p, int row, int col, bool use_cache)
|
||
|
{
|
||
|
// *** sequence important !!!
|
||
|
// if(isCellChanged(row,col)==false) {
|
||
|
// if(use_cache==true) return;
|
||
|
//}
|
||
|
|
||
|
CellAttribute *attr =
|
||
|
tablecache.value(row - topCell(), col - leftCell()); // save cache
|
||
|
// isCellChanged(row,col);
|
||
|
|
||
|
bool sort;
|
||
|
int h = cellHeight();
|
||
|
int w = htable->max_widths[col];
|
||
|
attr->w = w; //
|
||
|
|
||
|
QColor baseColor = palette().brush(QPalette::Base).color();
|
||
|
sort = (col == htable->sorted_col);
|
||
|
attr->sorted = sort;
|
||
|
|
||
|
// gridline
|
||
|
QColor lineColor, textColor;
|
||
|
QColor altColor = palette().brush(QPalette::AlternateBase).color();
|
||
|
lineColor.setRgb((baseColor.red() * 0.5 + altColor.red() * 0.5),
|
||
|
(baseColor.green() * 0.4 + altColor.green() * 0.6),
|
||
|
(baseColor.blue() * 0.4 + altColor.blue() * 0.6));
|
||
|
|
||
|
// QStyleOption opt;
|
||
|
// opt.rect=QRect(0,0,w,h-1);
|
||
|
// opt.state = QStyle::State_Active; //?
|
||
|
// QStyle::SH_ItemView_PaintAlternatingRowColorsForEmptyArea
|
||
|
// const int gridHint =
|
||
|
// style()->styleHint(QStyle::SH_Table_GridLineColor,
|
||
|
// &opt, this);
|
||
|
|
||
|
p->setPen(lineColor);
|
||
|
p->drawLine(0, h - 1, w, h - 1);
|
||
|
|
||
|
// background
|
||
|
if (htable->isSelected(row))
|
||
|
{
|
||
|
p->fillRect(0, 0, w, h - 1, palette().brush(QPalette::Highlight));
|
||
|
p->setPen(palette().brush(QPalette::HighlightedText).color()); // text
|
||
|
attr->selected = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
attr->selected = false;
|
||
|
if (sort)
|
||
|
{
|
||
|
p->fillRect(0, 0, w, h - 1, lineColor.dark(101));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p->fillRect(0, 0, w, h - 1, baseColor);
|
||
|
}
|
||
|
// style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p,
|
||
|
// this);
|
||
|
p->setPen(palette().brush(QPalette::Text).color()); // text
|
||
|
}
|
||
|
|
||
|
// tree gadget , treestep=height
|
||
|
int gap = h / 4;
|
||
|
int testFlag = 0;
|
||
|
if (col == 0 and htable->treemode == true)
|
||
|
{
|
||
|
QStyleOption opt;
|
||
|
int d = htable->rowDepth(row);
|
||
|
attr->depth = d; //**
|
||
|
int treestep = htable->treestep;
|
||
|
if (true /*lines*/)
|
||
|
{
|
||
|
/// int dx = folding ? gadget_space : 6;
|
||
|
for (int level = d, prow = row; level >= 0 and prow >= 0;
|
||
|
level--, prow = htable->parentRow(prow))
|
||
|
{
|
||
|
if (level == d)
|
||
|
continue;
|
||
|
int x = gap + level * treestep;
|
||
|
QRect branchR(x, 0, treestep, h);
|
||
|
opt.rect = branchR;
|
||
|
|
||
|
if (htable->lastChild(prow) == false)
|
||
|
{
|
||
|
if (testFlag)
|
||
|
{
|
||
|
p->drawLine(x + treestep / 2, 0, x + treestep / 2, h);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
opt.state = QStyle::State_Sibling; // | vertical
|
||
|
// line
|
||
|
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt,
|
||
|
p, this);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QRect branchR(gap + d * treestep, 0, treestep, h);
|
||
|
opt.rect = branchR;
|
||
|
if (testFlag)
|
||
|
{
|
||
|
int x = gap + d * treestep + treestep / 2;
|
||
|
|
||
|
p->drawLine(x, h / 2, x + treestep / 2, h / 2);
|
||
|
if (!htable->lastChild(row))
|
||
|
{
|
||
|
p->drawLine(x, 0, x, h);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p->drawLine(x, 0, x, h / 2);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
opt.state = QStyle::State_Item; //?
|
||
|
if (!htable->lastChild(row))
|
||
|
opt.state = opt.state | QStyle::State_Sibling; // |
|
||
|
}
|
||
|
attr->lastchild = htable->lastChild(row);
|
||
|
}
|
||
|
|
||
|
if (true /*folding*/)
|
||
|
{
|
||
|
HeadedTable::NodeState fs = htable->folded(row);
|
||
|
attr->folded = fs; //**
|
||
|
if (fs != HeadedTable::Leaf)
|
||
|
{
|
||
|
opt.state = opt.state | QStyle::State_Children;
|
||
|
if (fs != HeadedTable::Closed)
|
||
|
opt.state = opt.state | QStyle::State_Open;
|
||
|
}
|
||
|
p->save(); // temp , save pencolor
|
||
|
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, p, this);
|
||
|
p->restore();
|
||
|
}
|
||
|
gap = htable->gadget_space + d * treestep + 1;
|
||
|
}
|
||
|
|
||
|
// virtual int Pstable::alignment(int col)
|
||
|
if (htable->alignment_col[col] == Qt::AlignRight) // using cache
|
||
|
{
|
||
|
w -= gap;
|
||
|
gap = 0;
|
||
|
}
|
||
|
// Qt::IncludeTrailingSpaces
|
||
|
// p->drawText(gap, 0, w , h, Qt::TextIncludeTrailingSpace |
|
||
|
// Qt::IncludeTrailingSpaces | Qt::AlignVCenter |
|
||
|
// htable->alignment_col[col],htable->text(row,col));
|
||
|
// p->drawText(gap, 0, w , h, Qt::TextIncludeTrailingSpace |
|
||
|
// Qt::AlignVCenter
|
||
|
// | htable->alignment_col[col],htable->text(row,col));
|
||
|
p->drawText(gap, 0, w, h, Qt::AlignVCenter | htable->alignment_col[col],
|
||
|
htable->text(row, col));
|
||
|
|
||
|
htable->overpaintCell(p, row, col, gap);
|
||
|
|
||
|
// cache write!
|
||
|
// attr->xpos=tmp_x ;
|
||
|
attr->text = htable->text(row, col);
|
||
|
attr->xpos = htable->colXPos(col);
|
||
|
attr->size = tmp_size;
|
||
|
}
|
||
|
|
||
|
// DEL , Home key
|
||
|
void TableBody::jumpTop() { setYOffset(0); }
|
||
|
|
||
|
// DEL, End Key
|
||
|
void TableBody::jumpBottom() { setYOffset(maxYOffset()); }
|
||
|
|
||
|
/// !!!!
|
||
|
void TableBody::centerVertically(int row)
|
||
|
{
|
||
|
int topcell = row - viewHeight() / (cellHeight() * 2);
|
||
|
setTopCell(qMax(topcell, 0));
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
//??
|
||
|
void TableBody::showRange(int from, int to)
|
||
|
{
|
||
|
int h = viewHeight() / cellHeight();
|
||
|
if (to >= topCell() + h)
|
||
|
setTopCell(qMax(0, qMin(from, to - h + 1)));
|
||
|
}
|
||
|
|
||
|
// virtual
|
||
|
// called by
|
||
|
// 1.
|
||
|
int TableBody::cellWidth(int col) { return htable->max_widths[col]; }
|
||
|
|
||
|
// **** fix !!
|
||
|
void TableBody::updateRow(int row)
|
||
|
{
|
||
|
// ??
|
||
|
// for(int col = 0; col < htable->ncols; col++)
|
||
|
// updateCell(row, col,false); updateCell(row, col);
|
||
|
}
|
||
|
|
||
|
void TableBody::mousePressEvent(QMouseEvent *e)
|
||
|
{
|
||
|
if (numRows() == 0)
|
||
|
return; // *** prevent out of range
|
||
|
|
||
|
// printf("mousePressEvent() 1\n");
|
||
|
static int last_row = -1;
|
||
|
|
||
|
int row = findRow(e->y());
|
||
|
if (row == -1)
|
||
|
{
|
||
|
// printf("mousePressEvent\n");
|
||
|
htable->clearAllSelections();
|
||
|
if (e->y() >= 0)
|
||
|
row = numRows(); // if SHIFT+click outside ~
|
||
|
first_drag_row = prev_drag_row = row;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!(htable->options & HTBL_ROW_SELECTION))
|
||
|
return;
|
||
|
|
||
|
if (e->button() == Qt::LeftButton)
|
||
|
{
|
||
|
// folding
|
||
|
if (htable->treemode && htable->folding &&
|
||
|
e->x() < htable->gadget_space +
|
||
|
htable->treestep * htable->rowDepth(row) &&
|
||
|
htable->folded(row) != HeadedTable::Leaf)
|
||
|
{
|
||
|
emit htable->foldSubTree(row);
|
||
|
gadget_click = true;
|
||
|
last_row = row;
|
||
|
// clearCache(); // dont use cache
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (e->modifiers() & Qt::ShiftModifier)
|
||
|
{
|
||
|
if (row < last_row)
|
||
|
for (int i = row; i < last_row; i++)
|
||
|
htable->setSelected(i, true); // virtual
|
||
|
else
|
||
|
for (int i = last_row; i <= row; i++)
|
||
|
htable->setSelected(i, true); // virtual
|
||
|
}
|
||
|
else if (e->modifiers() & Qt::ControlModifier)
|
||
|
{
|
||
|
htable->setSelected(row, !htable->isSelected(row));
|
||
|
}
|
||
|
else
|
||
|
htable->selectOnlyOne(row);
|
||
|
|
||
|
first_drag_row = prev_drag_row = row;
|
||
|
|
||
|
emit htable->selectionChanged();
|
||
|
}
|
||
|
|
||
|
else if (e->button() == Qt::RightButton)
|
||
|
{
|
||
|
if (!htable->isSelected(row))
|
||
|
htable->selectOnlyOne(row);
|
||
|
emit htable->selectionChanged();
|
||
|
// better? emit htable->rightClicked(e->globalPos());
|
||
|
}
|
||
|
last_row = row;
|
||
|
// htable->repaint_changed();
|
||
|
repaintChanged(); // repaint
|
||
|
// view->update(); // fast but use more CPU
|
||
|
}
|
||
|
|
||
|
void TableBody::mouseReleaseEvent(QMouseEvent *e)
|
||
|
{
|
||
|
gadget_click = false;
|
||
|
|
||
|
if (e->button() == Qt::LeftButton)
|
||
|
{
|
||
|
if (autoscrolling)
|
||
|
{
|
||
|
////killTimers(); // no more autoscrolling
|
||
|
first_drag_row = prev_drag_row = -1;
|
||
|
autoscrolling = false;
|
||
|
}
|
||
|
}
|
||
|
else if (e->button() == Qt::RightButton)
|
||
|
{
|
||
|
QPoint p(6, 3);
|
||
|
p += e->globalPos();
|
||
|
emit htable->rightClicked(p);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TableBody::mouseDoubleClickEvent(QMouseEvent *e)
|
||
|
{
|
||
|
if (e->button() == Qt::LeftButton)
|
||
|
{
|
||
|
int row = findRow(e->y());
|
||
|
if (row != -1)
|
||
|
{
|
||
|
if (htable->options & HTBL_ROW_SELECTION &&
|
||
|
!htable->isSelected(row))
|
||
|
htable->selectOnlyOne(row);
|
||
|
// htable->selectionNotify();
|
||
|
emit htable->selectionChanged();
|
||
|
// htable->emit_double_click_signal(row);
|
||
|
emit htable->doubleClicked(row);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Bottle Neck ? no
|
||
|
void TableBody::leaveEvent(QEvent *) { emit htable->outOfCell(); }
|
||
|
|
||
|
void TableBody::mouseMoveEvent(QMouseEvent *e)
|
||
|
{
|
||
|
if (numRows() == 0)
|
||
|
return; // *** prevent out of range
|
||
|
|
||
|
// DRAFT CODE !
|
||
|
// Signal : find row, col(field name) emit flyOnEvent Signal
|
||
|
int row = findRow(e->y());
|
||
|
int col = findCol(e->x());
|
||
|
|
||
|
if (row < 0 or col < 0)
|
||
|
{
|
||
|
emit htable->outOfCell(); // if...
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
emit htable->flyOnCell(row, col);
|
||
|
|
||
|
if (e->buttons() == Qt::NoButton)
|
||
|
return;
|
||
|
if (e->buttons() == Qt::RightButton)
|
||
|
return;
|
||
|
|
||
|
if (e->buttons() & Qt::ControlModifier || gadget_click)
|
||
|
return;
|
||
|
|
||
|
if (row != prev_drag_row)
|
||
|
{
|
||
|
if (row == -1)
|
||
|
{
|
||
|
if (!autoscrolling)
|
||
|
{
|
||
|
// dragging outside table, cause scrolling
|
||
|
scrolldir = (e->y() < 0) ? UP : DOWN;
|
||
|
// killTimers();
|
||
|
// startTimer(scroll_delay);
|
||
|
autoscrolling = true;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
////killTimers();
|
||
|
autoscrolling = false;
|
||
|
dragSelectTo(row);
|
||
|
}
|
||
|
}
|
||
|
// repaintRow(row);
|
||
|
// view->update();
|
||
|
repaintChanged();
|
||
|
}
|
||
|
|
||
|
void TableBody::timerEvent(QTimerEvent *)
|
||
|
{
|
||
|
// timer not proved !
|
||
|
return;
|
||
|
// printf("timer\n");
|
||
|
if (!autoscrolling)
|
||
|
return;
|
||
|
////killTimers();
|
||
|
if (scrolldir == UP)
|
||
|
{
|
||
|
int top = topCell();
|
||
|
setTopCell((top > 1) ? top - 1 : 0);
|
||
|
dragSelectTo(topCell());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
setTopCell(topCell() + 1);
|
||
|
int bottom = lastRowVisible();
|
||
|
dragSelectTo((bottom < numRows()) ? bottom : numRows() - 1);
|
||
|
}
|
||
|
startTimer(scroll_delay);
|
||
|
}
|
||
|
|
||
|
// change drag selection point from previous drag position to row
|
||
|
void TableBody::dragSelectTo(int row)
|
||
|
{
|
||
|
int dir = (row > prev_drag_row) ? 1 : -1;
|
||
|
if ((prev_drag_row - first_drag_row) * dir >= 0)
|
||
|
{
|
||
|
// moving away from start point
|
||
|
for (int i = prev_drag_row + dir; i - dir != row; i += dir)
|
||
|
htable->setSelected(i, true);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// moving towards start point
|
||
|
for (int i = prev_drag_row; i != row; i += dir)
|
||
|
htable->setSelected(i, false);
|
||
|
}
|
||
|
prev_drag_row = row;
|
||
|
// htable->selectionNotify();
|
||
|
emit htable->selectionChanged();
|
||
|
}
|
||
|
|
||
|
// heuristic for determining a good XOR color: This is in general a hard
|
||
|
// problem but since we know (most of) the background and the foreground,
|
||
|
// we can try. Note that this function might not return an allocated QColor,
|
||
|
// so it is only useful for XOR drawing.
|
||
|
|
||
|
QColor TableBody::getXorColor()
|
||
|
{
|
||
|
QColor fg = palette().brush(QPalette::Base).color();
|
||
|
|
||
|
return fg; /// QColor(0, fg.pixel() ^ backgroundColor().pixel());
|
||
|
}
|
||
|
|
||
|
void TableBody::drawGhostCol(int x, int w)
|
||
|
{
|
||
|
static QColor xorcol = getXorColor();
|
||
|
|
||
|
QPainter p(this);
|
||
|
|
||
|
p.setPen(xorcol);
|
||
|
// p.setRasterOp(XorROP);
|
||
|
/// p.drawLine(x, 0, x, height());
|
||
|
////p.drawLine(x + w, 0, x + w, height());
|
||
|
}
|
||
|
|
||
|
// HeadedTable: the actually useable class
|
||
|
HeadedTable::HeadedTable(QWidget *parent, int opts) : QWidget(parent)
|
||
|
{
|
||
|
// meaningless?
|
||
|
options = HTBL_ROW_CONTEXT_MENU | HTBL_ROW_SELECTION |
|
||
|
HTBL_ROW_DOUBLE_CLICK | HTBL_HEADING_TOOLTIPS |
|
||
|
HTBL_HEADING_CONTEXT_MENU | HTBL_HEADING_CLICK |
|
||
|
HTBL_REORDER_COLS;
|
||
|
|
||
|
head = new TableHead(this);
|
||
|
body = new TableBody(this);
|
||
|
head->setObjectName("head");
|
||
|
body->setObjectName("body");
|
||
|
|
||
|
sorted_col = -1;
|
||
|
treemode = false;
|
||
|
treestep = 0;
|
||
|
lines = true;
|
||
|
folding = true;
|
||
|
gadget_space = 0;
|
||
|
nrows = ncols = 0; // hmm...
|
||
|
|
||
|
// printf("style name=%s \n",qPrintable(style()->objectName()));
|
||
|
// QApplication::setStyle(new QWindowsStyle);
|
||
|
head->setFrameShape(QFrame::NoFrame);
|
||
|
if (style()->objectName().contains("oxygen"))
|
||
|
;
|
||
|
else
|
||
|
{
|
||
|
body->setFrameShape(QFrame::NoFrame);
|
||
|
}
|
||
|
|
||
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
||
|
vlayout->setSpacing(0); // distance between Widget and Widget
|
||
|
|
||
|
#if QT_VERSION < 0x040300
|
||
|
vlayout->setMargin(0); // qt-4.2
|
||
|
#else
|
||
|
vlayout->setContentsMargins(0, 0, 0, 0); // qt-4.3
|
||
|
#endif
|
||
|
|
||
|
// vlayout->setSizeConstraint ( SizeConstraint )
|
||
|
vlayout->addWidget(head);
|
||
|
vlayout->addWidget(body);
|
||
|
setLayout(vlayout);
|
||
|
|
||
|
// connect keyboard shortcuts
|
||
|
QShortcut *c;
|
||
|
c = new QShortcut(Qt::CTRL + Qt::Key_A, this, SLOT(selectAll()));
|
||
|
// synchronize horizontal scrolling of head and body
|
||
|
connect(body->horizontalScrollBar(), SIGNAL(valueChanged(int)), head,
|
||
|
SLOT(scrollSideways(int)));
|
||
|
fontChange(font()); // *** need for init
|
||
|
// vp=new VPointer((QWidget *)QObject::parent());
|
||
|
// vp->hide(); //memory leak!!
|
||
|
}
|
||
|
|
||
|
HeadedTable::~HeadedTable() {}
|
||
|
|
||
|
// ok : move to Qttableview
|
||
|
void HeadedTable::fontChange(const QFont &oldFont)
|
||
|
{
|
||
|
// DEBUG("fontChange()\n");
|
||
|
int fontHeight = fontMetrics().height() + 1;
|
||
|
// printf("cell height =%d \n", cellH);
|
||
|
if (fontHeight % 2 != 0)
|
||
|
fontHeight++; // for pretty fold-lines
|
||
|
head->setCellHeight(fontHeight + 5);
|
||
|
head->setMaximumHeight(head->cellHeight());
|
||
|
body->setCellHeight(fontHeight);
|
||
|
treestep = fontHeight;
|
||
|
gadget_space = folding ? fontHeight + (fontHeight / 2) : 0;
|
||
|
// QWidget::fontChange ( oldFont );
|
||
|
}
|
||
|
|
||
|
// DRAFT virtual !
|
||
|
void HeadedTable::moveCol(int col, int place)
|
||
|
{
|
||
|
// go to void Procview::moveColumn(int col, int place)
|
||
|
}
|
||
|
|
||
|
// distance (in table coords) from left table edge of physical column
|
||
|
int HeadedTable::colOffset(int col)
|
||
|
{
|
||
|
int x = 0;
|
||
|
for (int c = 0; c < col; c++)
|
||
|
x += max_widths[c];
|
||
|
// x += body->cellWidth(c);
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
// OPTIZ
|
||
|
inline int HeadedTable::colXPos(int col)
|
||
|
{
|
||
|
int x = 0; // + coloffset
|
||
|
for (int c = 0; c < col; c++)
|
||
|
x += max_widths[c];
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
// repaint columns from col0 to col1. If col1 is -1, repaint all
|
||
|
// the way to the right edge of the table.
|
||
|
// called by
|
||
|
// 1.void Qps::update_table(int col)
|
||
|
void HeadedTable::repaintColumns(int col0, int col1)
|
||
|
{
|
||
|
QRect bvr = body->viewRect();
|
||
|
QRect hvr = head->viewRect();
|
||
|
int x0 = colOffset(col0) - body->xOffset();
|
||
|
if (x0 > hvr.width())
|
||
|
return;
|
||
|
if (x0 < 0)
|
||
|
x0 = 0;
|
||
|
bvr.setLeft(x0);
|
||
|
hvr.setLeft(x0);
|
||
|
if (col1 >= 0)
|
||
|
{
|
||
|
int x1 = colOffset(col1) + max_widths[col1] - body->xOffset();
|
||
|
if (x1 < hvr.width())
|
||
|
{
|
||
|
hvr.setRight(x1);
|
||
|
bvr.setRight(x1);
|
||
|
}
|
||
|
}
|
||
|
head->repaint(hvr);
|
||
|
body->repaint(bvr);
|
||
|
}
|
||
|
|
||
|
// DEL -> virtual
|
||
|
// called by Pstable::setTreeMode(bool)
|
||
|
void HeadedTable::setTreeMode(bool tm)
|
||
|
{
|
||
|
treemode = tm;
|
||
|
head->clearCache();
|
||
|
body->clearCache();
|
||
|
}
|
||
|
|
||
|
// update table Head !!
|
||
|
void HeadedTable::setSortedCol(int col)
|
||
|
{
|
||
|
{
|
||
|
int old_sorted = sorted_col;
|
||
|
sorted_col = col;
|
||
|
// printf("old_sorted=%d\n",old_sorted);
|
||
|
// printf("sorted_col=%d\n",sorted_col);
|
||
|
if (old_sorted != -1 && old_sorted < ncols) // ncols bug
|
||
|
updateHeading(old_sorted);
|
||
|
if (col != -1 && col < ncols)
|
||
|
updateHeading(col);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// should be virtual. why?
|
||
|
void HeadedTable::clearAllSelections()
|
||
|
{
|
||
|
for (int row = 0; row < nrows; row++)
|
||
|
setSelected(row, false);
|
||
|
body->view->update();
|
||
|
// update(); // not work why?
|
||
|
}
|
||
|
|
||
|
// BottleNeck ?
|
||
|
void HeadedTable::selectOnlyOne(int row)
|
||
|
{
|
||
|
// this apply to the current list only!
|
||
|
for (int r = 0; r < nrows; r++)
|
||
|
setSelected(r, r == row);
|
||
|
}
|
||
|
|
||
|
void HeadedTable::selectAll()
|
||
|
{
|
||
|
for (int r = 0; r < nrows; r++)
|
||
|
setSelected(r, true);
|
||
|
emit selectionChanged(); // notwork?
|
||
|
}
|
||
|
|
||
|
// default implementation returns a null string (no tip d)
|
||
|
QString HeadedTable::tipText(int) { return ""; }
|
||
|
char *HeadedTable::total_selectedRow(int col) { return 0; }
|
||
|
|
||
|
void HeadedTable::setNumRows(int rows)
|
||
|
{
|
||
|
nrows = rows;
|
||
|
head->setNumRows(1);
|
||
|
body->setNumRows(rows);
|
||
|
}
|
||
|
|
||
|
void TableCache::setRow(int row)
|
||
|
{
|
||
|
if (row < 0)
|
||
|
return;
|
||
|
|
||
|
int i, size = rows.size();
|
||
|
if (row >= size)
|
||
|
{
|
||
|
// rows.append(new TableRow);
|
||
|
}
|
||
|
|
||
|
if (row < nrow)
|
||
|
{
|
||
|
// printf("row=%d,nrow=%d \n",row,nrow);
|
||
|
if (size < nrow)
|
||
|
nrow = size;
|
||
|
for (i = row; i < nrow; i++)
|
||
|
{
|
||
|
for (int j = 0; j < 48; j++)
|
||
|
rows[i]->cells[j].text = "";
|
||
|
}
|
||
|
}
|
||
|
nrow = row;
|
||
|
}
|
||
|
|
||
|
void TableCache::setCol(int col)
|
||
|
{
|
||
|
if (col < 0)
|
||
|
return;
|
||
|
if (col < ncol)
|
||
|
{
|
||
|
// printf("clear cache\n");
|
||
|
int i, size = rows.size();
|
||
|
for (i = 0; i < size; i++)
|
||
|
for (int j = col; j < ncol; j++)
|
||
|
rows[i]->cells[j].text = "";
|
||
|
}
|
||
|
ncol = col;
|
||
|
}
|
||
|
|
||
|
// TEST
|
||
|
void TableHead::checkProfile()
|
||
|
{
|
||
|
QRect viewR = viewRect();
|
||
|
// if(viewR.y()!=0) printf(" qps: ooooohss....\n");
|
||
|
int maxViewCol = findCol(viewR.width());
|
||
|
if (maxViewCol < 0)
|
||
|
maxViewCol = numCols();
|
||
|
tablecache.setCol(maxViewCol);
|
||
|
tablecache.setRow(1);
|
||
|
}
|
||
|
|
||
|
// TESt
|
||
|
void TableBody::checkProfile()
|
||
|
{
|
||
|
htable->checkTableModel(); // important
|
||
|
|
||
|
QRect viewR = viewRect();
|
||
|
if (viewR.y() != 0)
|
||
|
printf(" qps: ooooophss....\n");
|
||
|
int maxViewRow = findRow(viewR.height());
|
||
|
if (maxViewRow < 0)
|
||
|
maxViewRow = numRows();
|
||
|
int maxViewCol = findCol(viewR.width());
|
||
|
if (maxViewCol < 0)
|
||
|
maxViewCol = numCols();
|
||
|
tablecache.setCol(maxViewCol);
|
||
|
tablecache.setRow(maxViewRow);
|
||
|
}
|
||
|
|
||
|
void HeadedTable::setNumCols(int cols)
|
||
|
{
|
||
|
// printf("cols=%d\n",cols);
|
||
|
|
||
|
ncols = cols;
|
||
|
// resetWidths();
|
||
|
for (int i = 0; i < cols; i++)
|
||
|
{
|
||
|
alignment_col[i] = alignment(i);
|
||
|
updateColWidth(i);
|
||
|
}
|
||
|
// printf("ncols=%d\n",ncols);
|
||
|
head->setNumCols(ncols);
|
||
|
body->setNumCols(ncols);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
//virtual
|
||
|
int HeadedTable::colWidth(int col)
|
||
|
{
|
||
|
int r = numRows();
|
||
|
for(int i=0;i<r;i++) text(i,col);
|
||
|
} */
|
||
|
|
||
|
// BOTTLENECK
|
||
|
// find Max width of a column
|
||
|
// called by
|
||
|
// 1. void HeadedTable::setNumCols(int cols)
|
||
|
int HeadedTable::updateColWidth(int col)
|
||
|
{
|
||
|
int w = 0;
|
||
|
int sw = 0;
|
||
|
int hw = 0;
|
||
|
int i = 0;
|
||
|
int rows = numRows();
|
||
|
bool treecol = (treemode && col == 0);
|
||
|
|
||
|
if ((w = sizeHintForColumn(col)) < 0) // width
|
||
|
{
|
||
|
if (w < 0)
|
||
|
w = -w; // trick.
|
||
|
// if(w<0) printf("w = %d\n",w);
|
||
|
// harsh, if procs more than 1000
|
||
|
for (i = 0; i < rows; i++)
|
||
|
{
|
||
|
sw = fontMetrics().width(text(i, col)) + 10;
|
||
|
|
||
|
if (treecol)
|
||
|
sw += treestep * rowDepth(i);
|
||
|
if (sw > w)
|
||
|
w = sw;
|
||
|
}
|
||
|
|
||
|
if (treecol)
|
||
|
{
|
||
|
w += gadget_space;
|
||
|
}
|
||
|
}
|
||
|
// don't forget the width of the heading
|
||
|
hw = fontMetrics().width(title(col)) + 12;
|
||
|
// return 0;
|
||
|
if (hw > w)
|
||
|
w = hw;
|
||
|
|
||
|
// sw=fontmetric.width("0") * colWidth(col);
|
||
|
// if(sw>w) w=sw;
|
||
|
|
||
|
max_widths[col] = w;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void HeadedTable::resetWidths()
|
||
|
{
|
||
|
for (int i = 0; i < numCols() + 1; i++)
|
||
|
max_widths[i] = 0;
|
||
|
}
|
||
|
|
||
|
// called by ?
|
||
|
void HeadedTable::repaintAll() // -> repaint()
|
||
|
{
|
||
|
int count = 0, trow = 0;
|
||
|
for (int row = 0; row < nrows; row++)
|
||
|
if (isSelected(row))
|
||
|
{
|
||
|
count++;
|
||
|
trow = row;
|
||
|
}
|
||
|
// body->view->update();
|
||
|
// update(); // not work why?
|
||
|
|
||
|
// printf("Qps debug: repaintAll()\n");
|
||
|
// head->clearCache();
|
||
|
// body->clearCache();
|
||
|
// update();
|
||
|
body->view->update();
|
||
|
head->view->update();
|
||
|
if (count == 1)
|
||
|
centerVertically(trow);
|
||
|
}
|
||
|
|
||
|
// PROBLEM : update() + repaint() call = draw twice !!!
|
||
|
// called by pstable::refresh()
|
||
|
// DEL if (render_area smaller than full_arear ) then force draw
|
||
|
void HeadedTable::repaint_changed()
|
||
|
{
|
||
|
// printf("repaint_changed()\n");
|
||
|
// body->setUpdatesEnabled(true);
|
||
|
head->repaintChanged();
|
||
|
body->repaintChanged();
|
||
|
}
|
||
|
|
||
|
void HeadedTable::hideEvent(QHideEvent *event) {}
|
||
|
|
||
|
void HeadedTable::paintEvent(QPaintEvent *e)
|
||
|
{
|
||
|
static int c = 0;
|
||
|
// printf("HeadedTable paintEvent %d\n",c++); //works ?
|
||
|
// QWidget::paintEvent(e);
|
||
|
// body->clearCache();
|
||
|
// head->update();
|
||
|
}
|
||
|
|
||
|
void HeadedTable::showEvent(QShowEvent *)
|
||
|
{
|
||
|
// printf("HeadedTable showEvent\n"); // works
|
||
|
// before paintEvent call
|
||
|
head->clearCache();
|
||
|
body->clearCache();
|
||
|
}
|
||
|
|
||
|
void HeadedTable::resizeEvent(QResizeEvent *e)
|
||
|
{
|
||
|
// DEBUG("resizeEvent() HeadedTable %d\n",head->cellHeight());
|
||
|
//// head->repaintRow(0);
|
||
|
QWidget::resizeEvent(e);
|
||
|
head->clearCache();
|
||
|
body->clearCache();
|
||
|
}
|