11 #include "TableViewHeader.h"
15 #include <QAbstractItemModel>
16 #include <QFontMetrics>
18 #include <QLinearGradient>
20 #include <QMessageBox>
21 #include <QMouseEvent>
26 #include <QVBoxLayout>
28 #include "AbstractTableModel.h"
29 #include "AbstractTreeModel.h"
30 #include "TableColumn.h"
31 #include "TableColumnList.h"
32 #include "TableView.h"
44 m_horizontalOffset = 0;
46 m_filterProgressMin = 0;
47 m_filterProgressMax = 0;
48 m_rebuildProgress = 0;
49 m_rebuildProgressMin = 0;
50 m_rebuildProgressMax = 0;
52 m_sortProgressMin = 0;
53 m_sortProgressMax = 0;
57 m_clickedColumnEdge = -1;
60 setMouseTracking(
true);
93 return QSize(0, QFontMetrics(font()).height() + 6);
118 disconnect(m_model, SIGNAL(filterProgressChanged(
int)),
120 disconnect(m_model, SIGNAL(rebuildProgressChanged(
int)),
122 disconnect(m_model, SIGNAL(sortProgressChanged(
int)),
124 disconnect(m_model, SIGNAL(filterProgressRangeChanged(
int,
int)),
126 disconnect(m_model, SIGNAL(rebuildProgressRangeChanged(
int,
int)),
128 disconnect(m_model, SIGNAL(sortProgressRangeChanged(
int,
int)),
130 disconnect(m_model, SIGNAL(filterCountsChanged(
int,
int)),
132 disconnect(
this, SIGNAL(requestedGlobalSelection(
bool)),
133 m_model, SLOT(setGlobalSelection(
bool)));
134 disconnect(m_model, SIGNAL(m_modelModified()),
135 this, SLOT(update()));
140 connect(m_model, SIGNAL(filterProgressChanged(
int)),
142 connect(m_model, SIGNAL(rebuildProgressChanged(
int)),
144 connect(m_model, SIGNAL(sortProgressChanged(
int)),
146 connect(m_model, SIGNAL(filterProgressRangeChanged(
int,
int)),
148 connect(m_model, SIGNAL(rebuildProgressRangeChanged(
int,
int)),
150 connect(m_model, SIGNAL(sortProgressRangeChanged(
int,
int)),
152 connect(m_model, SIGNAL(filterCountsChanged(
int,
int)),
154 connect(
this, SIGNAL(requestedGlobalSelection(
bool)),
155 m_model, SLOT(setGlobalSelection(
bool)));
156 connect(m_model, SIGNAL(modelModified()),
this, SLOT(update()));
160 for (
int i = 0; i < m_columns->size(); i++) {
161 disconnect((*m_columns)[i], SIGNAL(visibilityChanged()),
162 this, SLOT(update()));
166 m_columns = m_model->getColumns();
168 for (
int i = 0; i < m_columns->size(); i++)
169 connect((*m_columns)[i], SIGNAL(visibilityChanged()),
this, SLOT(update()));
180 int visibleTopLevelItemCount,
int topLevelItemCount) {
181 m_visibleCount = visibleTopLevelItemCount;
182 m_totalCount = topLevelItemCount;
184 if (m_visibleCount >= 0) {
186 for (
int i = 0; i < visibleCols.size(); i++) {
189 if (col->getTitle().isEmpty())
190 col->setWidth(QFontMetrics(font()).width(
191 QString::number(m_visibleCount)) + 22);
206 m_horizontalOffset = newOffset;
217 QPoint mousePos =
event->pos();
225 if (event->buttons() == Qt::LeftButton) {
227 if (m_clickedColumnEdge == -1 && m_clickedColumn != -1) {
229 if (m_columns->getVisibleColumns()[m_clickedColumn]->getTitle().isEmpty()) {
230 emit requestedGlobalSelection(
true);
250 QPoint mousePos =
event->pos();
252 if (m_clickedColumnEdge >= 0) {
254 QRect columnToResizeRect(
getColumnRect(m_clickedColumnEdge));
255 columnToResizeRect.setRight(mousePos.x());
257 TableColumn *col = m_columns->getVisibleColumns()[m_clickedColumnEdge];
260 if (columnToResizeRect.width() > 1) {
261 newWidth = columnToResizeRect.width();
262 if (m_columns->getSortingOrder()[0] == col)
263 newWidth = qMax(newWidth, ARROW_WIDTH + SORT_ARROW_MARGIN * 2);
266 m_columns->getVisibleColumns()[m_clickedColumnEdge]->setWidth(newWidth);
270 setCursor(Qt::SizeHorCursor);
273 setCursor(Qt::ArrowCursor);
287 m_clickedColumnEdge >= m_columns->getVisibleColumns().size() - 2;
288 if (m_clickedColumnEdge != -1) {
289 emit columnResized(wasLastCol);
293 TableColumn *col = m_columns->getVisibleColumns()[m_clickedColumn];
296 m_columns->getVisibleColumns().getSortingOrder()[0];
299 col->setSortAscending(!col->sortAscending());
301 m_columns->raiseToTop(col);
303 if (!m_model->sortingOn()) {
304 QMessageBox::information(
this, tr(
"Sorting Disabled"),
305 tr(
"Sorting is currently disabled for this table. Please configure your sorting "
306 "options before trying to sort by [<font color='red'>%1</font>].")
307 .arg(col->getTitle()),
313 m_clickedColumnEdge = -1;
314 m_clickedColumn = -1;
326 QPainter painter(
this);
327 painter.setRenderHints(QPainter::Antialiasing |
328 QPainter::TextAntialiasing);
330 ARROW_HEIGHT = qMax(height() / 5, 3);
331 ASSERT(height() > 8);
332 ARROW_WIDTH = ARROW_HEIGHT * 2 - 1;
361 if (column < visibleCols.size() && column >= 0) {
364 for (
int i = 0; i < column; i++)
365 indent += visibleCols[i]->getWidth() - 1;
367 colRect = QRect(indent - m_horizontalOffset, 0,
368 visibleCols[column]->getWidth(), height());
383 int mousedColumn = -1;
386 i < m_columns->getVisibleColumns().size() && mousedColumn < 0;
389 if (columnRect.contains(mousePos))
414 if (mousePos.x() - columnRect.left() < TableColumn::EDGE_WIDTH)
415 edge = mousedColumn - 1;
436 bool isAtColumnEdge =
false;
438 if (!columnRect.isNull()) {
440 mousePos.x() - columnRect.left() < TableColumn::EDGE_WIDTH;
442 columnRect.right() - mousePos.x() < TableColumn::EDGE_WIDTH;
443 bool isResizable =
false;
446 if (isOnLeft && columnNum > 0)
447 isResizable = visCols[columnNum - 1]->getTitle().size();
449 isResizable = visCols[columnNum]->getTitle().size();
451 isAtColumnEdge = (isOnLeft || isOnRight) && isResizable;
454 return isAtColumnEdge;
465 int visibleColWidth = -m_horizontalOffset;
468 for (
int i = 0; i < visibleCols.size(); i++)
469 visibleColWidth += visibleCols[i]->getWidth() - 1;
471 QRect rect(0, 0, qMin(width(), visibleColWidth), rowHeight);
473 int x = rect.center().x();
474 QLinearGradient gradient(x, rect.top(), x, rect.bottom());
477 bool selected =
false;
478 QColor color = selected ? palette().highlight().color() :
479 palette().button().color();
482 int adjustment = 110;
483 gradient.setColorAt(0, color.lighter(adjustment));
484 gradient.setColorAt(1, color.darker(adjustment));
485 painter->fillRect(rect, gradient);
489 QBrush brush = painter->brush();
490 QPainter::CompositionMode compMode = painter->compositionMode();
491 painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
494 painter->setBrush(QBrush(QColor(0, 70, 100, 30)));
495 paintProgress(painter, rect, m_filterProgressMin, m_filterProgressMax,
496 m_filterProgress,
false);
499 painter->setBrush(QBrush(QColor(100, 70, 0, 30)));
500 paintProgress(painter, rect, m_rebuildProgressMin, m_rebuildProgressMax,
501 m_rebuildProgress,
false);
504 painter->setBrush(QBrush(QColor(0, 100, 0, 30)));
505 paintProgress(painter, rect, m_sortProgressMin, m_sortProgressMax,
506 m_sortProgress,
true);
510 painter->setBrush(brush);
511 painter->setCompositionMode(compMode);
513 for (
int i = 0; i < visibleCols.size(); i++) {
516 QString columnText = visibleCol->getTitle();
517 QRect columnRect(
getColumnRect(visibleCols.indexOf(visibleCol)));
518 QPen pen(palette().dark().color().darker(150));
519 pen.setCapStyle(Qt::RoundCap);
520 painter->setPen(pen);
521 painter->drawLine(columnRect.topLeft() + QPoint(0, 1),
522 columnRect.bottomLeft() + QPoint(0, 1));
524 painter->drawLine(columnRect.topLeft() + QPoint(1, 0),
525 columnRect.topRight() - QPoint(0, 0));
527 painter->drawLine(columnRect.topLeft() + QPoint(1, 1),
528 columnRect.topRight() + QPoint(0, 1));
530 painter->drawLine(columnRect.bottomLeft() + QPoint(1, 1),
531 columnRect.bottomRight() + QPoint(0, 1));
533 painter->drawLine(columnRect.bottomLeft() + QPoint(1, 1),
534 columnRect.bottomRight() + QPoint(0, 1));
536 painter->drawLine(columnRect.topRight() + QPoint(0, 1),
537 columnRect.bottomRight() - QPoint(0, 0));
539 painter->setPen(selected ? palette().highlightedText().color() :
540 palette().buttonText().color());
542 QRect textRect(columnRect.x(),
544 columnRect.width() - (SORT_ARROW_MARGIN * 2 + ARROW_WIDTH),
545 columnRect.height());
546 painter->drawText(textRect , Qt::AlignCenter | Qt::TextSingleLine,
549 if (visibleCol == visibleCols.getSortingOrder()[0] &&
550 visibleCol->getWidth() >= SORT_ARROW_MARGIN * 2 + ARROW_WIDTH) {
551 ASSERT(SORT_ARROW_MARGIN > 0);
553 QRect arrowRect(textRect.right() + 1,
555 SORT_ARROW_MARGIN * 2 + ARROW_WIDTH,
558 ASSERT(arrowRect.width() + textRect.width() == columnRect.width());
559 ASSERT(arrowRect.right() == columnRect.right());
563 QPoint left(arrowRect.left() + SORT_ARROW_MARGIN,
564 arrowRect.center().y() - ((ARROW_HEIGHT - 1) / 2));
566 int yOffSet = ((ARROW_HEIGHT - 1) / 2);
567 if (ARROW_HEIGHT % 2 == 0)
569 QPoint center(left.x() + ((ARROW_WIDTH - 1) / 2),
570 arrowRect.center().y() + yOffSet);
572 QPoint right(center.x() + ((ARROW_WIDTH - 1) / 2),
573 arrowRect.center().y() - ((ARROW_HEIGHT - 1) / 2));
575 ASSERT(right.x() == arrowRect.right() - SORT_ARROW_MARGIN);
576 ASSERT(right.x() - center.x() == center.x() - left.x());
578 if (!visibleCol->sortAscending()) {
580 left.setY(center.y());
581 center.setY(right.y());
582 right.setY(left.y());
585 if (m_model->sortingOn()) {
586 painter->drawLine(left, center);
587 painter->drawLine(center, right);
592 columnRect.moveLeft(columnRect.right());
608 const QRect &rect,
int min,
int max,
int value,
bool over100) {
609 double progressPercent = 1.0;
610 int progressRange = max - min;
612 if (progressRange > 0)
613 progressPercent = ((double)(value - min)) / progressRange;
614 else if (progressRange == 0)
617 if (progressPercent < 1.0 || over100) {
618 QRect progressRect(rect);
619 progressRect.setWidth((
int)(progressRect.width() * progressPercent));
620 painter->fillRect(progressRect, painter->brush());
631 m_filterProgress = newProgress;
643 m_filterProgressMin = min;
644 m_filterProgressMax = max;
655 m_rebuildProgress = newProgress;
667 m_rebuildProgressMin = min;
668 m_rebuildProgressMax = max;
679 m_sortProgress = newProgress;
691 m_sortProgressMin = min;
692 m_sortProgressMax = max;