diff options
author | Marius Bugge Monsen <mmonsen@trolltech.com> | 2009-05-29 17:46:44 +0200 |
---|---|---|
committer | Marius Bugge Monsen <mmonsen@trolltech.com> | 2009-05-29 17:46:44 +0200 |
commit | 50aa984a068f050c115b985c549419be6874f6b9 (patch) | |
tree | 1bb95235d2ae11844519d6bccdaf850a9cb4e2d6 | |
parent | d77f9ba2ab3d22ce9d7cde8ee03655cb3fadb43e (diff) |
Refactor the QtGraphicsTableView layout function.
-rw-r--r-- | src/qgraphicstableview.cpp | 160 | ||||
-rw-r--r-- | src/qgraphicstableview.h | 2 | ||||
-rw-r--r-- | src/qgraphicstableview_p.h | 5 |
3 files changed, 123 insertions, 44 deletions
diff --git a/src/qgraphicstableview.cpp b/src/qgraphicstableview.cpp index 643b83a..e7fe534 100644 --- a/src/qgraphicstableview.cpp +++ b/src/qgraphicstableview.cpp @@ -25,11 +25,11 @@ #include "qgraphicstableview_p.h" #include "qtablemodelinterface.h" -#include "qtableselectionmanager.h" #include "qgraphicsheader.h" #include "qtablecontroller.h" #include <qdebug.h> +#include <qstack.h> #include <qpainter.h> #include <qstyle.h> #include <qstyleoption.h> @@ -112,8 +112,8 @@ void QtGraphicsTableViewItem::itemChanged(const QList<int> &roles) { Q_UNUSED(roles); // ### if the size changed, we need to let the layout know - prepareGeometryChange(); - update(); + //prepareGeometryChange(); + //update(); } QHash<int, QVariant> QtGraphicsTableViewItem::data(const QList<int> &roles) const @@ -138,19 +138,19 @@ void QtGraphicsTableViewItem::paint(QPainter *painter, const QStyleOptionGraphic d->view->initStyleOption(&d->option); d->view->copyStyleOptionState(option, &d->option); d->view->initStyleOption(&d->option, d->row, d->column); - d->option.rect = QRectF(QPointF(), size()).toRect(); + const QRect rect = QRectF(QPointF(), size()).toRect(); + d->option.rect = rect; style()->drawControl(QStyle::CE_ItemViewItem, &d->option, painter, widget); // draw grid const QColor gridColor = static_cast<QRgb>(style()->styleHint(QStyle::SH_Table_GridLineColor, &d->option, widget)); -// TODO check for option and make the left+top painting ones actually work // left - //painter->fillRect(d->option.rect.left(), d->option.rect.bottom(), d->option.rect.width(), 1, gridColor); + //painter->fillRect(rect.left(), rect.bottom(), rect.width(), 1, gridColor); // top - //painter->fillRect(d->option.rect.right(), d->option.rect.top(), 1, d->option.rect.height(), gridColor); + //painter->fillRect(right(), d->option.rect.top(), 1, rect.height(), gridColor); // right - painter->fillRect(d->option.rect.left(), d->option.rect.bottom(), d->option.rect.width(), 1, gridColor); + painter->fillRect(rect.left(), rect.bottom(), rect.width(), 1, gridColor); // bottom - painter->fillRect(d->option.rect.right(), d->option.rect.top(), 1, d->option.rect.height(), gridColor); + painter->fillRect(rect.right(), rect.top(), 1, rect.height(), gridColor); } /*! \class QtGraphicsTableViewItemCreatorBase @@ -241,12 +241,18 @@ void QtGraphicsTableViewPrivate::_q_cellsChanged(int firstRow, int firstColumn, void QtGraphicsTableViewPrivate::_q_selectionsChanged(const QList<QtTableSelectionRange> &changed) { // ### FIXME: naive lookup - for (int i = 0; i < items.count(); ++i) { - for (int j = 0; j < changed.count(); ++j) { - QtGraphicsTableViewItem *item = items.at(i); - if (changed.at(j).containsCell(item->row(), item->column())) { - item->update(); - break; + // ### FIXME: check header mappings + if (!model) + return; + const int columnCount = model->columnCount(); + for (int j = 0; j < changed.count(); ++j) { + QtTableSelectionRange range = changed.at(j); + if (range.intersects(visibleSections)) { + for (int row = range.topRow(); row <= range.bottomRow(); ++row) { + for (int column = range.leftColumn(); column <= range.rightColumn(); ++column) { + if (QtGraphicsTableViewItem *item = items.value((row * columnCount) + column)) + item->update(); + } } } } @@ -254,14 +260,13 @@ void QtGraphicsTableViewPrivate::_q_selectionsChanged(const QList<QtTableSelecti void QtGraphicsTableViewPrivate::_q_currentChanged(int currentRow, int currentColumn, int previousRow, int previousColumn) { - Q_UNUSED(previousColumn); - Q_UNUSED(previousRow); - // ### FIXME: naive lookup - for (int i = 0; i < items.count(); ++i) { - QtGraphicsTableViewItem *item = items.at(i); - if (item->row() == currentRow && item->column() == currentColumn) - item->update(); - } + if (!model) + return; + const int columnCount = model->columnCount(); + if (QtGraphicsTableViewItem *current = items.value((currentRow * columnCount) + currentColumn)) + current->update(); + if (QtGraphicsTableViewItem *previous = items.value((previousRow * columnCount) + previousColumn)) + previous->update(); } void QtGraphicsTableViewPrivate::_q_rowsInserted(int row, int count) @@ -948,6 +953,9 @@ void QtGraphicsTableView::doLayout() if (area.isEmpty()) return; + const int columnCount = d->model->columnCount(); + const int rowCount = d->model->rowCount(); + int horizontalCount; qreal horizontalOffset; QVector<int> horizontalMapping; @@ -957,7 +965,7 @@ void QtGraphicsTableView::doLayout() horizontalOffset = d->horizontalHeader->offset(); horizontalMapping = d->horizontalHeader->indexMapping(); } else { - horizontalCount = qMin(d->model->columnCount(), int(area.width() / d->defaultColumnWidth)); + horizontalCount = qMin(columnCount, int(area.width() / d->defaultColumnWidth)); horizontalOffset = d->horizontalOffset; } @@ -970,30 +978,93 @@ void QtGraphicsTableView::doLayout() verticalOffset = d->verticalHeader->offset(); verticalMapping = d->verticalHeader->indexMapping(); } else { - verticalCount = qMin(d->model->rowCount(), int(area.height() / d->defaultRowHeight)); + verticalCount = qMin(rowCount, int(area.height() / d->defaultRowHeight)); verticalOffset = d->verticalOffset; } - const int lastColumn = qMax(d->firstColumn + horizontalCount - 1, 0); - const int lastRow = qMax(d->firstRow + verticalCount - 1, 0); - const int firstIndex = (d->firstRow * horizontalCount) + d->firstColumn; + const int firstHorizontalSection = d->firstColumn; + const int firstVerticalSection = d->firstRow; + const int lastHorizontalSection = qMax(d->firstColumn + horizontalCount - 1, -1); + const int lastVerticalSection = qMax(d->firstRow + verticalCount - 1, -1); + + const int oldFirstVerticalSection = d->visibleSections.topRow(); + const int oldFirstHorizontalSection = d->visibleSections.leftColumn(); + const int oldLastVerticalSection = d->visibleSections.bottomRow(); + const int oldLastHorizontalSection = d->visibleSections.rightColumn(); + + // find unused items for reassignment + QStack<QtGraphicsTableViewItem*> unused; + + /* + -------------- + | | + -------------- + | | | | + | | | | + | | | | + -------------- + | | + -------------- + */ + + // top edge + for (int verticalSection = oldFirstVerticalSection; verticalSection < firstVerticalSection; ++verticalSection) { + const int row = verticalMapping.value(verticalSection, verticalSection); + for (int horizontalSection = oldFirstHorizontalSection; horizontalSection <= oldLastHorizontalSection; ++horizontalSection) { + const int column = horizontalMapping.value(horizontalSection, horizontalSection); + const int index = (row * columnCount) + column; + if (QtGraphicsTableViewItem *item = d->items.take(index)) + unused.push(item); + } + } + // left edge + for (int horizontalSection = oldFirstHorizontalSection; horizontalSection < firstHorizontalSection; ++horizontalSection) { + int column = horizontalMapping.value(horizontalSection, horizontalSection); + for (int verticalSection = firstVerticalSection; verticalSection <= lastVerticalSection; ++verticalSection) { + const int row = verticalMapping.value(verticalSection, verticalSection); + const int index = (row * columnCount) + column; + if (QtGraphicsTableViewItem *item = d->items.take(index)) + unused.push(item); + } + } + // bottom edge + for (int verticalSection = lastVerticalSection + 1; verticalSection <= oldLastVerticalSection; ++verticalSection) { + const int row = verticalMapping.value(verticalSection, verticalSection); + for (int horizontalSection = oldFirstHorizontalSection; horizontalSection <= oldLastHorizontalSection; ++horizontalSection) { + const int column = horizontalMapping.value(horizontalSection, horizontalSection); + const int index = (row * columnCount) + column; + if (QtGraphicsTableViewItem *item = d->items.take(index)) + unused.push(item); + } + } + // right edge + for (int horizontalSection = lastHorizontalSection + 1; horizontalSection <= oldLastHorizontalSection; ++horizontalSection) { + int column = horizontalMapping.value(horizontalSection, horizontalSection); + for (int verticalSection = firstVerticalSection; verticalSection <= lastVerticalSection; ++verticalSection) { + const int row = verticalMapping.value(verticalSection, verticalSection); + const int index = (row * columnCount) + column; + if (QtGraphicsTableViewItem *item = d->items.take(index)) + unused.push(item); + } + } + // move overlapping items qreal y = -verticalOffset; - for (int verticalSection = d->firstRow; verticalSection <= lastRow; ++verticalSection) { + for (int verticalSection = firstVerticalSection; verticalSection <= lastVerticalSection; ++verticalSection) { const int row = verticalMapping.value(verticalSection, verticalSection); const qreal height = rowHeight(row); qreal x = -horizontalOffset; - for (int horizontalSection = d->firstColumn; horizontalSection <= lastColumn; ++horizontalSection) { + for (int horizontalSection = firstHorizontalSection; horizontalSection <= lastHorizontalSection; ++horizontalSection) { const int column = horizontalMapping.value(horizontalSection, horizontalSection); const qreal width = columnWidth(column); - const int index = ((verticalSection * horizontalCount) + horizontalSection) - firstIndex; - QtGraphicsTableViewItem *item = d->items.value(index, 0); - // ### FIXME: scroll the items properly - if (item) { - item = d->creator->reassign(row, column, item); - } else if (index >= d->items.count()) { - item = d->creator->create(row, column, this); - d->items.append(item); + const int index = (row * columnCount) + column; + QtGraphicsTableViewItem *item = d->items.value(index); + if (!item) { + if (!unused.isEmpty()) + item = d->creator->reassign(row, column, unused.pop()); + else + item = d->creator->create(row, column, this); + d->items.insert(index, item); } item->setGeometry(x, y, width, height); x += width; @@ -1001,10 +1072,15 @@ void QtGraphicsTableView::doLayout() y += height; } - const int lastIndex = (lastRow * horizontalCount) + lastColumn; - const int removeCount = d->items.count() - (lastIndex - firstIndex) - 1; - for (int i = 0; i < removeCount; ++i) - d->creator->recycle(d->items.takeLast()); + // update internal structures + d->visibleSections.setRange(firstVerticalSection, firstHorizontalSection, lastVerticalSection, lastHorizontalSection); + + // recycle any unused items left + for (int i = 0; i < unused.count(); ++i) + d->creator->recycle(unused.at(i)); + + Q_ASSERT(d->items.count() == (horizontalCount * verticalCount)); + //Q_ASSERT(d->items.count() == childItems().count()); } /*! diff --git a/src/qgraphicstableview.h b/src/qgraphicstableview.h index ee3950f..9c561f6 100644 --- a/src/qgraphicstableview.h +++ b/src/qgraphicstableview.h @@ -123,7 +123,6 @@ public: void setTextElideMode(Qt::TextElideMode mode); bool isGridShown() const; - void setGridShown(bool show); qreal rowHeight(int row) const; void setRowHeight(int row, qreal height); @@ -183,6 +182,7 @@ public: void copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *dest); public Q_SLOTS: + void setGridShown(bool show); void setFirstRow(int row); void setFirstColumn(int column); void setHorizontalOffset(qreal offset); diff --git a/src/qgraphicstableview_p.h b/src/qgraphicstableview_p.h index c8e5c61..800f2c7 100644 --- a/src/qgraphicstableview_p.h +++ b/src/qgraphicstableview_p.h @@ -39,6 +39,8 @@ #include <qfont.h> #include <qvariant.h> +#include <qtableselectionmanager.h> + QT_BEGIN_NAMESPACE class QtTableModelInterface; @@ -114,7 +116,8 @@ public: mutable int cachedDataColumn; // view items - QList<QtGraphicsTableViewItem*> items; + QtTableSelectionRange visibleSections; + QHash<int, QtGraphicsTableViewItem*> items; QtGraphicsTableViewItemCreatorBase *creator; QtGraphicsTableView *q_ptr; |